{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[comment]: <> (los titulares se generan en el siguiente link: https://docs.google.com/drawings/d/1TLM83sTn9w2Jmq0l0Jy1ivIeLRVO_rKBCamm5Tq11Yo/edit?usp=sharing)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](../img/titulo_sintaxis_basica.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Contenido\n",
    "\n",
    "* [Datos](#Datos)\n",
    "    * [Datos basicos](#Datos-basicos)\n",
    "    * [Estructura de datos](#Estructura-de-datos)\n",
    "* [Operadores](#Operadores)\n",
    "    * [Operadores aritméticos elementales](#Operadores-aritmeticos-elementales)\n",
    "    * [Operadores de comparación](#Operadores-de-comparacion)\n",
    "    * [Operadores lógicos](#Operadores-logicos)\n",
    "* [Variables](#Variables)\n",
    "    * [Asignación](#Asignacion)\n",
    "    * [Indexado](#Indexado)\n",
    "* [Funciones integradas](#Funciones-integradas)\n",
    "* [Referencias usadas en el notebook](#Referencias-usadas-en-el-notebook)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Objetivos del notebook\n",
    "\n",
    "* Conocer los distintos tipos de datos que manipula Python.\n",
    "* Almacenar, asignar e indexar datos.\n",
    "* Imprimir e ingresar datos por consola con Python."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Datos\n",
    "\n",
    "Se denomina **dato** a cualquier **objeto manipulable por la computadora**. Un dato puede ser un carácter leı́do de un teclado, información almacenada en un disco, un número que se encuentra en la memoria central, etc. Los distintos tipos de datos se representan en diferentes formas: por ejemplo, no se almacena internamente de la misma manera un número entero que un caracter. Aunque los lenguajes de alto nivel permiten en alguna medida ignorar la representación interna de los datos, es preciso conocer algunos conceptos mı́nimos. **A nivel de máquina todos los datos se representan utilizando una secuencia finita de bits**. La definición de un tipo de dato incluye la definición del conjunto de valores permitidos y las operaciones que se pueden llevar a cabo sobre estos valores. Cuando se utiliza un dato en un programa es preciso que esté determinado su tipo para que el **compilador** o **interpretador** sepa cómo debe tratarlo y almacenarlo. Dependiendo del lenguaje puede o no ser preciso declarar expresamente en el programa el tipo de cada dato. No todos los tipos de datos existen en todos los lenguajes de programación. Hay lenguajes más ricos que otros en este sentido [Datos y variables, 2009]."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Datos basicos\n",
    "\n",
    "Los **tipos de datos básicos**, denominados **elementales** (o primitivas) son:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-6, 22, -4)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Números enteros (int) (2 or 4 bytes)\n",
    "-6, 22, -4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Números reales (float) (parte entera - parte decimal) (4 bytes)\n",
    "0.009, -31.423, 3.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lógicos (bool) (1 bit)\n",
    "True, False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Caracteres (char --> ASCII) (1 byte)\n",
    "'h', '!', 'A'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Estructura de datos\n",
    "\n",
    "Tipos de datos construidos a partir de datos elementales:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Números complejos (complex)\n",
    "2+3j, -3J"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python trae soporte por defecto para los números complejos, dónde la parte imaginaria va a estar representada por la **letra j o J en lugar de utilizar la i** como en la notación matemática. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cadena de caracteres (string)(str)\n",
    "'Esto es una cadena de caracteres', \"123ABC\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Se puede recuperar resultados pasados usando _<n>. Por ejemplo, para recuperar el resultado correspondiente a Out [7], usaríamos _7. Esta variable guarda ese valor para toda la sesión."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Para acceder al último resultado\n",
    "_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Resultado de la línea [2]\n",
    "_2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Operadores\n",
    "\n",
    "Un operador es un símbolo que indica que debe ser llevada a cabo una operación especificada, sobre un cierto número de operandos. Si abrimos una consola de Python, podríamos utilizarla como calculadora (siempre entre datos del mismo tipo):"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Operadores aritmeticos elementales"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Exponenciación (doble asterisco)\n",
    "10**6, 10**-6 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Los enteros son virtualmente ilimitados\n",
    "x = 9 ** 1000\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Suma\n",
    "12 + 123, 5.67 + 0.42"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Resta\n",
    "123 - 12, 2.13 - 12"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Multiplicación\n",
    "123 * -12, 34 * 65"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# División\n",
    "10/2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Al dividir números **enteros**, el resultado es **siempre decimal**, aunque sea un número entero. Cuando Python escribe un número decimal, lo escribe siempre con parte decimal, aunque sea nula."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Nota:** al realizar **operaciones con decimales**, los resultados pueden presentar [**errores de redondeo**](http://docs.python.org.ar/tutorial/3/floatingpoint.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Nota:** hay **soporte completo de punto flotante**; operadores con operando mezclados convertirá los enteros a punto flotante:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Resto\n",
    "10%3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.3333333333333335"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10/3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Las **reglas de prioridad** de operaciones son las mismas que en álgebra:\n",
    "\n",
    "1. Exponenciaciones.\n",
    "2. Multiplicaciones y divisiones.\n",
    "3. Sumas y restas.\n",
    "\n",
    ">**Nota:** Utilizar paréntesis para modificar la prioridad."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Variables\n",
    "\n",
    "Características de Python respecto al uso de variables:\n",
    "\n",
    "* **Lenguaje de tipado dinámico:** quiere decir que si no definimos las variables de manera explícita, las **variables** serán de un tipo **en función del contenido** y será interpretada en tiempo de ejecución. Las ganancias en tiempos de ejecución que pueden lograrse al cambiar de un tipo a otro son probablemente marginales, y salvo aplicaciones muy específicas, es mejor trabajar con los tipos por defecto sin realizar conversiones de tipos (por el momento ...).\n",
    "\n",
    "> **Nota:** en Python todo es un objeto del tipo string, con atributos y métodos, en la mayoría de los casos.\n",
    "\n",
    "* **Lenguaje fuertemente tipado:** dado el valor de una variable de un tipo concreto, no se puede usar como si fuera de otro tipo distinto a menos que se haga una conversión (casting).\n",
    "\n",
    "Por otra parte, **no es necesario inicializar las variables**, aunque en algunos casos inicializar y establecer posiciones de memoria previamente puede mejorar el rendimiento de nuestro código."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Asignacion\n",
    "\n",
    "Las instrucciones de asignación sirven para etiquetar los objetos en Python. La sintaxis más habitual de una operación de asignación es:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://miro.medium.com/max/82/1*z2vtb3qe8wsPviuVHGFxDQ.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Aquí, el número entero 1 (que, como todo en Python, es un objeto) tiene una etiqueta llamada a. Si reasignamos la etiqueta a, simplemente la movemos a otro objeto."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://miro.medium.com/max/199/1*KaKLH2sM3aj9gpUGKIL7zA.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ahora la etiqueta está atada al objeto 2 (que también es un número entero). El objeto original (el número 1) ya no tiene la etiqueta a. Puede que todavía exista, pero no podemos acceder a él a través de esta etiqueta. (Cuando un objeto no tiene más referencias o etiquetas, es eliminado)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"soy un string\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](../img/variables_objetos_01.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = 78"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](../img/variables_objetos_02.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Con estos ejemplos ejemplificamos que **el valor del objeto no cambió durante la vida del objeto. Por lo contrario, se creó otro objeto**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "v = s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](../img/variables_objetos_03.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Indexado\n",
    "\n",
    "Python indexa **comenzando en 0, no en 1** como en MATLAB, por ejemplo. De todas formas su sintaxis es muy parecida. Se presenta un ejemplo con string, pero como se mostrará más adelante lo mismo se aplica a otras estructura de datos.\n",
    "\n",
    "![](../img/indexado.png) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = \"Monty Python\"\n",
    "x[0]\n",
    "x[-12]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "len(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Funciones integradas\n",
    "\n",
    "A continuación se presenta algunas de las **funciones útiles**, que vienen **integradas en Python** (sin necesidad de importar ningún módulo), que pueden ser utilizadas con la mayoría de los datos. Estas funciones son pertenecientes a la [librería estandar](https://docs.python.org/3/library/) de Python."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Devuelve la longitud de una secuencia o colección\n",
    "len([1,2,3,4,6])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Imprime expresiones\n",
    "print(\"introducción informal a Python 3\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Función para ingresos de datos\n",
    "input()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Funciones de casting\n",
    "int(10)\n",
    "float(10)\n",
    "str(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Un ejemplo de aplicación\n",
    "x = 9 ** 10\n",
    "print(x)\n",
    "len(str(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Referencias usadas en el notebook\n",
    "\n",
    "* Cano, Juan Luis. Curso Aero Python. Extraido de [GitHub](https://github.com/AeroPython/Curso_AeroPython), 2016.\n",
    "* G. Van Rossum. El tutorial de Python. Extraido de [PyAr](http://docs.python.org.ar/tutorial/), 2018.\n",
    "* Datos y variables, 2009.\n",
    "* Massimo Di Pierro. Web2py - Manual de Referencia. Extraido de [www.web2py.com](http://www.web2py.com/books/default/chapter/36/02/el-lenguaje-python), 2018.\n",
    "* Eugenia Bahit. Python para principiante. Extraido de [Libros Web](http://librosweb.es/libro/python/), 2018.\n",
    "* INTI - Electrónica e Informática, UT Comunicaciones. Introducción al Procesamiento Digital de Señales, 2017.\n",
    "* Axel Kennedal. Difference between if, else and elif?. Extraido de [codecademy](https://www.codecademy.com/forum_questions/51684a3d4ce76309b4001b9c), 2013."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Licencia\n",
    "\n",
    "<a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\"><img alt=\"Licencia de Creative Commons\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-sa/4.0/88x31.png\" /></a><br />Este documento se destribuye con una <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\">licencia Atribución CompartirIgual 4.0 Internacional de Creative Commons</a>.\n",
    "\n",
    "© 2020. Infiniem Labs Acústica. infiniemlab.dsp@gmail.com (CC BY-SA 4.0))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}