{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Parte 1 - Introducci\u00f3n a Python e IPython" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "\u00bfQu\u00e9 es Python?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Lenguaje de programaci\u00f3n din\u00e1mico, interpretado y f\u00e1cil de aprender\n", "* Creado por Guido van Rossum en 1991\n", "* Ampliamente utilizado en ciencia e ingenier\u00eda\n", "* Multitud de bibliotecas" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "El zen de Python" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import this" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "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" ] } ], "prompt_number": 1 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Contacto con el notebook de IPython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Durante este curso utilizaremos el notebook de IPython para trabajar. IPython no es m\u00e1s que un int\u00e9rprete de Python con algunas mejoras sustanciales, pero adem\u00e1s su interfaz notebook es m\u00e1s c\u00f3moda de manejar que la l\u00ednea de comandos y nos da un poco m\u00e1s de flexibilidad." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Esto que est\u00e1s leyendo ahora no es m\u00e1s que un notebook de IPython, que como diremos luego adem\u00e1s de c\u00f3digo puede contener texto e im\u00e1genes. Pero veamos primero c\u00f3mo funciona." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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\u00e1 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\u00e1 vac\u00eda." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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\u00e9rprete, pero est\u00e1 dividida en **celdas**. Cada celda est\u00e1 marcada por la palabra `In []` y est\u00e1n **numeradas**. Tan solo tenemos que escribir el c\u00f3digo en ella y hacer click arriba en Cell -> Run, el tri\u00e1ngulo (\"Run cell\") o usar el atajo `shift + Enter`. El resultado de la celda se muestra en el campo `Out []`, tambi\u00e9n numerado y coincidiendo con la celda que acabamos de ejecutar. Esto es importante, como ya veremos luego." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vamos ahora a hacer una introducci\u00f3n muy r\u00e1pida a la sintaxis de Python, y a medida que avancemos iremos describiendo m\u00e1s caracter\u00edsticas de IPython que nos pueden resultar \u00fatiles." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Introducci\u00f3n a la sintaxis de Python" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Tipos num\u00e9ricos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Naturalmente disponemos de los tipos num\u00e9ricos y las operaciones habituales:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "2 * 4 - (7 - 1) / 3 + 1.0" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 2, "text": [ "7.0" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las divisiones por cero lanzan un error:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "1 / 0" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\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" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "1.0 / 0.0" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "float division by zero", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\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" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "
M\u00e1s adelante veremos c\u00f3mo tratar estos errores. Por otro lado, cuando usemos NumPy esta operaci\u00f3n devolver\u00e1 `NaN`.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La divisi\u00f3n entre enteros en Python 3 devuelve un n\u00famero real, al contrario que en Python 2." ] }, { "cell_type": "code", "collapsed": false, "input": [ "3 / 2" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 5, "text": [ "1.5" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para forzar la divisi\u00f3n entera, podemos usar el operador `//`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "3 // 2" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 6, "text": [ "1" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adem\u00e1s, Python incluye tambi\u00e9n n\u00fameros complejos:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "2 + 3j" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 7, "text": [ "(2+3j)" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "(3 + 2j) * (1 - 1j)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 8, "text": [ "(5-1j)" ] } ], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "(1j) ** 2" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 9, "text": [ "(-1+0j)" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para hallar el valor absoluto:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "abs(3 + 2j)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 10, "text": [ "3.605551275463989" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Tip de IPython: podemos recuperar resultados pasados usando `_`. Por ejemplo, para recuperar el resultado correspondiente a `Out [7]`, usar\u00edamos `_7`. Esta variable guarda ese valor para toda la sesi\u00f3n.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para convertir entre tipos num\u00e9ricos podemos usar las funciones `int`, `float` y `complex`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "_10" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "3.605551275463989" ] } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "int(_)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 12, "text": [ "3" ] } ], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Al convertir a `int` descartamos la parte entera. Si en realidad queremos redondear:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "round(_10)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 13, "text": [ "4" ] } ], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "float(_)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 14, "text": [ "4.0" ] } ], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "complex(_)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 15, "text": [ "(4+0j)" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Otras funciones \u00fatiles:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "max(0, -1, 1, 2)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 16, "text": [ "2" ] } ], "prompt_number": 16 }, { "cell_type": "code", "collapsed": false, "input": [ "min(1, 2, 0, -1)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 17, "text": [ "-1" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Nota: Esta es la manera de llamar funciones en Python: los argumentos se encierran entre par\u00e9ntesis y se separan por comas. Se hace de esta manera en otros lenguajes de programaci\u00f3n y no requiere mayor explicaci\u00f3n, de momento.
" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Asignaci\u00f3n y operadores de comparaci\u00f3n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La asignaci\u00f3n en Python funciona con el operador `=`" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = 1 + 2j" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Nota: En Python la asignaci\u00f3n 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", "collapsed": false, "input": [ "a = 1 + 2j\n", "a" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 19, "text": [ "(1+2j)" ] } ], "prompt_number": 19 }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Tip de IPython: En una celda podemos escribir c\u00f3digo que ocupe varias l\u00edneas. Si la \u00faltima de ellas devuelve un resultado, este se imprimir\u00e1.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos encadenar varias asignaciones:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "x, y = 1, 2\n", "x, y" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 20, "text": [ "(1, 2)" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Podemos realizar **asignaci\u00f3n m\u00faltiple**, que hemos hecho en la celda anterior con las variables `x` e `y` para intercambiar valores de manera intuitiva:
" ] }, { "cell_type": "code", "collapsed": false, "input": [ "x, y = y, x\n", "x, y" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 21, "text": [ "(2, 1)" ] } ], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los operadores de comparaci\u00f3n son `==`, `!=`, `<`, `<=`, `>`, `>=`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "x, y = 1, 2\n", "x, y" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 22, "text": [ "(1, 2)" ] } ], "prompt_number": 22 }, { "cell_type": "code", "collapsed": false, "input": [ "print(x == y)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "False\n" ] } ], "prompt_number": 23 }, { "cell_type": "code", "collapsed": false, "input": [ "print(x != y)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "True\n" ] } ], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "print(x < y)\n", "print(x <= y)\n", "print(x > y)\n", "print(x >= y)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "True\n", "True\n", "False\n", "False\n" ] } ], "prompt_number": 25 }, { "cell_type": "markdown", "metadata": {}, "source": [ "
La funci\u00f3n print es la que se usa para imprimir resultados por pantalla. En Python 2 era una sentencia y funcionaba de manera distinta, sin par\u00e9ntesis y sin posibilidad de pasar argumentos adicionales.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si la ordenaci\u00f3n no tiene sentido, obtenemos un error:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "1 + 1j < 0 + 1j" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "unorderable types: complex() < complex()", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\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()" ] } ], "prompt_number": 26 }, { "cell_type": "heading", "level": 3, "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\u00e9ntesis y las listas con corchetes." ] }, { "cell_type": "code", "collapsed": false, "input": [ "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)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[1, 2, 3.0, (4+0j), '5']\n", "(1, 2, 3.0, (4+0j), '5')\n", "False\n" ] } ], "prompt_number": 27 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para las tuplas, podemos incluso obviar los par\u00e9ntesis:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "1, 2, 3.0" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 28, "text": [ "(1, 2, 3.0)" ] } ], "prompt_number": 28 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los dos tipos tienen varias cosas en com\u00fan. En particular:\n", "\n", "* Podemos comprobar si un elemento est\u00e1 en la secuencia con el operador `in`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "2 in una_tupla" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 29, "text": [ "True" ] } ], "prompt_number": 29 }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Podemos saber cu\u00e1ntos elementos tiene la secuencia con la funci\u00f3n `len`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "len(una_lista)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 30, "text": [ "5" ] } ], "prompt_number": 30 }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Podemos *indexar* las secuencias, utilizando la sintaxis `[::]`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "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 \u00faltimo: 4 + 0j\n", "print(una_tupla[:]) # Desde el primero hasta el \u00faltimo\n", "print(una_lista[::2]) # Desde el primero hasta el \u00faltimo, saltando 2: 1, 3.0" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "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" ] } ], "prompt_number": 31 }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Nota: \u00a1En Python la indexaci\u00f3n empieza por cero!
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "F\u00edjate en dos detalles:\n", "\n", "* Cuando especificamos \u00edndices negativos, recorremos el array desde el final hasta el principio. Por eso `[-1]` da el \u00faltimo elemento, `[-2]` el pen\u00faltimo y as\u00ed sucesivamente.\n", "* Hemos utilizado la notaci\u00f3n `[::2]` para el \u00faltimo caso. Esto es una manera abreviada de escribir `[0:-1:2]`, es decir, si no decimos nada empezamos en el principio y terminamos en el final. Por eso `[:]` devuelve todos los elementos de la secuencia." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Naturalmente, las sequencias se pueden anidar: por ejemplo, una lista puede contener, a su vez, m\u00e1s listas." ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = [\n", " [1, 2, 3],\n", " [4, 5],\n", "]\n", "print(a)\n", "print(a[0])\n", "print(a[0][0])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[[1, 2, 3], [4, 5]]\n", "[1, 2, 3]\n", "1\n" ] } ], "prompt_number": 32 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Esto nos ser\u00e1 de gran ayuda en el futuro para construir arrays." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Estructuras de control (I): condicionales" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En Python, los condicionales siguen esta estructura:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(x, y)\n", "if x < y:\n", " print(\"x es menor que y\")\n", " print(\"x sigue siendo menor que y\")" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 2\n", "x es menor que y\n", "x sigue siendo menor que y\n" ] } ], "prompt_number": 33 }, { "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\u00ednea del condicional, todo lo que vaya a continuaci\u00f3n con *un* nivel de sangrado superior se considera dentro del condicional. En cuanto escribimos la primera l\u00ednea con un nivel de sangrado inferior, hemos cerrado el condicional. Si no seguimos esto a rajatabla Python nos dar\u00e1 errores; es una forma de forzar a que el c\u00f3digo sea legible.
" ] }, { "cell_type": "code", "collapsed": false, "input": [ "if 1 < 0:\n", " print(\"1 es menor que 0\")\n", "print(\"1 sigue siendo menor que 0\") # <-- \u00a1Mal!" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 sigue siendo menor que 0\n" ] } ], "prompt_number": 34 }, { "cell_type": "code", "collapsed": false, "input": [ "if 1 < 0:\n", " print(\"1 es menor que 0\")\n", " print(\"1 sigue siendo menor que 0\")" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "IndentationError", "evalue": "unexpected indent (, line 3)", "output_type": "pyerr", "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" ] } ], "prompt_number": 35 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si queremos a\u00f1adir 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", "collapsed": false, "input": [ "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\")" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 2\n", "x es menor que y\n" ] } ], "prompt_number": 36 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Estructuras de control (II): bucles" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los bucles tambi\u00e9n se demarcan con el sangrado. En Python hay dos tipos de bucles: `while` y `for`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "ii = 0\n", "while ii < 5:\n", " print(ii)\n", " ii += 1" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n" ] } ], "prompt_number": 37 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos interrumpir el bucle a la mitad usando la sentencia `break`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ii = 0\n", "while ii < 5:\n", " print(ii)\n", " ii += 1\n", " if ii == 3:\n", " break" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "1\n", "2\n" ] } ], "prompt_number": 38 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un bloque `else` justo despu\u00e9s del bucle se ejecuta si este no ha sido interrumpido por nosotros:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "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\")" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "1\n", "2\n" ] } ], "prompt_number": 39 }, { "cell_type": "code", "collapsed": false, "input": [ "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\")" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "El bucle ha terminado\n" ] } ], "prompt_number": 40 }, { "cell_type": "markdown", "metadata": {}, "source": [ "El otro bucle en Python es el bucle `for`, y funciona de manera un poco peculiar. La idea es recorrer un conjunto de elementos:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for ii in 1, 2, 4:\n", " print(ii)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1\n", "2\n", "4\n" ] } ], "prompt_number": 41 }, { "cell_type": "code", "collapsed": false, "input": [ "for nombre in \"Juan\", \"Luis\", \"Carlos\":\n", " print(nombre)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Juan\n", "Luis\n", "Carlos\n" ] } ], "prompt_number": 42 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Una cosa que haremos de manera recurrente ser\u00e1 recorrer un rango de n\u00fameros. Esto lo conseguimos con la funci\u00f3n range:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for ii in range(3):\n", " print(ii)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "1\n", "2\n" ] } ], "prompt_number": 43 }, { "cell_type": "code", "collapsed": false, "input": [ "for jj in range(2, 5):\n", " print(jj)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2\n", "3\n", "4\n" ] } ], "prompt_number": 44 }, { "cell_type": "markdown", "metadata": {}, "source": [ "***" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Definici\u00f3n de funciones" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para definir nuestra propia funci\u00f3n utilizamos la sentencia `def` seguida del nombre de la misma y entre par\u00e9ntesis los argumentos de entrada. La primera l\u00ednea de la funci\u00f3n puede ser una cadena de documentaci\u00f3n." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def funcion(x, y):\n", " \"\"\"Funci\u00f3n de prueba.\"\"\"\n", " pass" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 45 }, { "cell_type": "code", "collapsed": false, "input": [ "funcion" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 46, "text": [ "" ] } ], "prompt_number": 46 }, { "cell_type": "code", "collapsed": false, "input": [ "funcion.__doc__" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 47, "text": [ "'Funci\u00f3n de prueba.'" ] } ], "prompt_number": 47 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los valores de retorno de la funci\u00f3n se especifican con la sentencia `return`. Por ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def al_cuadrado(x):\n", " \"\"\"Funci\u00f3n que eleva un n\u00famero al cuadrado.\"\"\"\n", " y = x ** 2\n", " return y" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 48 }, { "cell_type": "code", "collapsed": false, "input": [ "al_cuadrado(4)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 49, "text": [ "16" ] } ], "prompt_number": 49 }, { "cell_type": "code", "collapsed": false, "input": [ "def multiplica(x, y=2.0):\n", " \"\"\"Multiplica dos n\u00fameros, por defecto el primero por 2.\"\"\"\n", " return x * y\n", "\n", "multiplica(2, 3)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 50, "text": [ "6" ] } ], "prompt_number": 50 }, { "cell_type": "code", "collapsed": false, "input": [ "multiplica(4)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 51, "text": [ "8.0" ] } ], "prompt_number": 51 }, { "cell_type": "code", "collapsed": false, "input": [ "multiplica(x, y=1.0)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 52, "text": [ "1.0" ] } ], "prompt_number": 52 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "PEP8, la gu\u00eda de estilo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Usa sangrado de 4 espacios, no tabuladores [IPython o tu editor se encargan de ello].\n", "* Acota las l\u00edneas a 79 caracteres.\n", "* Usa l\u00edneas en blanco para separar funciones y bloques de c\u00f3digo dentro de ellas.\n", "* Pon los comentarios en l\u00edneas aparte si es posible.\n", "* Usa cadenas de documentaci\u00f3n (*docstrings*).\n", "* Pon espacios alrededor de los operadores y despu\u00e9s de coma.\n", "* Usa la convenci\u00f3n 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)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Utilizando el m\u00f3dulo pep8\n", "\n", "https://pypi.python.org/pypi/pep8\n", "\n", "Y la extensi\u00f3n pep8magic\n", "\n", "https://gist.github.com/Juanlu001/9082229/\n", "\n", "Podemos comprobar si una celda de c\u00f3digo cumple con las reglas del PEP8:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%load_ext pep8magic" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 53 }, { "cell_type": "code", "collapsed": false, "input": [ "%%pep8\n", "if 6*9==42:print(\"Something fundamentally wrong...\" )" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "stdin:1:7: E225 missing whitespace around operator\n", "if 6*9==42:print(\"Something fundamentally wrong...\" )\n", " ^\n", "stdin:1:11: E231 missing whitespace after ':'\n", "if 6*9==42:print(\"Something fundamentally wrong...\" )\n", " ^\n", "stdin:1:11: E701 multiple statements on one line (colon)\n", "if 6*9==42:print(\"Something fundamentally wrong...\" )\n", " ^\n", "stdin:1:53: E202 whitespace before ')'\n", "if 6*9==42:print(\"Something fundamentally wrong...\" )\n", " ^\n" ] } ], "prompt_number": 54 }, { "cell_type": "code", "collapsed": false, "input": [ "%%pep8\n", "if 6*9 == 42:\n", " print(\"Something fundamentally wrong...\")" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "This code is PEP8-compliant!\n" ] } ], "prompt_number": 55 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Referencias" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Tutorial de Python oficial actualizado y traducido al espa\u00f1ol http://docs.python.org.ar/tutorial/\n", "* V\u00eddeo de 5 minutos de IPython http://youtu.be/C0D9KQdigGk\n", "* Introducci\u00f3n a la programaci\u00f3n con Python, Universitat Jaume I http://www.uji.es/bin/publ/edicions/ippython.pdf\n", "* PEP8 http://www.python.org/dev/peps/pep-0008/\u200e" ] } ], "metadata": {} } ] }