{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\"AeroPython\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Clase 1a: Introducción a IPython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_\n", "En esta clase haremos una rápida introducción al lenguaje Python y al intérprete IPython, así como a su Notebook. Veremos como ejecutar un script y cuáles son los tipos y estructuras básicas de este lenguaje. Seguro que ya has oído hablar mucho sobre las bondades de Python frente a otros lenguajes. Si no es así, échale un vistazo a [esto](http://nbviewer.ipython.org/github/AeroPython/Python_HA/blob/master/razones_python.ipynb).\n", "¿Estás preparado? ¡Pues Empezamos!\n", "_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ¿Qué es Python? " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Lenguaje de programación dinámico, interpretado y fácil de aprender\n", "* Creado por Guido van Rossum en 1991\n", "* Ampliamente utilizado en ciencia e ingeniería\n", "* Multitud de bibliotecas para realizar diferentes tareas." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### El zen de Python" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The Zen of Python, by Tim Peters\n", "\n", "Beautiful is better than ugly.\n", "Explicit is better than implicit.\n", "Simple is better than complex.\n", "Complex is better than complicated.\n", "Flat is better than nested.\n", "Sparse is better than dense.\n", "Readability counts.\n", "Special cases aren't special enough to break the rules.\n", "Although practicality beats purity.\n", "Errors should never pass silently.\n", "Unless explicitly silenced.\n", "In the face of ambiguity, refuse the temptation to guess.\n", "There should be one-- and preferably only one --obvious way to do it.\n", "Although that way may not be obvious at first unless you're Dutch.\n", "Now is better than never.\n", "Although never is often better than *right* now.\n", "If the implementation is hard to explain, it's a bad idea.\n", "If the implementation is easy to explain, it may be a good idea.\n", "Namespaces are one honking great idea -- let's do more of those!\n" ] } ], "source": [ "import this" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ¿Qué pinta tiene un programa en Python y cómo lo ejecuto?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vamos a ver `mi_primer_script.py` que está en la carpeta `static`. __De momento no te preocupes por el código,__ ya habrá tiempo para eso..." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "import math\r\n", " \r\n", "print(\"Hola gente del curso de AeroPython\")\r\n", "print(\"¿Cuántos sois hoy en clase?\")\r\n", "\r\n", "number = input()\r\n", "number = int(number)\r\n", "root = math.sqrt(number)\r\n", "\r\n", "print(\"Ufff! eso es un montón! espero que aprendáis mucho\")\r\n", "print(\"Por cierto, la raiz de %i es %f\" %(number, root))\r\n" ] } ], "source": [ "!cat ../static/mi_primer_script.py" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Tip de IPython:\n", "`cat` es un comando de la línea de comandos, no propio de Python. Anteponiendo `!` a comandos de la terminal como `cd`, `ls`, `cat`... se pueden ejecutar desde aquí.\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Si estás usando Windows y acabas de obtener un error, susituye la línea anterior por:
\n", " `!type ..\\static\\mi_primer_script.py`\n", "\n", "

\n", "`type` es un comando similar en Windows a `cat`. De nuevo, podemos ejecutar comandos como `cd`, `dir`, `type`, `find`... desde aquí anteponiendo `!` y utilizando `\\` en lugar de `/` para la ruta donde se encuentra el archivo.\n", " \n", "
" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hola gente del curso de AeroPython\n", "¿Cuántos sois hoy en clase?\n", "45\n", "Ufff! eso es un montón! espero que aprendáis mucho\n", "Por cierto, la raiz de 45 es 6.708204\n" ] } ], "source": [ "%run ../static/mi_primer_script.py" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Tip de IPython:\n", "`%run` es un _comando mágico_ del notebook que te permite ejecutar un archivo.\n", "\n", "Si quieres hacerlo desde una línea de comandos podrías hacer:\n", "\n", "`$ python3 ../static/mi_primer_script.py`\n", "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El método más simple es usar un editor (tu preferido) y ejecutar el script desde la línea de comandos. Pero existen también __IDE__s (_integrated development environment_ pensados para facilitar la escritura de código y tener al alcance de la mano otras herramientas como _profilers_, _debuggers_, _explorador de variables_... Entre los más adecuados para la programación científica se encuentran [IEP](http://www.iep-project.org/) y [Spyder](http://code.google.com/p/spyderlib/) (instalado con Anaconda)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Spyder\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ¿Qué es IPython?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[IPython](http://ipython.org/) no es más que un [intérprete][1] de Python con algunas mejoras sustanciales, pero además su interfaz notebook es más cómoda de manejar que la línea de comandos y nos da un poco más de flexibilidad.\n", "\n", "[1]: http://es.wikipedia.org/wiki/Int%C3%A9rprete_(inform%C3%A1tica)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Notebook de IPython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Será nuestra herramienta de trabajo durante el curso__. Esto que estás leyendo ahora no es más que un notebook de IPython, que como diremos luego además de código puede contener texto e imágenes. Pero veamos primero cómo funciona.\n", "\n", "__Al iniciar el notebook de IPython, en la pantalla principal podemos ver una ruta y una lista de notebooks__. Cada notebook es un archivo que está almacenado en el ordenador en la ruta que aparece. Si en esa carpeta no hay notebooks, veremos un mensaje indicando que la lista de notebooks está vacía.\n", "\n", "Al crear un notebook o al abrir uno nuevo se abre la interfaz de IPython propiamente dicha donde ya podemos empezar a trabajar. Es similar a un intérprete, pero está dividida en **celdas**. Las celdas pueden contener, código, texto, imágenes...\n", "\n", "Cada celda de código está marcada por la palabra `In []` y están **numeradas**. Tan solo tenemos que escribir el código en ella y hacer click arriba en Cell -> Run, el triángulo (\"Run cell\") o usar el atajo `shift + Enter`. El resultado de la celda se muestra en el campo `Out []`, también numerado y coincidiendo con la celda que acabamos de ejecutar. Esto es importante, como ya veremos luego.\n", "\n", "Si en la barra superior seleccionas Markdown (o usas el atajo `Shift-M`) en lugar de Code puedes escribir texto:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "Image(url=\"../static/markdown_cell.gif\")\n", "# Fuente Practical Numerical Methods with Python \n", "# http://openedx.seas.gwu.edu/courses/GW/MAE6286/2014_fall/about" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "También ecuaciones en latex y mucho más. Esto es una herramienta muy potente para explicar a alguien o a ti mismo lo que tu código hace, para hacer un informe, un trabajo, escribir en un blog...\n", "\n", "Markdown es un lenguaje aparte, no te preocupes por él demasiado ahora, irás aprendiendo sobre la marcha... Para cuando lo vayas necesitando, aquí tienes una [chuleta](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Image(url=\"../static/markdown_math.gif\")\n", "# Fuente Practical Numerical Methods with Python \n", "# http://openedx.seas.gwu.edu/courses/GW/MAE6286/2014_fall/about" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Puedes mover las celdas de un lugar a otro de este modo:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Image(url=\"../static/cell_move.gif\")\n", "# Fuente: Practical Numerical Methods with Python \n", "# http://openedx.seas.gwu.edu/courses/GW/MAE6286/2014_fall/about" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El Notebook tiene además numerosos atajos que irás aprendiendo sobre la marcha, puedes consultarlos en `Help > Keyboard Shortcourts`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introducción a la sintaxis de Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tipos numéricos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python dispone de los tipos numéricos y las operaciones más habituales:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "7.0" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 * 4 - (7 - 1) / 3 + 1.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las divisiones por cero lanzan un error:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;36m1\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" ] } ], "source": [ "1 / 0 " ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "float division by zero", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;36m1.0\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;36m0.0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m: float division by zero" ] } ], "source": [ "1.0 / 0.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Más adelante veremos cómo tratar estos errores. Por otro lado, cuando usemos NumPy esta operación devolverá `NaN`.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La división entre enteros en Python 3 devuelve un número real, al contrario que en Python 2." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.5" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 / 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se puede forzar que la división sea entera con el operador `//`: " ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 // 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se puede elevar un número a otro con el operador `**`:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "65536" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 ** 16" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Otro tipo que nos resultará muy útil son los complejos:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2+3j)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 + 3j" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1j" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1j" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3.605551275463989" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Valor absoluto\n", "abs(2 + 3j)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Tip de IPython: podemos recuperar resultados pasados usando `_`. 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": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3.605551275463989" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "abs(_13)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos __convertir variables__ a `int, float, complex, str`..." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "18" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "int(18.6)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "19" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "round(18.6)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "float(1)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2+0j)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "complex(2)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'256568'" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "str(256568)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos __comprobar el tipo de una variable__:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 2.\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "isinstance(a, float)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Otras funciones útiles son:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hola mundo\n" ] } ], "source": [ "print('hola mundo')" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max(1,5,8,7)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "-1" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "min(-1,1,0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__¡Acabas de utilizar funciones!__ Como ves es una manera bastante estándar: los argumentos se encierran entre paréntesis y se separan por comas. Se hace de esta manera en otros lenguajes de programación y no requiere mayor explicación, de momento." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
La función print es la que se usa para imprimir resultados por pantalla. Por si lo ves en algún sitio, en Python 2 era una sentencia y funcionaba de manera distinta, sin paréntesis y sin posibilidad de pasar argumentos adicionales.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Asignación y operadores de comparación" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La asignación se realiza con el operador `=`. Los nombres de las variables en Python pueden contener caracteres alfanuméricos (empezando con una letra) a-z, A-Z, 0-9 y otros símbolos como la \\_. \n", "\n", "Por cuestiones de estilo, las variables suelen empezar con minúscula, reservando la mayúcula para clases. \n", "\n", "Algunos nombres no pueden ser usados porque son usados por python:\n", "\n", " and, as, assert, break, class, continue, def, del, elif, else, except, exec, finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, raise, return, try, while, with, yield" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = 1 + 2j" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En Python __la asignación no imprime el resultado por pantalla__, al contrario de como sucede en MATLAB y Octave (salvo que se incluya el punto y coma al final). La mejor manera de visualizar la variable que acabamos de asignar es esta:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3.14159" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = 3.14159\n", "b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En una celda __podemos escribir código que ocupe varias líneas__. Si la última de ellas devuelve un resultado, este se imprimirá." ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(1, 2)" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x, y = 1, 2\n", "x, y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Podemos realizar **asignación múltiple**, que hemos hecho en la celda anterior con las variables `x` e `y` para intercambiar valores de manera intuitiva:
" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2, 1)" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x, y = y, x\n", "x, y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los operadores de comparación son:\n", "\n", "* `==` igual a\n", "* `!=` distinto de \n", "* `<` menor que\n", "* `<=` menor o igual que\n", "\n", "Devolverán un booleano: `True` o `False`" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x == y" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(x != y)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "False\n", "True\n", "True\n" ] } ], "source": [ "print(x < y)\n", "print(x <= y)\n", "print(x > y)\n", "print(x >= y)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# incluso:\n", "x = 5.\n", "6. < x < 8." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si la ordenación no tiene sentido nos devolverá un error:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "ename": "TypeError", "evalue": "unorderable types: complex() < complex()", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;36m1\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1j\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m0\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1j\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: unorderable types: complex() < complex()" ] } ], "source": [ "1 + 1j < 0 + 1j" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# En las cadenas de texto sí existe un orden\n", "'aaab' > 'ba'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Booleanos" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "True and False" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "not False" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "True or False" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "20" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Una curiosidad:\n", "(True + True) * 10 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Otros tipos de datos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Otro tipo de datos muy importante que vamos a usar son las secuencias: las tuplas y las listas. Ambos son conjuntos ordenados de elementos: las tuplas se demarcan con paréntesis y las listas con corchetes." ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3.0, (4+0j), '5']\n", "(1, 2, 3.0, (4+0j), '5')\n", "False\n" ] } ], "source": [ "una_lista = [1, 2, 3.0, 4 + 0j, \"5\"]\n", "una_tupla = (1, 2, 3.0, 4 + 0j, \"5\")\n", "print(una_lista)\n", "print(una_tupla)\n", "print(una_lista == una_tupla)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para las tuplas, podemos incluso obviar los paréntesis:" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "tuple" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tupla_sin_parentesis = 2,5,6,9,7\n", "type(tupla_sin_parentesis)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En los dos tipos podemos:\n", "\n", "* Comprobar si un elemento está en la secuencia con el operador `in`:" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 in una_lista" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 in una_tupla" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Saber cuandos elementos tienen con la función `len`:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(una_lista)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Podemos *indexar* las secuencias, utilizando la sintaxis `[::]`:" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "[1, 2]\n", "(1, 2, 3.0)\n", "5\n", "(1, 2, 3.0, (4+0j), '5')\n", "[1, 3.0, '5']\n" ] } ], "source": [ "print(una_lista[0]) # Primer elemento, 1\n", "print(una_tupla[1]) # Segundo elemento, 2\n", "print(una_lista[0:2]) # Desde el primero hasta el tercero, excluyendo este: 1, 2\n", "print(una_tupla[:3]) # Desde el primero hasta el cuarto, excluyendo este: 1, 2, 3.0\n", "print(una_lista[-1]) # El último: 4 + 0j\n", "print(una_tupla[:]) # Desde el primero hasta el último\n", "print(una_lista[::2]) # Desde el primero hasta el último, saltando 2: 1, 3.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " Veremos más cosas acerca de indexación en NumPy, así que de momento no te preocupes. Sólo __recuerda una cosa:__" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### ¡En Python, la indexación empieza por CERO!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos complicarlo un poco más y hacer cosas como una __lista de listas__:" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[['Álgebra', 'Cálculo', 'Física'],\n", " ['Mecánica', 'Termodinámica'],\n", " ['Sólidos', 'Electrónica']]" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mis_asignaturas = [\n", "['Álgebra', 'Cálculo', 'Física'],\n", "['Mecánica', 'Termodinámica'],\n", "['Sólidos', 'Electrónica']\n", "]\n", "mis_asignaturas" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Esto nos será de gran ayuda en el futuro para construir arrays." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Estructuras de control (I): Condicionales" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " if :\n", " \n", " elif :\n", " \n", " else:\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Importante: En Python los bloques se delimitan por sangrado, utilizando siempre cuatro espacios. Cuando ponemos los dos puntos al final de la primera línea del condicional, todo lo que vaya a continuación con *un* nivel de sangrado superior se considera dentro del condicional. En cuanto escribimos la primera línea con un nivel de sangrado inferior, hemos cerrado el condicional. Si no seguimos esto a rajatabla Python nos dará errores; es una forma de forzar a que el código sea legible.
" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.0 1\n", "x es mayor que y\n", "x sigue siendo mayor que y\n" ] } ], "source": [ "print(x,y)\n", "if x > y:\n", " print(\"x es mayor que y\")\n", " print(\"x sigue siendo mayor que y\")" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 sigue siendo menor que 0\n" ] } ], "source": [ "if 1 < 0:\n", " print(\"1 es menor que 0\")\n", "print(\"1 sigue siendo menor que 0\") # <-- ¡Mal!" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [ { "ename": "IndentationError", "evalue": "unexpected indent (, line 3)", "output_type": "error", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m3\u001b[0m\n\u001b[1;33m print(\"1 sigue siendo menor que 0\")\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m unexpected indent\n" ] } ], "source": [ "if 1 < 0:\n", " print(\"1 es menor que 0\")\n", " print(\"1 sigue siendo menor que 0\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si queremos añadir ramas adicionales al condicional, podemos emplear la sentencia `elif` (abreviatura de *else if*). Para la parte final, que debe ejecutarse si ninguna de las condiciones anteriores se ha cumplido, usamos la sentencia `else`:" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.0 1\n", "x es mayor que y\n" ] } ], "source": [ "print(x,y)\n", "if x > y:\n", " print(\"x es mayor que y\")\n", "else:\n", " print(\"x es menor que y\")" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.0 1\n", "x no es ni menor ni igual que y\n" ] } ], "source": [ "print(x, y)\n", "if x < y:\n", " print(\"x es menor que y\")\n", "elif x == y:\n", " print(\"x es igual a y\")\n", "else:\n", " print(\"x no es ni menor ni igual que y\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Estructuras de control (II): Bucles" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En Python existen dos tipos de estructuras de control típicas:\n", "\n", "1. Bucles `while`\n", "2. Bucles `for`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `while` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los bucles `while` repetiran las sentencias anidadas en él mientras se cumpla una condición:\n", "\n", " while :\n", " \n", " \n", "Como en el caso de los condicionales, los bloques se separan por indentación sin necesidad de sentencias del tipo `end`" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-2\n", "-1\n", "0\n", "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "ii = -2\n", "while ii < 5:\n", " print(ii)\n", " ii += 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Tip: \n", "`ii += 1` equivale a `ii = ii + 1`. En el segundo Python, realiza la operación ii + 1 creando un nuevo objeto con ese valor y luego lo asigna a la variable ii; es decir, existe una reasignación. En el primero, sin embargo, el incremento se produce sobre la propia variable. Esto puede conducirnos a mejoras en velocidad.\n", "\n", "Otros operadores 'in-place' son: `-=`, `*=`, `/=` \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se puede interrumpir el bucle a la mitad con la sentencia `break`:" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n" ] } ], "source": [ "ii = 0\n", "while ii < 5:\n", " print(ii)\n", " ii += 1\n", " if ii == 3:\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un bloque `else` justo después del bucle se ejecuta si este no ha sido interrumpido por nosotros:" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n" ] } ], "source": [ "ii = 0\n", "while ii < 5:\n", " print(ii)\n", " ii += 1\n", " if ii == 3:\n", " break\n", "else:\n", " print(\"El bucle ha terminado\")" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "El bucle ha terminado\n" ] } ], "source": [ "ii = 0\n", "while ii < 5:\n", " print(ii)\n", " ii += 1\n", " #if ii == 3:\n", " #break\n", "else:\n", " print(\"El bucle ha terminado\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `for`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El otro bucle en Python es el bucle `for`, y funciona de manera un que puede resultar chocante al principio. La idea es recorrer un conjunto de elementos:\n", "\n", " for in :\n", " " ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "4\n", "5\n" ] } ], "source": [ "for ii in (1,2,3,4,5):\n", " print(ii)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Juanlu\n", "Siro\n", "Carlos\n" ] } ], "source": [ "for nombre in \"Juanlu\", \"Siro\", \"Carlos\":\n", " print(nombre)" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n" ] } ], "source": [ "for ii in range(3):\n", " print(ii)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n", "4\n" ] } ], "source": [ "for jj in range(2, 5):\n", " print(jj)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## PEP 8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__La guía de estilo:__\n", "\n", "* Usa sangrado de 4 espacios, no tabuladores [IPython o tu editor se encargan de ello].\n", "* Acota las líneas a 79 caracteres.\n", "* Usa líneas en blanco para separar funciones y bloques de código dentro de ellas.\n", "* Pon los comentarios en líneas aparte si es posible.\n", "* Usa cadenas de documentación (*docstrings*).\n", "* Pon espacios alrededor de los operadores y después de coma.\n", "* Usa la convención minuscula_con_guiones_bajos para los nombres de las funciones y las variables.\n", "* Aunque Python 3 te lo permite, no uses caracteres especiales para los identificadores.\n", "\n", "(Traducido de http://docs.python.org/3/tutorial/controlflow.html#intermezzo-coding-style)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Utilizando el módulo pep8\n", "\n", "https://pypi.python.org/pypi/pep8\n", "\n", "Y la extensión pep8magic\n", "\n", "https://gist.github.com/Juanlu001/9082229/\n", "\n", "Podemos comprobar si una celda de código cumple con las reglas del PEP8:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_Hemos visto como la sintaxis de Python nos facilita escribir código legible así como aprendido algunas buenas prácticas al programar. Características como el tipado dinámico (no hace falta declarar variables) y ser lenguaje interpretado (no hace falta compilarlo) hacen que el tiempo que pasamos escrbiendo código sea menos que en otro tipo de lenguajes._\n", "\n", "_Se han presentado los tipos de variables, así como las estructuras de control básicas. En la siguiente clase practicaremos con algunos ejercicios para que te familiarices con ellas_\n", "\n", "_Esperamos también que poco a poco te sientas cada vez más a gusto con el Notebook de IPython y puedas sacarle todo el partido_\n", "\n", "__Referencias__\n", "\n", "* Tutorial de Python oficial actualizado y traducido al español http://docs.python.org.ar/tutorial/\n", "* Vídeo de 5 minutos de IPython http://youtu.be/C0D9KQdigGk\n", "* Introducción a la programación con Python, Universitat Jaume I http://www.uji.es/bin/publ/edicions/ippython.pdf\n", "* PEP8 http://www.python.org/dev/peps/pep-0008/‎" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "Clase en vídeo, parte del [Curso de Python para científicos e ingenieros](http://cacheme.org/curso-online-python-cientifico-ingenieros/) grabado en la Escuela Politécnica Superior de la Universidad de Alicante." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import YouTubeVideo\n", "\n", "YouTubeVideo(\"ox09Jko1ErM\", width=560, height=315, list=\"PLGBbVX_WvN7bMwYe7wWV5TZt1a58jTggB\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si te ha gustado esta clase:\n", "\n", "Tweet\n", "\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "####

¡Síguenos en Twitter!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###### Follow @AeroPython " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### \"Licencia
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "_Las siguientes celdas contienen configuración del Notebook_\n", "\n", "_Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como [seguro](http://ipython.org/ipython-doc/dev/notebook/security.html)_\n", "\n", " File > Trusted Notebook" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "Follow @AeroPython\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "Follow @AeroPython\n", "" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "El estilo se ha aplicado =)\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Esta celda da el estilo al notebook\n", "from IPython.core.display import HTML\n", "css_file = '../static/styles/style.css'\n", "HTML(open(css_file, \"r\").read())" ] } ], "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.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }