{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Python para ciencia e ingenier\u00eda. Clase 1/6\n", "\n", "**Tallerista**: Mart\u00edn Gait\u00e1n (Phasety)\n", "\n", "**Colaboradores**: Jairo Trad (Insus) y Juli\u00e1n Scortechini (Phasety)\n", "\n", " \n", " Agosto/Septiembre de 2013\n", "\n", "\n", "\n", "----\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Empecemos!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python es un lenguaje de programaci\u00f3n:\n", "\n", "* Interpretado\n", "* Interactivo\n", "* F\u00e1cil de aprender, programar y **leer** (menos *bugs*)\n", "* De *muy alto nivel*\n", "* Multiparadigma\n", "* Orientado a objetos\n", "* Libre y con licencia permisiva\n", "* Eficiente\n", "* Vers\u00e1til y potente! \n", "* Con gran documentaci\u00f3n\n", "* Y una gran comunidad de usuarios\n", "\n", "----\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Trivia: Sab\u00edas que...?\n", "\n", "- ... el creador de Python es un holand\u00e9s llamado Guido Van Rossum que le puso este nombre al lenguaje por su fanatismo por la comedia *Monty Python*?\n", "\n", "\n", "\n", "\n", "- Guido trabaja en Dropbox, que est\u00e1 hecho en Python?\n", "\n", "- Aunque se cree que es un \"lenguaje nuevo\", la primera versi\u00f3n es de 1991, el mismo a\u00f1o de la estandarizaci\u00f3n de [Fortran 90](http://www.iso.org/iso/catalogue_detail?csnumber=17366) y muy anterior a Java (1995)?\n", "- Google, Nasa y Walt Disney son algunas empresas/instuciones que usan Python como uno de sus principales lenguajes de programaci\u00f3n?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Instalaci\u00f3n\n", "\n", "* En Windows o mac: usaremos [Anaconda](http://continuum.io/downloads). Instal\u00e1 la versi\u00f3n que corresponda a tu OS\n", "* En linux directamente podes instalar todo lo necesario desde tus repositorios. Por ejemplo en Ubuntu: \n", "\n", "`sudo apt-get install ipython ipython-notebook spyder python-matplotlib python-numpy python-scipy python-sympy`\n", "\n", "---- \n", "\n", "### \u00bfC\u00f3mo se usa Python?\n", "\n", "#### Consolas interactivas\n", "\n", "Hay muchas maneras de usar el lenguaje Python. Cuando lo \n", "Dijimos que es un lenguaje **interpretado** e **interactivo**. Si ejecutamos la consola (`cmd.exe`) y luego `python`, se abrir\u00e1 la consola interactiva\n", "\n", "\n", "\n", "En la consola interactiva podemos escribir sentencias o peque\u00f1os bloques de c\u00f3digo que son ejecutados inmediatamente. Pero *la consola interactiva* est\u00e1ndar es **fea**. Mucho mejor usar **IPython**. \n", "\n", "\n", "\n", "La consola IPython supera a la est\u00e1ndar en muchos sentidos. Podemos autocompletar (`<TAB>`), ver ayuda r\u00e1pida de cualquier objeto (`?`) y muchas cosas m\u00e1s. \n", "\n", "\n", "#### Programas/scripts\n", "\n", "Tambi\u00e9n podemos usar Python para hacer *programas* o *scripts*. Esto es, escribir nuestro c\u00f3digo en un archivo con extensi\u00f3n *.py* y ejecutarlo con el interprete. Por ejemplo, el archivo *hello.py* (al que se le llama *m\u00f3dulo*) tiene este contenido:\n", "\n", " print \"Hello world!\"\n", "\n", "Si ejecutamos `python scripts/hello.py` se ejecutar\u00e1 n el interprete Python y obtendremos el resultado\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "!python scripts/hello.py" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Hello world!\r\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Python no exige un editor espec\u00edfico y hay muchos modos y maneras de programar. \n", "\n", "Un buen editor es **Spyder** que es un IDE (entorno integrado: editor + ayuda + consola interactiva)\n", "\n", "\n", "\n", "Pod\u00e9s ejecutar todo el m\u00f3dulo en la consola interactiva que incluye, o seleccionar una porci\u00f3n. \n", "\n", "#### Ipython Notebook\n", "\n", "Y otra forma muy \u00fatil es usar los *Notebooks*. El notebook es un entorno interactivo y enriquecido. Podemos crear y editar \"celdas\" c\u00f3digo Python que pod\u00e9s editar y volver a ejecutar, pod\u00e9s intercalar celdas de texto, f\u00f3rmulas matem\u00e1ticas, y hacer que gr\u00e1ficos se muestren inscrutados en la misma pantalla. etc. Estos archivos se guardan con extensi\u00f3n *.ipynb*, que pueden exportarse como html (est\u00e1ticos) o como c\u00f3digo python puro. (.py)\n", "\n", "Los notebooks son muy \u00fatiles para la \"programaci\u00f3n exploratoria\", muy frecuente en ciencia e ingenier\u00eda. El Dr. Dami\u00e1n \u00c1vila (amigo de la casa) los llam\u00f3 *\"Papers ejecutables\"*. \n", "\n", "Todo el material de estos cursos estar\u00e1n en formato notebook.\n", "\n", "----\n", "\n", "### \u00a1Quiero programar!\n", "\n", "\n", "Python es un lenguaje de muy alto nivel y por lo tanto trae muchos *tipos* de datos incluidos. \n", "\n", "### N\u00fameros\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "1 + 1.4 - 12" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 1, "text": [ "-9.6" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ejecuten su consola y \u00a1a practicar!" ] }, { "cell_type": "code", "collapsed": false, "input": [ "2**3" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 2, "text": [ "8" ] } ], "prompt_number": 2 }, { "cell_type": "code", "collapsed": false, "input": [ "4564654654654654122453453545544545467100003456970149034538478541340012 % 2" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 3, "text": [ "0L" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los tipos num\u00e9ricos b\u00e1sicos son *integer* (enteros sin limite), *float* (reales) y *complex* (complejos)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "(3.2 + 12j) * 2" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 4, "text": [ "(6.4+24j)" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las operaciones aritm\u00e9ticas b\u00e1sicas son:\n", "\n", "* adici\u00f3n: `+`\n", "* sustracci\u00f3n: `-`\n", "* multiplicaci\u00f3n: `*`\n", "* divisi\u00f3n: `/`\n", "* m\u00f3dulo: `%`\n", "* potencia: `**`\n", "* divisi\u00f3n entera: `//`\n", "\n", "Las operaciones se pueden agrupar con parentesis y tienen precedencia est\u00e1ndar " ] }, { "cell_type": "code", "collapsed": false, "input": [ "resultado = int((21 + 4.5)**2 / 1.2) + 1j\n", "print(resultado)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "(541+1j)\n" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Atenti**: El modo interactivo `print` *imprime* el resultado pero no *devuelve* in output. `int()` es el tipo de datos para enteros y permite forzar que el resultado sea de este tipo (truncado). \n", "\n", "El resultado qued\u00f3 guardado en la *variable* `resultado`. \n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "type(resultado)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 6, "text": [ "complex" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En Python todo es un *objeto*. Los objetos no solo *guardan* valores sino que que tienen *m\u00e9todos*. Es decir, traen \"funciones\" (acciones) que podemos ejecutarles. Prueben escribir `resutado.` y apretar `<TAB>`. Por ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "resultado.conjugate()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 7, "text": [ "(541-1j)" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En una sesi\u00f3n interactiva el `?` brinda ayuda contextual" ] }, { "cell_type": "code", "collapsed": false, "input": [ "resultado.conjugate?" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Ejercicios\n", "\n", "1. Crear una variable llamada `magnitud` con un valor real\n", "2. Definir otra variable compleja `intensidad` cuya parte real sea 1.5 veces `magnitud` y la parte imaginaria 0.3 veces `magnitud` + 1j\n", "3. Encontrar la raiz cuadrada de `intensidad`\n", "\n", "----" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Strings: Secuencias de caracteres\n", "\n", "Una cadena o *string* es una **secuencia** de caracteres (letras, n\u00fameros, simbolos). Hay dos tipos **str** y **unicode**.\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print (\"Hola mundo!\") " ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Hola mundo!\n" ] } ], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "chinito = u'\u5b57\u6f22\u5b57'" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "type(chinito)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "unicode" ] } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se pueden definir con ap\u00f3strofes, comillas, o triple comillas" ] }, { "cell_type": "code", "collapsed": false, "input": [ "calle = \"O'Higgings\"" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "\"\"\"Me gustas cuando callas\n", "porque est\u00e1s como ausente...\"\"\"" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 13, "text": [ "'Me gustas cuando callas\\nporque est\\xc3\\xa1s como ausente...'" ] } ], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "poema = _" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las cadenas tienen sus propios m\u00e9todos: pasar a may\u00fasculas, capitalizar, reemplazar una subcadena, etc. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "print poema.replace('gustas', 'molestas').replace('callas', 'hablas').replace('como ausente', 'demasiado gritona')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Me molestas cuando hablas\n", "porque est\u00e1s demasiado gritona...\n" ] } ], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "calle.lower()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 16, "text": [ "\"o'higgings\"" ] } ], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tambi\u00e9n se pueden concatenar" ] }, { "cell_type": "code", "collapsed": false, "input": [ "calle + \" fue un soldado de San Mart\u00edn\"" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 17, "text": [ "\"O'Higgings fue un soldado de San Mart\\xc3\\xadn\"" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pero las cadenas tambi\u00e9n son **secuencias**. O sea, conjuntos ordenados que se pueden indizar, recortar, reordenar, etc. \n", "\n", "\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "cadena = \"SLICEINDEX\"\n", "print len(cadena)\n", "print cadena[0]\n", "print cadena[1]\n", "print cadena[0:5]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "10\n", "S\n", "L\n", "SLICE\n" ] } ], "prompt_number": 18 }, { "cell_type": "code", "collapsed": false, "input": [ "cadena[:3], cadena[-2:], cadena[:-5]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 19, "text": [ "('SLI', 'EX', 'SLICE')" ] } ], "prompt_number": 19 }, { "cell_type": "code", "collapsed": false, "input": [ "cadena[::2] #wow!" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 20, "text": [ "'SIENE'" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Algunas operaciones" ] }, { "cell_type": "code", "collapsed": false, "input": [ "\"*\" * 80 # repetici\u00f3n" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 21, "text": [ "'********************************************************************************'" ] } ], "prompt_number": 21 }, { "cell_type": "code", "collapsed": false, "input": [ "\"%s era un groso\" % calle # interpolacion" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 22, "text": [ "\"O'Higgings era un groso\"" ] } ], "prompt_number": 22 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pero el **tipado es fuerte**. En general, los tipos no se convierten impl\u00edcitamente" ] }, { "cell_type": "code", "collapsed": false, "input": [ "\"1.2\" + 2" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "cannot concatenate 'str' and 'int' objects", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m<ipython-input-23-67bb27a69e2f>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;34m\"1.2\"\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: cannot concatenate 'str' and 'int' objects" ] } ], "prompt_number": 23 }, { "cell_type": "code", "collapsed": false, "input": [ "float(\"1.2\") + 2" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 35, "text": [ "3.2" ] } ], "prompt_number": 35 }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "\n", "### Listas y tuplas: contenedores universales" ] }, { "cell_type": "code", "collapsed": false, "input": [ "nombres = [\"Meli\", \"Nadia\", \"Daniel\"]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 36 }, { "cell_type": "code", "collapsed": false, "input": [ "type(nombres)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 37, "text": [ "list" ] } ], "prompt_number": 37 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las listas tambien son secuencias" ] }, { "cell_type": "code", "collapsed": false, "input": [ "nombres[0]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 38, "text": [ "'Meli'" ] } ], "prompt_number": 38 }, { "cell_type": "code", "collapsed": false, "input": [ "nombres[-2:]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 39, "text": [ "['Nadia', 'Daniel']" ] } ], "prompt_number": 39 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Y pueden contener cualquier tipo de objetos" ] }, { "cell_type": "code", "collapsed": false, "input": [ "mezcolanza = [1.2, \"Jairo\", 12e6, calle, nombres[1]]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 40 }, { "cell_type": "code", "collapsed": false, "input": [ "print mezcolanza" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[1.2, 'Jairo', 12000000.0, \"O'Higgings\", 'Nadia']\n" ] } ], "prompt_number": 41 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hasta ac\u00e1 son iguales a las **tuplas**" ] }, { "cell_type": "code", "collapsed": false, "input": [ "una_tupla = (\"Mart\u00edn\", 1.2, (1j, nombres[0]))\n", "print type(una_tupla)\n", "print una_tupla[1:3]\n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "<type 'tuple'>\n", "(1.2, (1j, 'Meli'))\n" ] } ], "prompt_number": 42 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**LA DIFERENCIA** es que las **listas son mutables**. Es decir, es un objeto que puede cambiar: extenderse con otra secuencia, agregar o quitar elementos, cambiar un elemento o una porci\u00f3n por otra, reordenarse *in place*, etc. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "mezcolanza.append(una_tupla)\n", "print mezcolanza" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[1.2, 'Jairo', 12000000.0, \"O'Higgings\", 'Nadia', ('Mart\\xc3\\xadn', 1.2, (1j, 'Meli'))]\n" ] } ], "prompt_number": 43 }, { "cell_type": "code", "collapsed": false, "input": [ "nombres.sort()\n", "print nombres" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['Daniel', 'Meli', 'Nadia']\n" ] } ], "prompt_number": 44 }, { "cell_type": "code", "collapsed": false, "input": [ "mezcolanza[-1] = \"otra cosa\"" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 45 }, { "cell_type": "code", "collapsed": false, "input": [ "print mezcolanza" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[1.2, 'Jairo', 12000000.0, \"O'Higgings\", 'Nadia', 'otra cosa']\n" ] } ], "prompt_number": 46 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las **tuplas** son mucho m\u00e1s eficientes (y seguras) si s\u00f3lo vamos a **leer** elementos (como una memoria ROM). Pero muchas cosas son comunes. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "l = [1, 3, 4, 1]\n", "t = (1, 3, 1, 4)\n", "l.count(1) == t.count(1)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 47, "text": [ "True" ] } ], "prompt_number": 47 }, { "cell_type": "code", "collapsed": false, "input": [ "t[1] = \"osooooo\"" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m<ipython-input-48-aee0fef3e8f2>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mt\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m\"osooooo\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "prompt_number": 48 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Como toda secuencia, las listas y tuplas se pueden *desempacar*" ] }, { "cell_type": "code", "collapsed": false, "input": [ "nombre, nota = (\"Juan\", 10)\n", "print nota" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "10\n" ] } ], "prompt_number": 50 }, { "cell_type": "code", "collapsed": false, "input": [ "a, b = 1, 2.0\n", "a, b = b, a\n", "print a" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2.0\n" ] } ], "prompt_number": 51 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Como con los n\u00fameros, se pueden convertir las secuencias de un tipo de dato a otro. Por ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = (1, 3, 4)\n", "b = list(a)\n", "print b, type(b)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[1, 3, 4] <type 'list'>\n" ] } ], "prompt_number": 52 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Una funci\u00f3n *builtin* muy \u00fatil es `range`" ] }, { "cell_type": "code", "collapsed": false, "input": [ "help(range)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Help on built-in function range in module __builtin__:\n", "\n", "range(...)\n", " range([start,] stop[, step]) -> list of integers\n", " \n", " Return a list containing an arithmetic progression of integers.\n", " range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.\n", " When step is given, it specifies the increment (or decrement).\n", " For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!\n", " These are exactly the valid indices for a list of 4 elements.\n", "\n" ] } ], "prompt_number": 54 }, { "cell_type": "code", "collapsed": false, "input": [ "range(6)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 55, "text": [ "[0, 1, 2, 3, 4, 5]" ] } ], "prompt_number": 55 }, { "cell_type": "code", "collapsed": false, "input": [ "range(-10, 10)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 56, "text": [ "[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" ] } ], "prompt_number": 56 }, { "cell_type": "code", "collapsed": false, "input": [ "range(0, 25, 5)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 57, "text": [ "[0, 5, 10, 15, 20]" ] } ], "prompt_number": 57 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tambi\u00e9n hay una funci\u00f3n est\u00e1ndar que da la sumatoria" ] }, { "cell_type": "code", "collapsed": false, "input": [ "help(sum)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Help on built-in function sum in module __builtin__:\n", "\n", "sum(...)\n", " sum(sequence[, start]) -> value\n", " \n", " Returns the sum of a sequence of numbers (NOT strings) plus the value\n", " of parameter 'start' (which defaults to 0). When the sequence is\n", " empty, returns start.\n", "\n" ] } ], "prompt_number": 58 }, { "cell_type": "code", "collapsed": false, "input": [ "sum([1, 5, 5, 10])" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 59, "text": [ "21" ] } ], "prompt_number": 59 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En toda secuencia tenemos el m\u00e9todo index, que devuelve la posici\u00f3n en la que se encuentra un elemento" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = [1, 'hola', []]\n", "print a.index('hola')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1\n" ] } ], "prompt_number": 74 }, { "cell_type": "markdown", "metadata": {}, "source": [ "y como las listas son *mutables* tambi\u00e9n se pueden reordenar *inline* (no se devuelve un valor, se cambia sobre la misma variable)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a.reverse()\n", "print a" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[[], 'hola', 1]\n" ] } ], "prompt_number": 75 }, { "cell_type": "markdown", "metadata": {}, "source": [ "La forma alternativa es usando una funci\u00f3n, que devuelve un valor" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = list(reversed(a))\n", "print a" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[[], 'hola', 1]\n" ] } ], "prompt_number": 77 }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Nota*: se fuerza la conversi\u00f3n de tipo con `list()` porque reversed no devuelve estrictamente una lista. Ya veremos m\u00e1s sobre esto.\n", "\n", "Una funci\u00f3n \u00fatil es `zip()`, que agrupa elementos de distintas secuencias" ] }, { "cell_type": "code", "collapsed": false, "input": [ "nombres = ['Juan', 'Jos\u00e9', 'Cismondi']\n", "pasiones = ['cerveza', 'visitar phasety', 'lechuga']\n", "zip(nombres, pasiones)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 77, "text": [ "[('Juan', 'cerveza'),\n", " ('Jos\\xc3\\xa9', 'visitar phasety'),\n", " ('Cismondi', 'lechuga')]" ] } ], "prompt_number": 77 }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Ejercicios\n", "\n", "- Resuelva la siguiente operaci\u00f3n $$\\frac{(\\sum_{k=0}^{100}k)^3}{2}$$\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Un poco de control de flujos\n", "\n", "#### if/elif/else\n", "\n", "En todo lenguaje necesitamos controlar el flujo de una ejecuci\u00f3n segun una condici\u00f3n Verdadero/Falso (booleana). *Si (condicion) es verdadero hac\u00e9 (bloque A); Sino hac\u00e9 (Bloque B)*. En pseudo c\u00f3digo:\n", "\n", " Si (condicion):\n", " bloque A\n", " sino:\n", " bloque B\n", "\n", "y en Python es muy parecido! \n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "edad = 17\n", "if edad < 18:\n", " print \"Usted es menor de edad. Raje de ac\u00e1, pendejo\"\n", "else:\n", " print \"Bienvenido, jovato\"\n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Usted es menor de edad. Raje de ac\u00e1, pendejo\n" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los operadores l\u00f3gicos en Python son muy explicitos. \n", " \n", " A == B \n", " A > B \n", " A < B\n", " A => B\n", " A =< B\n", " A != B\n", " A in B\n", "y a todos los podemos combinar con `not`, que niega la condici\u00f3n" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos tener multiples condiciones. Se ejecutar\u00e1 el primer bloque cuya condici\u00f3n sea verdadera, o en su defecto el bloque `else`. Esto es equivalente a la sentencia `switch` de otros lenguajes " ] }, { "cell_type": "code", "collapsed": false, "input": [ "if edad < 12:\n", " print \"Feliz dia del ni\u00f1o\"\n", "elif 13 < edad < 18:\n", " print \"Qu\u00e9 problema los granitos, no?\"\n", "elif edad in range(19, 60):\n", " print \"No ser\u00e9 feliz pero tengo marido\"\n", "else:\n", " print \"Y eso es todo amigos!\"" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Qu\u00e9 problema los granitos, no?\n" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En un `if`, la conversi\u00f3n a tipo *boolean* es impl\u00edcita. El tipo `None` (vaci\u00f3), el `0`, una secuencia (lista, tupla, string) (o conjunto o diccionario, que ya veremos) vac\u00eda siempre evalua a ``False``. Cualquier otro objeto evalua a ``True``." ] }, { "cell_type": "code", "collapsed": false, "input": [ "if 5 - 5: \n", " a = \"No es cero\"\n", "else: \n", " a = \"Dio cero\"\n", "print a" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Dio cero\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para hacer asignaciones condicionales se puede usar la *estructura ternaria* del `if`: `A si (condicion) sino B`" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = \"No es cero\" if (5-5) else \"dio cero\"\n", "print a" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "dio cero\n" ] } ], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### For\n", "\n", "Otro control es *iterar* sobre una secuencia (o *\"iterador\"*). Obtener cada elemento para hacer algo. En Python se logra con la sentencia `for`\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sumatoria = 0\n", "for elemento in [1, 2, 3]:\n", " sumatoria = sumatoria + elemento\n", "print sumatoria" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "6\n" ] } ], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notar que no iteramos sobre el \u00edndice de cada elemento, sino sobre los elementos mismos. \u00a1Basta de `i`, `j` y esas variables innecesarias! . Si por alguna razon son necesarias, tenemos la funci\u00f3n `enumerate`\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for posicion, valor in enumerate([4, 3, 19]):\n", " print \"El valor de la posicion %s es %d\" % (posicion, valor) " ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "El valor de la posicion 0 es 4\n", "El valor de la posicion 1 es 3\n", "El valor de la posicion 2 es 19\n" ] } ], "prompt_number": 78 }, { "cell_type": "markdown", "metadata": {}, "source": [ "El bloque `for` se corre hasta el final del *iterador* o hasta encontrar un sentencia `break`" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sumatoria = 0\n", "for elemento in range(1000):\n", " if elemento > 100:\n", " break\n", " sumatoria = sumatoria + elemento\n", "print sumatoria, elemento" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "5050 101\n" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tambi\u00e9n podemos usar `continue` para omitir la ejecuci\u00f3n de \"una iteraci\u00f3n\"" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sumatoria = 0\n", "for elemento in range(20):\n", " if elemento % 2:\n", " continue\n", " print elemento\n", " sumatoria = sumatoria + elemento\n", "print \"sumatoria pares:\", sumatoria" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "2\n", "4\n", "6\n", "8\n", "10\n", "12\n", "14\n", "16\n", "18\n", "sumatoria pares: 90\n" ] } ], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Muchas veces queremos iterar una lista para obtener otra, con sus elementos modificados. Por ejemplo, obtener una lista con los cuadrados de los primeros 10 enteros." ] }, { "cell_type": "code", "collapsed": false, "input": [ "cuadrados = []\n", "for i in range(10):\n", " cuadrados.append(i**2)\n", "print cuadrados" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Una forma compacta y elegante (\u00a1pyth\u00f3nica!) de escribir esta estructura muy frecuente son las **listas por comprehensi\u00f3n**:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "[i**2 for i in range(10)]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 21, "text": [ "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" ] } ], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se lee: \"Obtener el cuadrado de cada elemento i de la secuencia (rango 0 a 9)\". Pero adem\u00e1s podemos filtrar: usar solo los elementos que cumplen una condici\u00f3n. Por ejemplo, obtener la sumatoria de los cubos de los numeros impares menores a 10. $$\\sum_{a=0}^{9}a^3 \\mid a\\ impar $$" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sum([a**3 for a in range(10) if a % 2 == 1])" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 22, "text": [ "1225" ] } ], "prompt_number": 22 }, { "cell_type": "markdown", "metadata": {}, "source": [ "La misma sintaxis funciona sin tener que hacer listas: se crean *generadores*, que son tipos de datos iterables pero no indizables (es el mismo tipo de objeto que devuelve `reversed`, que ya vimos). Si es para *recorrer* todos los elementos de corrido son mucho m\u00e1s eficientes." ] }, { "cell_type": "code", "collapsed": false, "input": [ "(a**3 for a in range(10) if a % 2 == 1)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 25, "text": [ "<generator object <genexpr> at 0x3420910>" ] } ], "prompt_number": 25 }, { "cell_type": "code", "collapsed": false, "input": [ "sum(a**3 for a in range(10) if a % 2 == 1)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 26, "text": [ "1225" ] } ], "prompt_number": 26 }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### While\n", "\n", "Otro tipo de sentencia de control es *while*: iterar mientras se cumpla una condici\u00f3n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = 0\n", "while a < 10:\n", " print a\n", " a += 1" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "prompt_number": 74 }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Ejercicios\n", "\n", "\n", "- Encuentre el m\u00ednimo de $$f(x) = (x-4)^2-3 \\mid x \\in [-100, 100)$$ \n", "- Encuentre el promedio de los n\u00fameros reales de la cadena `\"3,4 1,2 -6 0 9,7\"`. Podes usar el m\u00e9todo `split()` para separa la cadena por espacios en blanco" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 33 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### M\u00e1s estructuras: diccionarios y conjuntos\n", "\n", "La diccionarios son otro tipo de estructuras de alto nivel que ya vienen incorporados. A diferencia de las secuencias, los valores **no est\u00e1n en una posici\u00f3n** sino bajo **una clave**: son asociaciones `clave:valor`\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "camisetas = {'Ori\u00f3n': 1, 'Martinez': 7, 'Riquelme': 10, 'Gait\u00e1n': 'Jugador n\u00ba 12'} " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 34 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Accedemos al valor a traves de un clave" ] }, { "cell_type": "code", "collapsed": false, "input": [ "camisetas['Riquelme']" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 36, "text": [ "10" ] } ], "prompt_number": 36 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las claves pueden ser cualquier objeto inmutable (cadenas, numeros, tuplas) y los valores pueden ser cualquier tipo de objeto. Las claves no se pueden repetir pero los valores s\u00ed.\n", "\n", "**Importante**: los diccionarios **no tienen un orden definido**. Si por alguna raz\u00f3n necesitamos un orden, debemos obtener las claves, ordenarlas e iterar por esa secuencia de claves ordenadas.\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sorted(camisetas.keys())" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 37, "text": [ "['Gait\\xc3\\xa1n', 'Martinez', 'Ori\\xc3\\xb3n', 'Riquelme']" ] } ], "prompt_number": 37 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los diccionarios **son mutables**. Es decir, podemos cambiar el valor de una clave, agregar o quitar. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "camisetas['Blandi'] = 9\n", "print camisetas" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'Ori\\xc3\\xb3n': 1, 'Martinez': 7, 'Blandi': 9, 'Riquelme': 10, 'Gait\\xc3\\xa1n': 'Jugador n\\xc2\\xba 12'}\n" ] } ], "prompt_number": 56 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hay muchos m\u00e9todos \u00fatiles" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for jugador, camiseta in camisetas.items():\n", " if jugador == 'Gait\u00e1n':\n", " continue \n", " print \"%s lleva la %d\" % (jugador, camiseta)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Ori\u00f3n lleva la 1\n", "Martinez lleva la 7\n", "Blandi lleva la 9\n", "Riquelme lleva la 10\n" ] } ], "prompt_number": 58 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se puede crear un diccionario a partir de tuplas `(clave, valor)` con el construcutor `dict()`" ] }, { "cell_type": "code", "collapsed": false, "input": [ "dict([('Yo', 'gaitan@phasety.com'), ('Meli', 'mgomez@phasety.com'), ('Cismondi', 'cismondi@phasety.com')])" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 73, "text": [ "{'Cismondi': 'cismondi@phasety.com',\n", " 'Meli': 'mgomez@phasety.com',\n", " 'Yo': 'gaitan@phasety.com'}" ] } ], "prompt_number": 73 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Que es muy \u00fatil usar con la funci\u00f3n `zip()` que ya vimos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los diccionarios son super \u00fatiles, recuerdenlos!\n", "\n", "#### Conjuntos\n", "\n", "Los conjuntos (`set()`) son grupos de claves \u00fanicas e inmutables." ] }, { "cell_type": "code", "collapsed": false, "input": [ "mamiferos = {'perro', 'gato', 'leon'}\n", "domesticos = {'perro', 'gato', 'gallina'}\n", "aves = {'gallina', 'halc\u00f3n', 'colibr\u00ed'}" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 76 }, { "cell_type": "code", "collapsed": false, "input": [ "mamiferos.intersection(domesticos)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 70, "text": [ "{'gato', 'perro'}" ] } ], "prompt_number": 70 }, { "cell_type": "code", "collapsed": false, "input": [ "mamiferos.union(domesticos)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 71, "text": [ "{'gallina', 'gato', 'leon', 'perro'}" ] } ], "prompt_number": 71 }, { "cell_type": "code", "collapsed": false, "input": [ "aves.difference(domesticos)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 72, "text": [ "{'colibr\\xc3\\xad', 'halc\\xc3\\xb3n'}" ] } ], "prompt_number": 72 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }