Sunteți pe pagina 1din 45

Introduccin a Python para ingenieros

Estos breves apuntes son el material de apoyo de un curso de 10 horas sobre el lenguaje de programacin Python aplicado al mbito de la Ingeniera. Este curso est dirigido a alumnos de ltimos cursos de carrera o de postgrado que ya cuentan con alguna experiencia en programacin, bien con C o Fortran, y con conocimientos de Matlab. Este no es ningn caso un curso completo de Python. Es demasiado corto y parcial como para servir de referencia. El objetivo es el de poder reciclar los conocimientos de Clculo Numrico y programacin de la manera ms eficiente posible para poder escribir programas y libreras en Python. Es, por consiguiente, un curso de mnimos. Introduccin Qu es Python? Documentacin El entorno de desarrollo en Matlab SAGE Python 3 Primeros pasos con Python Python es un lenguaje interpretado Python es un lenguaje interactivo Python es un lenguaje dinmico Python es un lenguaje orientado a objetos En Python todo est modularizado Python incluye bateras, pero no cargador Python es tambin una calculadora Control de flujo Condicionales o sentencias if Intermezzo. Listas. Iteradores Definicin de funciones, encapsulamiento y mdulos Duck Typing Docstrings Mdulos Intermezzo. Tuples Funciones que retornan varias variables Funciones con argumentos por omisin Empaquetar y desempaquetar argumentos Intermezzo. Diccionarios. De vuelta al empaquetado y desempaquetado de argumentos Funciones lambda Programacin funcional Tipos, o cmo programar en Python La clase string Intermezzo. Archivos y la clase file La clase list Una breve introduccin a la programacin orientada a objetos Un pequeo viaje por la biblioteca estndar. El mdulo os

El mdulo sys El mdulo shutil El mdulo datetime Numpy y la clase array Instalar numpy Importar numpy La clase array Indexacin n-dimensionalidad Matlab La clase matrix Scipy. Haciendo Python mejor que Matlab Matplotlib. Grficos en 2D. Clculo simblico con Sympy. Soluciones a los ejercicios propuestos Ejercicio 1 Ejercicio 2 Mdulo finance Mdulo turbulence

Introduccin
Estara bien que por una vez leyerais la introduccin, aunque todos sabemos que nadie se lee nunca la introduccin de nada.

Qu es Python?
Python es un lenguaje de programacin interpretado e interactivo de propsito general. Es, hasta cierto punto, comparable con otros lenguajes de programacin de dominio especfico que podemos encontrar dentro del mbito de la Ingeniera como Matlab, Octave, R, SPSS o IDL. Se trata tambin de un lenguaje de programacin relativamente moderno y en constante, aunque moderada, renovacin. Fue creado por Guido van Rossum en el ao 1991 tomando prestadas muchas de las buenas ideas presentes en los lenguajes de programacin que conoca. A diferencia de lo que viene siendo habitual, en vez de reinventar cada idea simplemente las incorpor de manera que tuvieran sentido. Aunque la mente de un holands suele ser un sitio bastante complicado y retorcido consigui crear un lenguaje sencillo, intuitivo y fcil de aprender. Difcilmente se es ms productivo con cualquier otro lenguaje de cuanto se es programando en Python. De hecho se suele decir: la vida es corta, por eso programo en Python. Quizs el nico lenguaje comparable a Python en ese sentido es Ruby, que curiosamente naci de la mente de un japons; tambin un sitio habitualmente complicado y retorcido. Python gozaba de cierta popularidad dentro del mundo UNIX porque se le consideraba una alternativa razonable a Perl, el que era por aquel entonces el lenguaje de scripting para programacin de sistemas por antonomasia. La explosin de Python lleg entre los aos 2003 y 2007 con el auge de las aplicaciones web y posteriormente con la nube. Es uno de los cuatro lenguajes oficiales de Google y toda la infraestructura de Youtube est programada en Python. Permite a los desarrolladores de arquitecturas de servicios utilizar el mismo lenguaje para la aplicacin (para lo que tambin se ha venido utilzando PHP, como en el caso de Facebook), para el middleware y para la gestin de los equipos. Si bien Java es el lenguaje de las aburridas consultoras de sistemas y de las mastodnticas multinacionales, Python es el lenguaje de las startups de Silicon Valley. Ms o menos mientras ganaba en popularidad entre los futuros empleados de Google, en algunos sectores del clculo cientfico se lo veia como una ms que prometedora alternativa a Matlab. Matlab es en el fondo un lenguaje de programacin mediocre que sirve para juntar funciones realmente tiles. Python deba recorrer el sentido contrario: es un lenguaje de programacin singularmente atractivo para el que, hace unos aos, no haba un contexto cientfico. Ni siquiera se dise pensando en el Clculo Numrico. Jim Hugunin puso la primera piedra del castillo, Numeric. No era ms que una clase para poder tratar arrays n-dimensionales en Python y algunas rutinas numricas pero tena serios problemas de velocidad en comparacin con Matlab. Tambin haba ciertos problemas de fragmentacin, cada centro de investigacin desarrollaba sus propias bibliotecas de clculo y las comparta, pero no haba ningn lugar donde poder poner las cosas en comn. El punto de no retorno lleg el ao 2007 con numpy y scipy. Finalmente Python contaba con los bloques bsicos para hacer Clculo Numrico, todos los usuarios usaban el mismo y saban dnde compartir sus desarrollos. En enero de 2012, momento en el que escribo estas lneas, Python cuenta con una coleccin de recursos para Ciencia equivalente a la de Matlab, incluso superior en campos como la visualizacin o el clculo simblico. Y la gran mayora de estos recursos son libres y gratuitos, sin problemas de royalties o de abogados que intenten defender la propiedad intelectual de sus clientes.

En resumen: Python es el futuro.

Documentacin
Uno de los motivos del xito de Python es la gran cantidad de documentacin de calidad que existe sobre el lenguaje y sus bibliotecas, empezando por la documentacin oficial que encontraremos tanto en la pgina web http://python.org como en los instaladores para cualquier sistema operativo. Hay dos documentos que es importante retener en la memoria. El primero es el tutorial, de poco ms de 100 pginas, que introduce la mayora de los elementos esenciales del lenguaje. Obviamente en tan pocas pginas no es posible entrar en profundidad con todos los detalles y matices del lenguaje pero es una gua casi imprescindible si uno quiere programar en Python y no sabe cmo. El segundo documento es mucho ms extenso: la documentacin de la librera estndar. Python es, como veremos, un lenguaje modular. Algunos de estos mdulos se consideran parte de cualquier distribucin al igual que en C tenemos la funcin malloc o en Fortran la funcin allocate. Todo lo que se documenta como parte de la librera estndar est disponible en cualquier instalacin de Python independientemente del sistema operativo y de la arquitectura de procesador.

El entorno de desarrollo en Matlab


Python es un lenguaje de programacin con todas las letras tal como lo es C, Fortran o Java. Al igual que estos lenguajes y a diferencia de Matlab no existe un entorno de desarrollo oficial. Aunque en cada instalacin de Python viene un pequeo editor llamado idle no es ni mucho menos el ms recomendable. En mi caso tengo dos elecciones personales: Emacs y Eclipse. Lo ms normal es que si no os habis peleado largas horas de vuestra vida con un Linux ni siquiera os suene la palabra emacs pero s es probable que os suene eclipse. Eclipse es un entorno de desarrollo originalmente pensado para Java pero que fue tornandos en agnstico respecto al lenguaje de programacin. Existe una extensin bastante popular llamada pydev que convierte a Eclipse en un entorno de desarrollo completo para Python, con gestor de proyectos y debugger. Es una eleccin muy interesante en el momento en el que uno se plantea realizar un proyecto realmente grande con Python. Pero para manejar los pequeos scripts que escribiremos en este curso cualquier cosa vale, incluso idle. Hay centenares de entornos de desarrollo para Python, incluso algunos estn pensados para parecerse lo mximo posible al entorno de Matlab como spyder. Os recomiendo que visitis la wiki del proyecto Python donde encontraris una lista actualizada de todos los entornos de desarrollo para Python, tanto libres como comerciales.

SAGE
Sage es un notebook parecido al que encontramos en entornos como Maple o Mathematica basado en Python. Fue creado por William Stein para cubrir sus necesidades como docente e investigador en Matemticas. Uno podra considerar SAGE como un proyecto paralelo y casi independiente de Python pero nos permite utilizar Python en la nube a travs del navegador. De este modo no utilizaremos ninguna funcionalidad especfica de SAGE sino que accederemos al intrprete de Python a travs del notebook de forma interactiva y en la nube. Utilizar SAGE como soporte de este curso para ver de manera interactiva el resultado de bloques de cdigo escrito en Python, pero esto no significa en absoluto que la manera ptima de escribir un programa en Python sea con SAGE. Se trata de una herramienta puramente docente. El objetivo es dejar un notebook pblico en http://picachu.dmt.upm.es para que quien lo desee

pueda crear, modificar y compartir su trabajo en Python con todos los participantes del grupo.

Python 3
Python est en la actualidad migrando de versin. Aunque la mayora del cdigo escrito en Python sigue las especificaciones de la versin 2 hace ya un tiempo que uno puede descargar y utilizar la versin 3. Algunos cambios importantes entre versiones son fciles de migrar, como por ejemplo el comando print que pasa a ser una funcin. Incluso podemos pedir al intrprete de Python 2 que nos avise si alguna parte de nuestro cdigo tendr problemas con Python 3. Este hecho descubre la pregunta de cundo se har necesario empezar a escribir cdigo para Python 3. La respuesta es que no depende de nosotros. Cuando uno escribe en Python utiliza muchas libreras adicionales que no siempre estn disponibles an para Python 3. En el momento en el que todas las dependencias de nuestro trabajo ya ejecuten sobre Python 3 probablemente slo tengamos que cambiar de un intrprete a otro.

Primeros pasos con Python


Python es un lenguaje interpretado
Cuando compilamos un programa escrito en C o en Fortran generamos un ejecutable. Para hacer funcionar ese ejecutable nos basta con muy poca cosa; en el caso de un hola, mundo basta con simplemente ejecutarlo. El sistema operativo lo considera ejecutable y simplemente cumple sus ordenes. Esto no sucede as en los lenguajes interpretados. El cdigo en Python nunca llega a traducirse a algo que el sistema operativo pueda entender. En Python el programa termina convertido en un ensamblador propio que una mquina virtual es capaz de entender y ejecutar. La consecuencia principal de este mtodo es que es imprescindible contar con un intrprete de Python instalado en el ordenador para poder ejecutar cdigo en Python. Esta no es hoy en da una condicin demasiado severa. El nico sistema operativo mayoritario que no cuenta con un intrprete de Python instalado por omisin es Windows. Linux, Mac OSX, Solaris y AIX entre otros cuentan con uno, aunque algunas veces compensa instalar una versin ms actualizada que la que encontraremos en la distribucin del sistema operativo. En el caso especial de Windows bastar con descargarse un instalador, darle doble clic y decir que s a todo. Cuando ejecutamos cdigo en Python lo lanzamos a un intrprete que es capaz de entender este lenguaje. A diferencia de los lenguajes estticos como C o Fortran en el que un compilador convierte el cdigo de programa en un ejecutable que el sistema operativo es capaz de entender.

Python es un lenguaje interactivo


Python dispone de una consola interactiva con la que jugaremos un poco antes de escribir algn que otro programa.

Consola de Python en la ventana de IDLE en Linux La manera de acceder a esta consola difiere en funcin del sistema operativo. En los UNIX y derivados bastar con abrir una consola de sistema y teclear en ella python. En Windows bastar con abrir el programa correspondiente que seguro que se llamar Python shell o algo parecido.

Una vez estemos delante del intrprete de Python podemos empezar a jugar. En este respecto se trata de un lenguaje de programacin parecido a Matlab, de modo que podemos probar a hacer una suma sin problemas.
>>> 2+2 4

Como seguramente intentaris hacer algo ms complicado con nmeros, una gran parte de las funciones matemticas bsicas estn en el mdulo math, pero ya llegaremos a ello.

Python es un lenguaje dinmico


En Python no hay que declarar ninguna variable. Cada variable toma el tipo que tenga en cada caso lo que est en el lado derecho del operador asignacin =. Esto es cierto tanto la primera vez que se utiliza una variable como cuando se le asigna un valor a una variable ya existente. Esto es sencillo en el caso de Python porque es un lenguaje interpretado: la mayora de las asignaciones resuelven el tipo en tiempo de ejecucin, no en tiempo de compilacin del mismo modo que sucede en Matlab o Octave. Si volvemos al intrprete:
>>> a = 2.3 >>> b = 3.2 >>> print a*b 7.36 >>> a = 2 >>> print type(a) <type 'int'> >>> print a*b 6.4 >>> a = 'hola' >>> print type(a) <type 'str'> >>> print a*b Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't multiply sequence by non-int of type 'float'

Creo que no hace falta dedicarle un captulo a lo que hace la sentencia print. Obviamete, cuando intentamos multiplicar una secuencia de caracteres por un nmero en coma flotante obtenemos un error claramente identificado como error de tipo. Aunque Python est lleno de sorpresas. Si vuestra intucin os dice que una operacin puede ser posible a lo mejor est implementada. Qizs parte del xito de Python se debe a que la gente que lo ha estado creando durante las dos ltimas dcadas es gente particularmente lista. Por ejemplo... Qu sucede si multiplicamos una palabra por 2?
>>> a = 'hola' >>> print 2*a holahola

Pues que tenemos dos veces 'hola'. Entonces, si tomamos la definicin de multiplicacin como una secuencia de sumas...
>>> print a+a holahola

Python est lleno de detalles de estos as que algunas veces es bueno dejarse llevar por la intuicin.

Python es un lenguaje orientado a objetos


El las carreras de informtica cubrir los conceptos fundamentales de la orientacin a objetos requiere una asignatura entera. De todos los paraidgmas de programacin es el ms exitoso que se conoce. Incluso Fortran, a partir del estndar Fortran 2003, soporta la programacin orientada a objetos. Matlab era tambin otro lenguaje que histricamente haba ignorado la orientacin a objetos pero por soportarlo tambin, a su manera. La primera implementacin de la orientacin a objetos de Matlab era tan deficiente que qued en el olvido. A la segunda consiguieron un resultado razonable gracias a casi copiar el planteamiento de Python. Sin embargo las metodologas de programacin es una temtica larga y miserablemente olvidada dentro de los planes de estudios de las carreras de Ingeniera as que no nos queda ms remedio que dejar un enorme hueco en este curso. Me centrar en comentar lo ms bsico y fundamental de lo que es un objeto: los atributos y los mtodos. De este modo veremos una clase como una manera de agrupar variables, los atributos, y funciones que operan sobre estas variables, los mtodos. Es imposible hablar de Python y no hablar sobre la orientacin a objetos porque en Python prcticamente todo es un objeto. Por ejemplo un nmero complejo es un ejemplo especialmente simple.
>>> c = 2+3j >>> print c,type(c) (2+3j) <type 'complex'> >>> c.real 2.0 >>> c.imag 3.0 >>> print c*(1j)+3 2j

Python dispone de una constante especial, j que es la unidad imaginaria. Como en Matlab y Octave es recomendable utilizarlo como sufijo de un nmero tal como se hace en el ejemplo. Cualquier nmero imaginario tiene dos atributos, su parte real y su parte imaginaria. Si bien la suma de un nmero complejo es una operacin trivial (es la suma de sus partes real e imaginaria respectivamente) la multiplicacin no lo es. Esto significa que la clase complex tiene la operacin de producto definida internamente. Podemos ver todos los atributos, mtodos y operaciones disponibles para una clase utilizando la funcin help.
>>> help(c) Help on complex object: class complex(object) | complex(real[, imag]) -> complex number | | Create a complex number from a real part and an optional imaginary part. | This is equivalent to (real + imag*1j) where imag defaults to 0. | | Methods defined here: | | __abs__(...) | x.__abs__() <==> abs(x) | | __add__(...) | x.__add__(y) <==> x+y | | __coerce__(...) | x.__coerce__(y) <==> coerce(x, y)

(...)

Esta funcin que aparece como __abs__() es en realidad la funcin valor absoluto, de modo que estas dos operaciones:
>>> abs(c) 3.605551275463989 >>> c.__abs__() 3.605551275463989

Son equivalentes a todos los efectos.

En Python todo est modularizado


Esta s es una diferencia esencial entre Matlab/Octave y Python. En estos lenguajes cualquier funcin de la biblioteca est accesible al intrprete. Esto hace que, a medida que el nmero de funciones crece, crezca tambin la probabilidad de conflictos. En Python todas las bibliotecas, incluso la biblioteca estndar, estn modularizadas. Por ejemplo, si queremos calcular el seno de tendremos que importar antes el mdulo que contiene tanto la funcin seno como el valor de
>>> import math >>> math.sin(math.pi) 1.2246063538223773e-16

Dos puntos a tener en cuenta: Cada mdulo es en s un objeto. En este caso, despus de importar math, hemos llegado a la constante como un atributo del mdulo y a la funcin sin como un mtodo. Prcticamente la totalidad de mdulos o scripts en Python importan algn mdulo. Podemos importar mdulos prcticamente en cualquier punto de la ejecucin pero por convencin se suelen importar al principio. Ahora podis pensar que para la funcin seno o para :math:pi, tener que arrastrar el nombre math puede ser algo tedioso; especialmente si no hay una intencin especial de agrupar las funciones de este mdulo. Si queremos importar slo sin y pi podemos hacerlo de la siguiente manera:
>>> from math import sin,pi >>> sin(pi) 1.2246063538223773e-16

Tambin podis pensar... Y si tengo que importar veinticinco funciones del mdulo math? Tengo que escribirlas todas en la llamada a import? Evidentemente no. Podemos utilizar un wildcard para importar todo el contenido del mdulo y ponerlo a disposicin del programa:
>>> from math import * >>> sin(pi) 1.2246063538223773e-16 >>> cos(pi) -1.0 >>> tan(pi) -1.2246063538223773e-16

Aunque esta manera de importar el contenido de los mdulos es bastante prctica porque evita olvidos no es la recomendada para produccin.

Python incluye bateras, pero no cargador


En la introduccin, porque siempre es mala idea no leer la introduccin, mencion que para programar en Python es una gran idea acostumbrarse a utilizar un interfaz de desarrollo integrada (IDE) como Eclipse; algo ms sofisticado que IDLE. Cuando se dice que Python incluye bateras se menciona el hecho que la biblioteca estndar es enorme comparada con otros lenguajes de programacin, que slo incluye funcionalidades bsicas. La biblioteca estndar de Python incluso viene con la posibilidad de generar interfaces grficas con ventanas en cualquier sistema operativo. Pero Python no es Matlab ni Visual Basic en el sentido que uno debe decidir cmo programar, gestionar y ejecutar sus scripts o mdulos. Es ms, debido a que Python tiene la gran particularidad de que el significado de un programa depende de cmo se ha escrito es prcticamente imprescindible utilizar una herramienta especfica. A modo de ejemplo ejecutaremos un Hola, mundo! portable, es decir, podemos seguir exactamente el mismo mtodo en cualquier sistema operativo. Una vez abrimos IDLE, en el men archivo seleccionamos nueva ventana, lo que abrir un editor en el que podemos escribir el programa. Entonces en esta nueva ventana escribimos lo siguiente:
if __name__ == '__main__': print 'Hola, Mundo!'

Editor para Python de IDLE en Linux Justo despus de escribir los dos puntos finales de la primera lnea veremos que el editor nos sita automticamente a cuatro caracteres del margen izquierdo. El motivo puede parecer puramente esttico pero leed otra vez el programa. Hay un condicional, un if, y ninguna sentencia que termine el bloque. No hay ningn end ni corchetes que encapsulen las sentencias ejecutables. Lo que determina la prioridad del bloque de cdigo es precisamente la separacin respecto al margen izquierdo. Todo lo que est indentado despus de los dos puntos es parte del bloque if. La necesidad de utilizar una herramienta especfica radica aumentar la facilidad en la que se maneja la indentacin del cdigo. En IDLE, por ejemplo, para cambiarla basta con apretar el tabulador o backspace al principio de cada lnea para cambiarla. Pero si comparamos IDLE con el IDE de Matlab seguimos echando de menos un montn de piezas: la ayuda integrada, algo que nos permita navegar entre los objetos, un debugger, un profiler... Parte de la gracia de cualquier lenguaje de programacin, y es tambin el caso de C o Fortran, es llegar a un entorno de desarrollo con el que nos sintamos cmodos. La comodidad es una sensacin muy personal y para conseguirla puedo ayudaros muy poco.

Ahora, en la ventana del editor, seleccionad run y luego run module o pulsad F5. En el intrprete aparecer un Hola, Mundo!. La parte inicial, el if __name__ == '__main__': es una convencin de Python que viene a decir que lo que hay a partir de esta lnea tiene que ejecutarse si se ejecuta el archivo .py. Lo utilizaremos otras veces y veremos de su importancia ms adelante.

Python es tambin una calculadora


El intrprete cuenta con todas las operaciones aritmticas usuales: suma, resta, multiplicacin, divisin... Slo hay que hacer un par de puntualizaciones al comportamiento del lenguaje. El smbolo correspondiente a la potencia es el doble asterisco, **, como en Fortran.
>>> 2**10 1024

Otra diferencia es el operador modulo que da el residuo de la divisin entrera entre dos nmeros. En Matlab, Octave y Fortran este operador es una funcin, a diferencia de C en el que se trata de un operador. Python comparte la convencin con C al respecto
>>> 5%2 1

La divisin tiene un comportamiento un poco particular en Python 2 y depende del tipo de cada operador. Si tanto el numerador como el denominador son nmeros enteros, el operador / corresponde a la divisin entera y no a la divisin en coma flotante. Sin embargo, si alguno de los dos operandos es un nmero en coma flotante el resultado tambin lo ser.
>>> 5/2 2 >>> 5.0/2 2.5

Sin embargo este comportamiento se corregir en Python 3 de manera que cualquier divisin ser la divisin en coma flotante. Podemos modificar el comportamiento de Python 2 utilizando el mdulo __future__ que introduce algunas de las modificaciones que recibir el lenguaje en el futuro
>>> from __future__ import division >>> 5/2 2.5

Por lo dems el comportamiento respecto a las operaciones aritmticas es el mismo e importando los mdulos math y cmath conseguiremos funcionalidades equivalentes a cualquier calculadora. Aunque an estamos muy lejos de algo parecido a Matlab y Octave.

Control de flujo
Este captulo no es ms que una introduccin sobre cmo hacer lo que se puede hacer con cualquier lenguaje de programacin en Python. El control de flujo es el nombre tcnico de las estructuras condicionales, los bucles y sus derivados mientras que el encapsulamiento es cmo se llama a la tcnica de tomar partes de nuestro cdigo y convertirlas en funciones. Quiero enfatizar que esta parte, en el fondo, no tiene nada que ver con Python. Si uno experimenta dificultades para seguir esta seccin: nuseas, mareos o desorientacin espacial; recomiendo encarecidamente tomar un curso de programacin de verdad ya sea en la Universidad o en Youtube. Ahora incluso los hay buenos.

Condicionales o sentencias if
El condicional ms sencillo posible es el siguiente:
>>> if True: print 'Verdadero' ... Verdadero

Dos cosas interesantes aqu. Hay una constante especial para determinar verdadero, True, del mismo modo que lo hay para falso con False. Aunque se cumple la regla que se considera como falso el 0 entero y como verdadero cualquier otro valor se enfatiza como buena prctica que cualquier condicional debe evaluar una constante lgica que puede tener como valor True o False. Otra peculiaridad es que no tenemos por qu pasar a la siguiente lnea si despus de la condicin y los dos puntos slo queremos escribir una lnea. De este modo estas dos sentencias son equivalentes a
>>> if True: ... print 'Verdadero' ... Verdadero

El intrprete, en cuanto se da cuenta que hemos escrito dos puntos, nos cambia el smbolo de entrada a tres puntos. Esto significa que est esperando nuestra decisin de si queremos introducir contenido en el bloque o queremos salir de l. Para complicar un poco ms el control de flujo pasaremos de trabajar con la consola a trabajar con scripts. Recordad que cualquier archivo con cdigo escrito en Python tendr la extensin .py. Por ejemplo:
from random import choice if __name__ == '__main__': guess = choice([True,False]) if guess: print 'Cara' else: print 'Cruz'

Vemos que la condicin lgica complementaria tambin requiere de un bloque de cdigo asociado despus de los dos puntos de rigor. Vemos tambin varias cosas nuevas e interesantes en este programa. Uno es el mdulo random que contiene multitud de funciones especficas para la generacin de nmeros o secuencias aleatorias de

cualquier tipo. En este caso hemos importado la funcin choice, que dada una lista (que an no sabis lo que es) escoge un elemento de la misma de manera aleatoria. De este modo, si ejecutis el script varias veces, algunas veces os saldr Cara y otras veces Cruz.
Python 2.7 (r27:82500, Aug 07 2010, 16:54:59) [GCC] on linux2 Type "copyright", "credits" or "license()" for more information. >>> ================================ RESTART ================================ >>> Cruz >>> ================================ RESTART ================================ >>> Cruz >>> ================================ RESTART ================================ >>> Cruz >>> ================================ RESTART ================================ >>> Cruz >>> ================================ RESTART ================================ >>> Cara

Aunque alguien avispado me podra decir que este programa se poda escribir de manera mucho ms eficiente ahorrndome el condicional
from random import choice if __name__ == '__main__': print choice(['Cara','Cruz'])

Obviamente podemos introducir condiciones adicionales a la estructura con elif y complicar un poco la estructura:
from random import choice if __name__ == '__main__': (pos,nil,neg) = (0,0,0) # Multiple assignment while pos<10 and nil<10 and neg<10: num = choice([-1,0,1]) if num == 0: nil += 1 elif num > 0: pos += 1 elif num < 0: neg += 1 else: print 'Something impossible just happened!' print 'Positive:',pos,'Zero:',nil,'Negative:',neg

Lo que estamos haciendo con este script es tomar tres variables, pos, nil y neg que utilizaremos como contadores. La funcin choice escoge entre tres valores y dependiendo de si su valor es negativo, positivo o cero incrementa el contador correspondiente. En este caso la condicin complementaria else no tiene ningna funcin porque las tres condiciones anteriores cubren todo el espacio de probabilidades pero lo he dejado ah por si alguien tiene un ordenador que con una lgica alternativa. Como an no hemos visto prcticamente nada de Python cualquier tontera nos parece novedosa. Hay muchas cosas interesantes en este pequeo ejemplo Una asignacin mltiple en la primera lnea

Un bucle con condicional while en el que hemos puesto una condicin lgica compuesta El operador incremento += presente en prcticamente todos los lenguajes de programacin excepto Matlab y Fortran. Ejercicio 1 La sucesin de Fibonacci tiene la siguiente definicin:

Escribir un programa que saque por pantalla los 20 primeros trminos de la sucesin de Fibonacci. Ejercicio 2 Aunque los bombos y las esferas de plstico no tienen porqu ser imparciales se prefieren a los ordenadores para las loteras y los bingos. Tambin es verdad que los generadores de nmeros pseudoaleatorios tampoco son perfectos. Escribir un programa que sortee la primitiva, cinco extracciones de un conjunto de 49 nmeros sin repeticin. Merece la pena echarle un vistazo a la ayuda del mdulo random.

Intermezzo. Listas.
Aunque esta seccin debera estar en el prximo captulo, el destinado a los distintos tipos que Python proporciona, es importante conocer lo bsico sobre las secuencias (la lista es un tipo de secuencia) para entender cmo funcionan los bucles. A diferencia de C o Fortran, en el que existen verdaderos bucles con el for de C o el do de Fortran, en Python (al igual que en Matlab) no existen los bucles como tal. Lo que tenemos son iteradores en el que asignamos a una variable el elemento siguiente de algo sobre lo que podamos iterar. La secuencia ms comn en Python es la lista, un tipo que sera algo entre una matriz y una celda en Matlab. El literal se introduce mediante corchetes
>>> a = [1,2,3,4] >>> print a [1, 2, 3, 4]

Una lista en Python es una lista de cosas, de modo que puede contener absolutamente cualquier valor independientemente de su tipo.
>>> a = [1,'hola',True] >>> print a [1, 'hola', True]

Las listas estn indexadas, como cualquier cosa en Python, con la numeracin a partir de cero:
>>> print a[0] 1

Una de las propiedades ms curiosas y tiles a la vez de la indexacin en Python es la posibilidad de utilizar ndices negativos para numerar una secuencia desde el final. El elemento correspondiente al ndice -1 ser el ltimo elemento de la secuencia
>>> print a[-1] True

Las listas son secuencias mutables, es decir que podemos cambiar cualqiera de sus elementos por asignacin
>>> a[-1] = False >>> print a [1, 'hola', True]

Si despus de estos comandos peds la documentacin de cualquier lista, en este caso con help(a) comprobaris que disponemos de un montn de mtodos para manipular tanto sus elementos como el orden de los mismos. Veremos ms sobre las listas en el siguiente captulo. De momento ya sabemos lo suficiente para entender el concepto de iterador.

Iteradores
Quizs la funcin ms bsica que genera una lista de valores es la funcin range:
>>> print range(5) [0, 1, 2, 3, 4]

Vemos que se trata de una lista de valores desde cero con incremento 1 de 5 elementos. Esta funcin nos permite generar un iterador tan bsico como nos es posible
>>> for i in range(5) ... print i, ... 0 1 2 3 4

Entenderemos perfectamente la diferencia entre un iterador y un bucle con el siguiente ejemplo


>>> for i in range(5) ... i = i**2 ... print i, 0 1 4 9 16

Vemos que aunque hemos modificado la variable i dentro del bloque correspondiente a una iteracin, al entrar en la siguiente iteracin, i se ha sobreescrito con el siguiente elemento de la secuencia. Es importante tener este comportamiento en cuenta porque implica que algunos algoritmos tal como estan publicados en C o en Fortran no pueden ser simplemente copiados en Python. Podemos controlar los bucles con las sentencias break y continue, por ejemplo
>>> for w in ['defenestrate','the','cat','now']: ... if w == 'cat': ... print 'No, I love cats!' ... break ... else: ... print w ... defenestrate the No, I love cats!

En el siguiente ejemplo representamos por pantalla slo los nmeros impares de la secuencia entre 0 y 9, aunque iteramos con la secuencia entera.
>>> for num in range(10): ... if num%2 == 0:

... continue ... else: ... print num, 1 3 5 7 9

Esta no es ni mucho menos la manera de tratar los bucles en Python. Los bucles en cualquier lenguaje interactivo son lentos comparados con otros lenguajes como C o Fortran, ms orientados a obtener un buen rendimiento. Python no es una excepcin de modo que debemos evitar iterar sobre secuencias muy largas innecesariamente. Por ejemplo, si queremos iterar sobre slo los valores impares de una secuencia de nmeros podemos filtrarla antes, de este modo nos aseguraremos que el iterador realiza slo los ciclos imprescindibles.
>>> from itertools import ifilter >>> for num in ifilter(lambda x: x%2, range(10)): ... print num, 1 3 5 7 9

Para entender el ejemplo anterior necesitamos saber qu son las funciones lambda. Llegaremos a ello poco despus de entender cmo Python reinterpreta el concepto de funcin. El mdulo itertools es uno de estos secretos escondidos de Python que uno siempre se arrepiente de no haber conocido antes. Alguna de las utilidades de este mdulo, al igual que algunos de los trucos que provienen de la programacin funcional, ahorran muchas lneas de cdigo y aceleran el resultado significativamente. Importante Uno de los problemas de obligar a formatear el cdigo de una determinada manera es el no poder dejar bloques vacos. Por ejemplo:
>>> while True: ... # Implement this later ^ IndentationError: expected an indented block

Vemos que, aunque hemos puesto el comentario precisamente donde debamos se queja que no es capaz de entender el bloque de cdigo. Esto es precisamente porque los comentarios no sirven para marcar un bloque de cdigo; son comentarios, no cdigo. Para dejar un bloque vaco contamos con la sentencia pass
>>> while True: ... pass # Implement this later

De este modo ya no generamos ningn error

Definicin de funciones, encapsulamiento y mdulos


Aunque Python es estrictamente un lenguaje orientado a objetos tiene todas las piezas necesarias para utilizar el paradigma procedimental, tambin llamado cdigo spaghetti con funciones para que quien lo lea no se atragante. Python, al igual que Matlab, no diferencia entre funciones y subrutinas pero al igual que fortran pasa siempre los argumentos por referencia. Esto significa que si cambiamos alguno de los argumentos de entrada lo estaremos cambiando de verdad, no una hipottica copia hecha en tiempo de ejecucin, as que cuidadn. La funcin ms sencilla que podemos definir es es la funcin vaca sin argumentos:
>>> def none(): ... pass

Es una funcin que no recibe ningn argumento, no hace nada y no devuelve ningn argumento de salida.

Duck Typing
Construyamos una funcin un poco ms complicada.
>>> from math import sqrt >>> def rms(a): ... return sqrt(a**2.mean())

En esta vemos todas las piezas necesarias para definir una funcin de verdad. Recibe un argumento, a, realiza un clculo con este mismo argumento y devuelve un resultado a la salida. Ahora intentmos llamarla desde el intrprete:
>>> rms([1,2,3,4]) Traceback (most recent File "<stdin>", line File "<stdin>", line TypeError: unsupported call last): 1, in <module> 2, in rms operand type(s) for ** or pow(): 'list' and 'int'

Este ejemplo nos sirve para introducir el concepto de duck typing. Cuando hemos definido la funcin func:rms y hemos definido el argumento a no hemos especificado ningn tipo. Declarar los argumentos de entrada y de salida es algo obligatorio en, por ejemplo, Fortran y C. En cambio en Matlab no es necesario porque la mayora de las variables tienen el mismo tipo, una matriz. En cambio Python es un lenguaje orientado a objetos as que, estrictamente hablando, tiene infinitos tipos posibles. Sin embargo al definir la funcin no se nos pide que declaremos de qu tipo es. Encima en el cuerpo de la funcin asumimos que el argumento de entrada a se puede elevar al cuadrado y dispone del mtodo mean(). Y nadie nos avisa de lo mucho que podemos cagarla con esto! Este es el concepto de duck typing. Uno puede hacer lo que le d la real gana dentro de cualquier bloque de funcin, o en un mtodo, y es responsable de lo que haya dentro. Y si da un error es culpa del programador. Este comportamiento no implica que Python sea un lenguaje menos formal. Si en un lenguaje donde tenemos que declarar el tipo de todos los argumentos nos equivocamos llamando una funcin nos avisar en tiempo de compilacin. Pero como Python es un lenguaje interpretado la decisin ha sido dejar que estos errores simplemente sucedan en tiempo de ejecucin.

En el caso de la funcin anterior nosotros, como programadores, definimos la funcin rms(), por Root Mean Square, por la raz cuadrada de cualquier tipo que pueda elevarse al cuadrado y disponga del mtodo mean(). Afortunadamente, por si nos equivocamos y pasamos a rms() algo que no cuadra, el sistema de excepciones de Python es excelente. Quizs el mejor que uno pueda encontrar. Si nos fijamos en el mensaje de error vemos que es perfectamente explicativo: no puedo elevar al cuadrado una lista de enteros. Entonces llegamos a la conclusin que la funcin func:rms est diseada para funcionar con un tipo que no es la lista y que dispone del mtodo mean(), como por ejemplo un array.
>>> from numpy import array >>> rms(array([1,2,3,4,5,6],dtype='double') 3.8944404818493075

Nota Acabamos de utilizar la clase array del mdulo numpy. Es una clase esencial para el Clculo Numrico en Python as que le dedicaremos un captulo entero ms adelante.

Docstrings
Si no hay pistas sobre los tipos en las cabeceras tendremos que documentar convenientemente cada funcin. Lo ms sencillo es utilizar una cadena de texto con soporte para salto de lnea justo despus de la definicin de la cabecera
from math import sqrt def rms(a): """ Computes the root mean square of *a*, which is a numpy array. The result is a double constant. """ return sqrt((a**2).mean())

Ahora utilizamos la funcin help() para ver qu pinta tiene en la consola


>>> help(rms) Help on function rms in module func1: rms(a) Computes the root mean square of *a*, which is a numpy array. The result is a double constant.

Python disponde de excelentes herramientas para tratar la documentacin incluida en el cdigo. Disponemos de herramientas capaces de crear manuales a partir de dicha documentacin, formatos propios para redactarla e incluso podemos introducir notacin matemtica en LaTeX para describir algoritmos. La herramienta en la que est redactado esta documentacin, Sphinx, es de gran ayuda cuando cualquier proyecto empieza a crecer de verdad para mantener todo bien ordenado y documentado.

Mdulos
Podemos utilizar los mdulos para ordenar las funciones que vayamos escribiendo de manera eficaz. Tomemos como ejemplo el siguiente archivo llamado means.py que contiene la definicin de varias medias posibles:
from math import sqrt

def rms(a): """ Computes the root mean square of *a*, which is a numpy array. The result is a double constant. """ return sqrt((a**2).mean()) def cmc(a): """ Computes the cubic root mean cube of *a*, which is a numpy array. The result is a double constant. """ return ((a**3).mean())**(1.0/3.0) def nmn(a,n): """ Computes the nth root mean nth power of *a*, which is a numpy array. The result is a double constant. """ return ((a**n).mean())**(1/float(n))

Quizs la manera ms efectiva de gestionar colecciones de funciones es la siguiente:


>>> import means >>> help(means) Help on module means: NAME FILE /home/guillem/intropy/_static/means.py FUNCTIONS cmc(a) Computes the cubic root mean cube of *a*, which is a numpy array. The result is a double constant. nmn(a, n) Computes the nth root mean nth power of *a*, which is a numpy array. The result is a double constant. rms(a) Computes the root mean square of *a*, which is a numpy array. The result is a double constant. sqrt(...) sqrt(x) Return the square root of x. means

Esto implica que podemos utilizar el nombre del mdulo, means, como prefijo del espacio de nombres:
>>> from numpy import array >>> means.cmc(array([1,2,3,4,5,6],dtype="double")) 4.1888593641200274

Y todo esto gratis slo por haber ordenado las distintas funciones dentro del mismo archivo.

Intermezzo. Tuples
Ya concemos un tipo bsico de secuencia, la lista. Es el momento de conocer otro: el tuple. Podemos hacernos una idea intuitiva de qu es si analizamos la asignacin mltiple. Cuando escribo lo siguiente:
>>> a = 2

Asigno el literal nmero entero 2 a la variable a. Podemos complicar un poco la asignacin haciendo dos a la vez
>>> a,b = 1,2

Acabo de realizar una asignacin mltiple. En este caso la variable a contendr el nmero entero 1 y la variable b el nmero entero 2. Podemos utilizar tambin la siguiente sintaxis:
>>> (a,b) = (1,2)

A todos los efectos esta sentencia ejecutable es idntica a la anterior. La nica diferencia es que en la anterior hemos utilizado la sintaxis reservada a las asignaciones mltiples mientras que en este caso hemos utilizado una variable doble. Y es precisamente este concepto de variable mltiple el que nos sirve para entender el tuple. El tuple es una secuencia inmutable que se puede utilizar, a todos los efectos, como una secuencia de variables de longitud arbitraria. El hecho que no sea inmutable diferencia el tuple de la lista. Slo podemos cambiar el tuple, no podemos cambiar ninguno de sus elementos independientemente. Como demostracin:
>>> a = (1,2,False) >>> a[2] = True Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment

Importante Un tuple no sirve para lo mismo que una lista. Un tuple sirve para concatenar variables sin que haya una relacin formal entre ellas. Las listas son para conjuntos ordenados de elementos que, tengan o no el mismo tipo, estan relacionados conceptualmente. Los tuples se indexan igual que las listas, utilizando corchetes. No slo no se pueden cambiar los elementos de un tuple sino que tampoco se pueden sustraer o aadir ms elementos.

Funciones que retornan varias variables


Gracias al concepto de tuple una funcin que retorna varias variables no es ms que una funcin que retorna un tuple
>>> ... ... >>> >>> 27 >>> >>> 8 >>> >>> def something(a): return (a,a**2,a**3) a,squarea,cubea = something(3) print cubea (a,squarea,cubea) = something(2) print cubea a = something(4) print a

(4, 16, 64)

Funciones con argumentos por omisin


Podemos definir argumentos opcionales con un valor por omisin con la siguiente notacin
>>> ... ... >>> >>> 27 >>> >>> 9 def something(a,b=2) return(a,a**b,a**(b+1)) a,squarea,cubea = something(3) print cubea a,squarea,cubea = something(3,1) print cubea

Empaquetar y desempaquetar argumentos


Podemos empaquetar argumentos de una funcin utilizando un tuple y el operador asterisco. Por ejemplo, si una funcin debe recibir dos argumentos podemos pasarle un nico argumento doble y desempaquetarlo con el asterisco
>>> a,squarea,cubea = something(*(3,1)) ... print cubea 9

Podemos tambin desempaquetar argumentos con el operador doble asterisco (**) y un diccionario pero como no sabemos qu es un diccionario vamos a por otro intermezzo.

Intermezzo. Diccionarios.
Hemos visto ya dos tipos distintos de tipos derivados: las listas y los tuples. Los primeros sirven para almacenar conjuntos ordenados de valores en los que el orden cuenta y los segundos sirven para juntar valores de manera inmutable. En la programacin moderna se ha popularizado una manera de almacenar datos de tipo key-value. En las listas y los tuples podemos acceder a cada valor a travs de un ndice, en el caso de Python numerado desde el cero. El ndice es, de manera natural, un nmero entero. Esta no es la manera necesariamente ms adecuada para nombrar un valor, por ejemplo cuando una lista contiene nmeros enteros y podemos confundir fcilmente el ndice con el contenido. El almacenamiento key-value asigna una clave a cada valor que contiene el tipo derivado, de manera que forman una pareja. La impliementacin de esta estrategia en Python es el diccionario.
>>> d = {1 : 1, 'dos': 2, 3: [1,2,3]} >>> print d {1: 1, 3: [1, 2, 3], 'dos': 2} >>> d['cuatro'] = 2.443 >>> print d {'cuatro': 2.443, 1: 1, 3: [1, 2, 3], 'dos': 2} >>> for key in d.iterkeys(): ... print d[key] ... 2.443 1 [1, 2, 3] 2

Vemos que los diccionarios son mutables, podemos eliminar o aadir ms parejas clave-valor. La manera de acceder a un valor a travs de la clave es la misma que utilizaramos si fuera el ndice de una lista o un tuple, con la diferencia que este no es necesariamente un entero. El ejemplo anterior no es muy bueno porque da un rodeo por las claves para iterar sobre los valores. Una manera un poco ms efectiva de hacerlo es utilizando el mtodo itervalues()
>>> for value in d.itervalues(): ... print value ... 2.443 1 [1, 2, 3] 2

Advertencia En los diccionarios, como en cualquier almacenamiento key-value, el orden en el que realmente estn almacenadas las parejas no se no se considera relevante. Si creamos un diccionario introduciendo las parejas en un orden dado puede ser que Python lo cambie por cualquier motivo que se puede escapar a nuestra comprensin.

De vuelta al empaquetado y desempaquetado de argumentos


Ahora que ya sabemos lo bsico sobre los diccionarios podemos volver al tema que traamos entre manos. El problema de pasar argumentos con el tuple y el operador * es que quizs no queremos introducir todos los argumentos en una llamada donde algunos de los argumentos tienen un valor por omisin. Os pongo un ejemplo
>>> def dummy(a,b=2,c=3,d=4): ... print a,c ... print b,d ... >>> dummy(1) 1 3 2 4

Cmo conseguimos llamar la funcin anterior slo mencionando los agumentos a y d? Pues con los diccionarios y el operador ** es tan sencillo como lo siguiente
>>> dummy(1,**{'d':123}) 1 3 2 123 >>> dummy(**{'a':321,'d':123}) 321 3 2 123

Nota En la funcin anterior el argumento a es imprescindible. Sea cual sea la manera en la que escojamos introducir ese argumento no nos lo podemos olvidar o recibiremos un error.

Funciones lambda
Una funcin lambda es una estructura que en tiempo de ejecucin convierte una variable en una funcin con argumentos. Aunque algunos habrn visto este tipo de estructuras por primera vez en Matlab con los function handles, expresados por el smbolo @, las funciones lambda son un invento

de los aos cincuenta. De hecho son un invento del primer lenguaje interpretado de la historia, lisp que es casi contemporneo a Fortran y fue el primer lenguaje que utilizaba el paradigma funcional. Lisp tuvo un gran arranque y se convirti rpidamente en el lenguaje por excelencia en la investigacin en inteligencia artificial pero como nunca se ense demasiado en las universidades cay un poco en el olvido. El paradigma funcional sigue vivo en algunos lenguajes de programacin modernos como Scheme o Haskell, incluso Python adopta algunas de las herramientas propias de la programacin funcional. La estructura de una funcin lambda en Python conserva la forma que tena en lisp:
>>> square = lambda x: x*x >>> print square(3) 9

Si necesitamos ms de una variable


>>> prod = lambda x,y: x*y >>> print prod(3,4) 12

Las funciones lambda son muy tiles para definir funciones cortas que slo usaremos una vez.

Programacin funcional
Python no sigue el paradigma funcional pero reinterpreta algunas de sus caractersticas ms tiles como son las funciones map() y reduce() La primera aplica una funcin dada a todos los elementos de una lista o secuencia y nos devuelve una lista con el resultado
>>> print map(lambda x:x[0]*x[1],[(1,2),(2,3),(3,4),(4,5)]) [2, 6, 12, 20]

O podemos empezar a utilizar los mdulos de la librera estndar para empezar a contestarnos preguntas que siempre quisimos formular. Cunto suman cada una de las combinaciones con repeticin de dos elementos de los nmeros del 1 al 4?

Tipos, o cmo programar en Python


En Python todos los tipos intrnsecos son objetos y como tales tienen atributos y mtodos. Un viaje por los tipos intrnsecos de Python es, en el caso de no haber utilizado nunca la orientacin a objetos, una demostracin prctica sobre cmo se usan objetos definidos por terceros. De hecho, estrictamente hablando, definir nuevos tipos en Python es utilizar un conjunto bastante limitado de las funcionalidades de la orientacin a objetos. Ya hemos hablado de los nmeros enteros, reales y complejos; de las listas, los tuples y los diccionarios; sobre los que volveremos a hablar en este captulo. Nos faltan las cadenas de caracteres.

La clase string
Aunque las cadenas de caracteres no son un tipo demasiado importante en el Clculo son la sustancia de multitud de algoritmos. Slo veremos lo ms bsico de esta clase que, en muchos sentidos, no es ms que una cadena de caracteres. Nota Una diferencia importante entre Python 2 y Python 3 es que en la en el primero existen diferencias entre las codificaciones de caracteres. No es lo mismo un caracter ASCII de uno latin1 o de uno UTF-8. La codificacin es una caraceterstica propia de algunos tipos de cadenas de caracteres. Esto cambia en Python 3, todas las cadenas de caracteres son Unicode, en este caso UTF-8. Esto implica que incluso los archivos de cdigo en Python sern unicode y que uno puede utilizar tildes y caracteres localizados para escribir comentarios. El soporte para Unicode es esencial en lo que respecta a internacionalizacin y nos incumbe a nosotros puesto que no siempre querremos utilizar ingls para todo. Para introducir una cadena de caracteres podemos utilizar bien comillas simples o comillas dobles.
>>> a = 'string' >>> b = 'string'

o bien podemos crear cadenas de caracteres vacas


>>> c = '' >>> d = str()

Las cadenas de caracteres, como hemos visto anteriormente, soportan algunas operaciones aritmticas como la suma y la multiplicacin; obviamente reinterpretadas como secuencia de caracteres. Una de las operaciones ms habituales con caracteres es la de reconocer secuencias. Para ello contamos con la funcin find() y la sentencia in.
>>> 'r' in 'string' True >>> str('string').find('r') 2

Uno de los pocos motivos por el que queremos un string en Clculo Numrico es para manipular archivos que contienen datos y sus nombres. Por ejemplo, numerarlos:
>>> for i in range(10): ... 'datafile'+str(i).zfill(3)+'.dat' 'datafile000.dat'

'datafile001.dat' 'datafile002.dat' 'datafile003.dat' 'datafile004.dat' 'datafile005.dat' 'datafile006.dat' 'datafile007.dat' 'datafile008.dat' 'datafile009.dat'

Importante Este es un buen ejemplo para introducir el concepto de pythonic. En Python, como en cualquier lenguaje de programacin, hay infinitas maneras de implementar algo. Especialmente si el lenguaje es muy extenso y es poco estricto en lo que a sintaxis se refiere. Este es precisamente el caso de Python. En el ejemplo anterior hemos creado una cadena de caracteres utilizando el operador aritmtico suma para concatenar caracteres. Aunque esto sea perfectamente correcto y leble no es el modo ms pythonic de llegar al objetivo. Es unpythonic Este adjetivo se suele utilizar para implementaciones que, en vez de utilizar alguna funcionalidad lateral del lenguaje, como por ejemplo el comportamiento de un operador aritmtico cuando se aplica a cadenas de caracteres, utiliza un mtodo ms leble y mejor documentado. Esta distincin es completamente subjetiva y slo puede utilizarse cuando ya se cuenta con una slida experiencia programando en Python. Un ejemplo de lo que es o no pythonic es optar por utilizar de manera casi obsesiva los mtodos de los tipos ms usuales como str, list o dict. Estas clases estn implementadas enteramente en C y utilizar sus mtodos suele ser ms eficiente que implementar el algoritmo nosotros mismos. Podemos proponer una implementacin ms convencional de lo anterior utilizando el mtodo join() de la clase str
>>> for i in range(10): ... str().join(['datafile',str(i).zfill(3),'.dat']) ... 'datafile000.dat' 'datafile001.dat' 'datafile002.dat' 'datafile003.dat' 'datafile004.dat' 'datafile005.dat' 'datafile006.dat' 'datafile007.dat' 'datafile008.dat' 'datafile009.dat'

Otra posibilidad bastante til es la de completar cadenas de caracteres dando formato a sus argumentos al igual que hacemos con el comando print en C. Por ejemplo:
>>> for i in range(10): ... 'datafile%03i.dat'%(i) ... 'datafile000.dat' 'datafile001.dat' (...)

Lo que viene despus del smbolo de porcentaje es un tuple en el que podemos alinear todos los argumentos que tenga la cadena de caracteres. Aunque, otra vez, hay una manera mucho ms

pythonic de hacer exactamente lo mismo, mediante la funcin format() de cualquier cadena de caracteres
>>> for i in range(10): ... 'datafile{:03d}.dat'.format(i) ... 'datafile000.dat' 'datafile001.dat' (...)

Truco Hay un buen tutorial sobre la manera de escribir cadenas de caracteres con formato en la documentacin estndar del lenguaje Empezamos a ver que si buceamos un poco por entre la documentacin de Python podemos llegar a escribir cdigo perfectamente leble, eficiente y bonito.
>>> from random import choice >>> for i in range(10): ... 'Lanzamiento {}, me ha salido {}'.format(i,choice(['Cara','Cruz'])) ... 'Lanzamiento 0, me ha salido Cruz' 'Lanzamiento 1, me ha salido Cara' 'Lanzamiento 2, me ha salido Cruz' 'Lanzamiento 3, me ha salido Cara' 'Lanzamiento 4, me ha salido Cara' 'Lanzamiento 5, me ha salido Cruz' 'Lanzamiento 6, me ha salido Cruz' 'Lanzamiento 7, me ha salido Cara' 'Lanzamiento 8, me ha salido Cara' 'Lanzamiento 9, me ha salido Cruz'

Esto nos llevara un buen rato en cualquier otro leguaje que no fuera Python, incluso en Matlab.

Literal
Hay mltiples maneras de definir una cadena de caracteres directamente sin necesidad de hacer una llamada a la clase str. Podemos utilizar bien las comillas simples o las comillas dobles indistintamente o cuando necesitemos alguno de los dos caracteres dentro. Por ejemplo, si necesitamos una comilla simple dentro de una cadena de caracteres:
>>> print "I'm afraid that was the funniest practical joke" I'm afraid that was the funniest practical joke

O viceversa, si necesitamos algunas comillas dobles podemos introducir los caracteres entre comillas simples. Tambin disponemos del control de carro con los caracteres especiales usuales como
>>> print "I am a whale!\n'______'" I am a whale! '______'

Pero si lo que realmente queremos es introducir una cadena de caracteres con ms de una lnea tenemos un literal especfico para ello
>>> print """I have seen {} ... elephants hanging ... on a spider web""".format('MILLIONS!!!') I have seen MILLIONS!!!

elephants hanging on a spider web

Tambin en este caso podemos utilizar comillas simples o dobles.

Intermezzo. Archivos y la clase file


En Clculo Numrico utilizamos esencialmente nmeros. Las cadenas de caracteres nos sirven para poder expresar texto, normalmente datos. Estos datos suelen terminar en archivos que contienen, oh sorpresa, caracteres. El problema es que de momento no tenemos ni idea de cmo abrir, leer, escribir y cerrar un archivo. Para ello necesitamos conocer la clase file que casi siempre instanciaremos a partir de la funcin open() de la librera estndar. Nota Soy un usuario de Linux desde hace ya un montn de aos. Algunos de los ejemplos de este libro rezuman cultura UNIX por todos los poros y uno puede pensar que Python es un juguetito de los que utilizamos esta familia de sistemas operativos. Esto no es verdad en absoluto. Los desarrolladores de Python han hecho un importante esfuerzo para abstraer prcticamente cualquier funcin del sistema operativo en el que estemos trabajando. Muchas de las utilidades para no tener que depender del SO estn en los mdulos os, sys y shutil. Aunque no hemos hablado sobre la librera estndar empezar a utilizarlos aqu para que los ejemplos funcionen en cualquier sistema operativo. Importante La manera usual de ejecutar Python en sistemas UNIX es llamarlo desde una consola. Esta manera de funcionar tiene implicaciones importantes porque entonces el intrprete cargar ese directorio como camino para acceder a los archivos mediante la localizacin relativa. En Windows lo ms normal es ejecutar un script desde la interfaz grfica. El comportamiento del intrprete ser cargar el directorio en el que se encuentre el script para que el mismo pueda acceder al entorno a partir de su posicin relativa. Nota SAGE es un bicho raro en lo que respecta a archivos porque se trata de una aplicacin web. Para cargar una instancia de un objeto file basta con utilizar la funcin open(), para la que no tenemos que importar ningn mdulo
>>> fh = open('tipos.rst','r')

El segundo argumento se refiere a los permisos con los que abrimos el archivo, en este caso con permisos de slo lectura. A partir de ah ya disponemos de todos los elementos necesarios para leer el archivo.
>>> print fh.readline() Tipos, o cmo programar en Python >>> print fh.readline() =================================

En este caso la variable fh dipone de los mtodos necesarios tanto para leer lnea a lnea o devolver cada una de las lneas del archivo como una lista o para leerlo byte a byte en un estilo ms parecido a C.

La misma clase que nos permite escribir archivos tambin nos permite leerlos, siempre que se trate de texto. Al final debemos acordarnos de cerrar el archivo para no ir perdiendo memoria por ah.
>>> fh.close()

Formato binario
Uno puede leer y escribir nmeros como si fuera texto, uno es libre de hacerlo, pero es una estupidez de un tamao tan estremecedor que debera estar tipificado como delito con pena de crcel. Si uno quiere guardar nmeros, como una matriz o una ristra de datos, lo mejor es guardarlo en formato binario del mismo modo que el sistema lo representa en memoria. Es sin duda la manera ms eficiente de hacerlo. Esto es independiente de cmo se abra, se lea, o se cierre el archivo. El archivo no es distinto, lo nico que cambia es su contenido. Esto abre una casustica sobre cmo representar los nmeros y los metadatos asociados como las dimensiones o la precisin. Por suerte numpy y los mdulos pickle y cpickle harn el trabajo sucio por nosotros.

La clase list
Ya hemos hablado sobre las listas pero es importante que les demos un segundo vistazo. Lo ms importante que debemos saber de una lista es que no es un array. No es una buena idea hacer operaciones aritmticas sobre los elementos de una lista porque son una secuencia de elementos que no necesariamente tienen el mismo tipo. Python lo sabe y se va a negar porque no puede multiplicar una letra por un nmero en coma flotante. Sin embargo las listas son quizs el tipo ms utilizado en Python porque son una manera muy eficiente de operar sobre listas de cosas.
>>> l = str('this is a list >>> print l ['this', 'is', 'a', 'list', >>> l.extend('that I extend >>> print l ['this', 'is', 'a', 'list', of words').split() 'of', 'words'] now'.split()) 'of', 'words', 'that', 'I', 'extend', 'now']

Indexacin
Ya hemos visto cmo funcionan los subndices
>>> l.index('list') 3 >>> l[3] 'list'

Lo que an no sabemos hacer es seleccionar una secuencia dentro de la lista a partir de los ndices. Ah debemos pararnos un instante porque si se entiende bien a la primera no se albergarn dudas al respecto en un futuro. Cuando en vez de refernrnos a un elemento nos referimos a una secuencia dentro de la lista, un slice, no nos referimos a los ndices sino a los intervalos que hay entre los elementos. Esto significa que el primer elemento, el de ndice 0, corresponde al slice 0-1. El tercer elemento, de ndice 2, corresponde al slice 2-3.

>>> l[0:1] ['this'] >>> l[2:3] ['a'] >>> l[9:10] ['now']

Aunque podemos acceder al ltimo elemento tal como se muestra en el ejemplo, disponemos de un atajo para no tener que saber cmo de larga es la lista que mejora si recordamos que podemos utilizar ndices negativos:
>>> l[:1] ['this'] >>> l[-1:] ['now']

La cosa se puede complicar. Supongamos que queremos los elementos entre el tercero y el antepenltimo
>>> l[2:-2] ['a', 'list', 'of', 'words', 'that', 'I']

Y que encima los queremos en el rden inverso


>>> l[-2:2:-1] ['extend', 'I', 'that', 'words', 'of', 'list']

Supongo que con esto es suficiente Cualquier objeto que disponga de la funcin __getitem__() puede indexarse y si dispone tambin de la funcin __getslice__() podremos tambin obtener secuencias. Hay un montn de clases que disponen de estos dos mtodos como str, tuple o, la que ms nos interesa a nosotros, array

Comprehension expressions
Algunas veces queremos generar una lista a travs de una secuencia y una condicin ms o menos compleja que no se reduce a alguno de los mtodos de una lista. Por ejemplo obtener de la lista de palabras anterior y por orden las palabras que contienen la letra o. Podemos hacerlo mediante un bucle.
>>> for w in l: ... if 'o' in w: ... s.append(w) ... >>> print s ['of', 'words', 'now']

O podemos generar directamente la lista con un comprehension


>>> s = [w for w in l if 'o' in w] >>> print s ['of', 'words', 'now']

La sintaxis de estas sentencias generadoras es prcticamente la frase en ingls: la palabra para cada palabra en la lista si la letra est en la palabra. Sencillo. Tambin nos permite empezar a utilizar la sintaxis de Python como autnticos profesionales.
>>> print str(' ').join([w.capitalize() for w in l]) 'This Is A List Of Words That I Extend Now'

Disqus

Una breve introduccin a la programacin orientada a objetos

Un pequeo viaje por la biblioteca estndar.


El mdulo os El mdulo sys El mdulo shutil El mdulo datetime

Numpy y la clase array


Un array es un conjunto de valores con el mismo tipo, esto es, todos sus elementos son enteros, reales en doble precisin, complejos en simple precisin... Python ya dispone de un tipo array que sirve para almacenar elementos de igual tipo pero no proporciona toda la artillera matemtica necesaria como para hacer operaciones de manera rpida y eficiente. De este modo, siempre que nos refiramos a la clase array siempre nos referiremos a la que viene con el mdulo numpy Si consultamos la documentacin de numpy nos cuenta lo siguiente: Numpy proporciona: 1. Un objeto tipo array para datos homogneos de tipo arbitrario 2. Operaciones matemticas rpidas para dichos arrays 3. Rutinas para lgebra lineal, transformadas de Fourier y generacin de nmeros pseudoaleatorios. Es, en sentido estricto, una parte mnima que permite convertir Python en un lenguaje apto para Clculo Numrico.

Instalar numpy
Desde el punto de vista de la instalacin, numpy no es distinto de cualquier otro mdulo de Python. El tipo de instalacin cambia bastante en funcin del sistema operativo que estemos utilizando. En Linux es recomendable instalar la versin disponible para la distribucin correspondiente. Hay tambin instaladores para Windows y Mac. Quizs lo ms adecuado es instalar alguna versin empaquetada de Python que incluya todas las libreras relacionadas con clculo cientfico como puede ser EPD (Enthought Python Distribution) o PythonX,Y.

Importar numpy
No es demasiado recomendable hacer un from numpy import *. Esto importara una cantidad bastante considerable de funciones y clases y, si estamos trabajando con algn otro mdulo relacionado con clculo numrico, es muy probable que estemos provocando un conflicto de nombres. En prcticamente toda la literatura sobre numpy se importa como:
>>> import numpy as np

O lo que es lo mismo, importar todo numpy dentro del namespace np. Esto no es ms que una abreviatura de simplemente hacer
>>> import numpy

Los recortes de cdigo de estos apuntes bien usarn el prefijo numpy o el np, sin un control especialmente estricto. Simplemente hay que tener en cuenta que los dos nombres son equivalentes.

La clase array
La clase array ser, a partir de este momento, la herramienta bsica para los recortes, los ejercicios y los ejemplos. No podemos hacer numrico en Python sin array. Para crear un array con determinados valores lo ms normal es generarlo a partir de una lista.
>>> a = np.array([[1,2],[3,4]],dtype='double') >>> print a [[ 1. 2.] [ 3. 4.]]

Acabamos de crear un array de 2 filas y 2 columnas de reales de doble precisin. Aunque la lista de listas que hemos utilizado para crear el array contuviera slo nmeros enteros (no hemos puesto ningn punto despus de cada uno de los nmeros) el argumento dtype sirve para especificar la precisin. En el siguiente ejemplo crearemos un array vaco de nmeros en coma flotante de simple precisin con la funcin empty()
>>> b = np.empty([5,5],dtype=np.float32) >>> print b [[ -1.32853384e-05 1.45904930e-33 1.55866143e-33 1.32851727e-33] [ 1.55863498e-33 1.72551991e-33 1.55871433e-33 1.55875400e-33] [ 1.72652496e-33 1.55870110e-33 1.33484143e-33 1.72649557e-33] [ 1.33462396e-33 1.72646619e-33 1.47818708e-33 1.27814146e-33] [ 1.31751905e-33 -1.13159913e-05 1.47921638e-33 1.31749995e-33]] 1.55876722e-33 1.72653965e-33 1.72555224e-33 1.50808284e-33 1.80231790e-33

Acabamos de crear un array vaco, esto significa que lo que hemos obtenido son 25 nmeros ordenados en 5 filas y 5 columnas de lo que hubiera en ese preciso instante en la memoria, aunque el resultado de esto no tenga sentido. La funcin empty() es la manera ms eficiente de alocatear memoria, aunque ya sabemos que alocatear no es necesario en Python. Si queremos generar un array y adems inicializarlo con algo que tenga sentido podemos utilizar la funcin :func:zeros
>>> b = np.zeros([5,5],dtype=np.float32) >>> print b [[ 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0.]]

Indexacin n-dimensionalidad Matlab


Es innegable que una de las inspiraciones de numpy es Matlab. La idea es intentar aprovechar todo lo bueno y corregir lo que no tiene sentido o est mal diseado.

Uno de los grandes mritos de Matlab es el disponer de tal cantidad de funciones para generar y manipular arrays que ha llegado a cambiar el lenguaje en el que se comunican muchos cientficos e ingenieros. Uno incluso puede or por ah un linspace o un meshgrid. Como el afn de Python es el de no reinventar la rueda podemos encontrar estas mismas funciones con ese mismo nombre en numpy

La clase matrix
Ya hemos visto que la clase array es ms parecida a los arrays que encontramos en C o en Fortran que a las miatrices de Matlab; todas las operaciones aritmticas se ejecutan elemento a elemento. Esto puede ser un inconveniente si nuestro cerebro ha enfermado por culpa de Matlab y cada vez que vemos una multiplicacin entre dos arrays pensamos en la multiplicacin matricial. La solucin es utilizar la clase matrix en vez de la clase array, teniendo en cuenta que slo es til en el caso bidimensional. Esta clase cambia los mtodos correspondientes a la multiplicacin y la potencia para que sea su equivalente matricial, y no el escalar. Podemos generar una matriz a partir de un array utilizando el mtodo asmatrix()

Scipy. Haciendo Python mejor que Matlab

Matplotlib. Grficos en 2D.


De todos los mdulos disponibles orientados a clculo cientfico, matplotlib es quizs el ms descaradamente inspirado en Matlab. Se trata de un paquete para la representacin de grficos planos (en 2D) tanto o ms potente que el propio Matlab que utiliza todas las convenciones de llamadas propias de Matlab intentando que se comporten de la manera ms parecida posible. Por ejemplo, disponemos de las funciones plot(), xlabel(), title(), axis()... Prcticamente todo lo que se puede hacer con Matlab se puede hacer con Matplotlib. De hecho en la pgina web del proyecto hay una galera de ejemplos bastante impresionante. Importante Obviamente todo lo que se puede hacer con Matlab programando. Matplotlib no dispone una interfaz grfica de tipo point-and-click para aspirantes a mono-lanzado-al-espacio que le da al ratn aleatoriamente a todo lo que ven. Nada de darle a un botn y que Matlab genere un script que reproduce la figura. Estos apuntes sirven para aprender a hacer cosas, no para que las cosas nos hagan a nosotros. Si habis llegado a este captulo esperando encontrar cosas as buscad en otro sitio y bebed un poco de cicuta a mi salud.

Clculo simblico con Sympy.

Soluciones a los ejercicios propuestos


Ejercicio 1
if __name__ == '__main__': f0 = 1 f1 = 1 n = 1 print f0,f1, while n < 20: f0, f1 = f1, f1+f0 print f1, n += 1

Que tiene como resultado


>>> 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946

Ejercicio 2
El ejercicio puede resolverse con un simple vistazo a la ayuda del mdulo random
>>> import random >>> random.seed() >>> random.sample(xrange(50),5) [46, 43, 38, 25, 8]

Mdulo finance
class finance.yahoostock(symbol, **kwargs)[source] Bases: object Wrapper class for Yahoo Finance chart data. The only mandatory argument is the signature of the stock as a string. Keyword arguments sdate Initial time for the data as datetime.date or datetime.datetime edate Final time for the data as datetime.date or datetime.datetime weekly If it is True gives weekly data monthly If it is True gives monthly data Example. IBM_stock = yahoostock(IBM,sdate=datetime.date(2011,1,30),weekly=True) adj_close[source] I Dont really know what this is clse[source] Value at the end of the session date[source] Date returned as a float high[source] Highest value during the session low[source] Lowest value during the session open[source] Value at the beginning of the session read()[source] Reads the data from Yahoo finance volume[source] Volume traded during the sessino

Mdulo turbulence
class turbulence.Vorticity2D(Lx, Ly, Re, CFL)[source] Bases: object Solves Navier-Stokes equations in 2D using the vorticity-current function formulation for incompressible flows. Original code from Adrian Lozano, March 22nd 2011 Modified version in Matlab by Guillem Borrell, May 23rd 2011 Ported to Python by Guillem Borrell, December 30th 2011 FW()[source] Solve the right hand side, both linear and nonlinear terms corr2d()[source] Returns the array of non shifted 2d correlations. omega[source] Transforms vorticity from Fourier to physical space to make pretty plots. set_initial(omega)[source] Set initial vorticity field once the instance has been created. Make sure that the array is (self.nx,self.ny) shaped or you will be on serious trouble. step()[source] Integrates a single Runge Kutta time step. It uses a fourth order low-storage RK scheme and the timestep is evaluated at the first substep. velocities()[source] Returns the velocity components of the result obtained from the vorticity field. class turbulence.Vorticity2DSerial(Lx, Ly, Re, CFL)[source] Bases: turbulence.Vorticity2D Class Vorticity 2D extended with fortran. Serial version of FFTW used. Requires the rhs_tur2d module properly compiled. FW()[source] cleanup()[source]

step()[source] Integrates a single Runge Kutta time step. Calls the Fortran optimized routine. It uses a fourth order low-storage RK scheme and the timestep is evaluated at the first substep. turbulence.test_kh(fign, Lx, Ly, nsteps)[source] Test a Kelvin-Helmholtz instability turbulence.test_tur2d(fign, Lx, Ly, nsteps)[source] Test a vortex soup

Python Module Index


f|t f finance t turbulence

ndice
A|C|D|F|H|L|O|R|S|T|V|Y

A
adj_close (finance.yahoostock atributo)

C
cleanup() (turbulence.Vorticity2DSerial mtodo) corr2d() (turbulence.Vorticity2D mtodo) clse (finance.yahoostock atributo)

D
date (finance.yahoostock atributo)

F
finance (mdulo) FW() (turbulence.Vorticity2D mtodo) (turbulence.Vorticity2DSerial mtodo)

H
high (finance.yahoostock atributo)

L
low (finance.yahoostock atributo)

O
omega (turbulence.Vorticity2D atributo) open (finance.yahoostock atributo)

R
read() (finance.yahoostock mtodo)

S
set_initial() (turbulence.Vorticity2D mtodo) step() (turbulence.Vorticity2D mtodo)

(turbulence.Vorticity2DSerial mtodo)

T
test_kh() (en el mdulo turbulence) turbulence (mdulo) test_tur2d() (en el mdulo turbulence)

V
velocities() (turbulence.Vorticity2D mtodo) Vorticity2D (clase en turbulence) volume (finance.yahoostock atributo) Vorticity2DSerial (clase en turbulence)

Y
yahoostock (clase en finance)

S-ar putea să vă placă și