You are on page 1of 46

Notas del curso

Programaci n en Python o
Curso de actualizaci n docente o Facultad de Ciencias
David P. Sanders
22 de junio de 2010

Captulo 1

Qu es Python? e
Python es un lenguaje de programaci n que surgi en 1990. Desde entonces se ha desarrollado enormemente, o o para volverse un lenguaje de programaci n moderno, y uno de los m s utilizados en el mundo. o a Python es un lenguaje interpretado no es necesario compilar constantemente cada programa, si no se puede utilizar de manera interactiva. Por lo tanto, es una herramienta id nea para llevar a cabo tareas de c mputo o o cientco, tales como an lisis de datos, gracaci n de resultados, y exploraci n de problemas. En este sentido, a o o se puede comparar con programas comerciales tales como Matlab. Tambi n hay paquetes que permiten llevar a e cabo c lculos simb licos a trav s de Python, de los cuales destaca sage (www.sagemath.org), por lo cual a o e tambi n se puede considerar como competidor de Mathematica y Maple. e Python viene con una losofa de bateras incluidas. Esto quiere decir que hay muchas bibliotecas disponibles que est n dise adas para facilitarnos la vida al hacer diferentes tareas, desde el c mputo cientco hasta la a n o manipulaci n de p ginas web. Por lo tanto, Python es un lenguaje sumamente vers til. o a a Cabe enfatizar que se suele encontrar Python f cil de aprenderse y de utilizarse. Por lo tanto, considero que a Python es tambi n el lenguaje id neo para la ense anza del c mputo cientco en la Facultad de Ciencias, un e o n o campo que se ha vuelto de suma importancia.

1.1.

Meta del curso

La meta principal de este curso es la de ense ar las t cnicas b sicas de Python en el contexto del c mputo n e a o cientco, y en particular de la fsica computacional, con un n de actualizaci n docente en la Facultad de o Ciencias.

CAPITULO 1. QUE ES PYTHON?

Captulo 2

Comenzando con Python


En este captulo, empezaremos a explorar el lenguaje Python. Se dar n las bases tanto de la sint xis b sica, a a a como de las herramientas principales para escribir programas en el lenguaje. En todo el curso se har enfasis a en las aplicaciones al c mputo cientco y a la ense anza del mismo. o n La versi n de Python que ocuparemos es la 2.6. La nueva versi n 3 rompe la compatibilidad con los paquetes o o b sicos para el c mputo cientco por el momento. a o

2.1.

El entorno ipython

El entorno principal que ocuparemos para trabajar de manera interactiva es ipython. Otro posible es idle. ipython est dise ado para maximar la productividad al utilizar Python. En particular, tiene ciertos comandos a n que no existen en otros interpretadores de Python. Uno muy util es
In [1]: logstart primero_log.py

Este comando graba un log (bit cora) de todo lo que se teclea en la sesi n actual en el archivo dado, aqui a o
primero_log.py.

Otra funci n de suma utilidad en ipython es que la de completar palabras parciales con la tecla <TAB>. o Adem s, los comandos who y whos proveen informaci n de las funciones nuevas agregadas en la sesi n. a o o La documentaci n para cualquier funci n o comando est disponible en ipython al poner ?, por ejemplo o o a
who?

Para funciones, ?? muestra el c digo fuente de la funci n, cuando est disponible. o o a

2.2.

Aritm tica e

Python se puede utilizar como una calculadora:


3 3 + 2 3 * (-7.1 + 10**2)

Aqu, ** indica una potencia, como en Fortran, y las par ntesis alteran la prioridad en las operaciones. e Es necesario1 tener cuidado al hacer manipulaciones con enteros:
1 / 2
1 En

Python 2.6; la situaci n cambia en Python 3. o

4
3 / 2 5 / 2

CAPITULO 2. COMENZANDO CON PYTHON

ya que el resultado se redondea al entero m s cercano. Para evitar eso, basta un punto decimal: a
1 / 2.

Los n meros sin punto decimal se consideran enteros, y los con punto decimal otantes (de doble precisi n). u o Los enteros pueden ser arbitrariamente grandes:
2 ** 2 ** 2 ** 2 ** 2

Python cuenta con n meros complejos, utilizando la notaci n 1j para la raiz de 1: u o


1 + 3j 1j * 1j j # da un error

# indica un comentario que se extiende hasta el nal de la lnea.

2.3.

Variables

Para llevar a cabo c lculos, necesitamos variables. Las variables se declaran como debe de ser: a
a = 3 b = 17.5 c = 1 + 3j print a + b / c

Python reconece de manera autom tica el tipo de la variable seg n su forma. El comando print imprime su a u argumento de una manera bonita. Al reasignar una variable, se pierde la informaci n de su valor interior, incluyendo el tipo: o
a = 3 a = -5.5

2.4.

Entrada por parte del usuario

Se puede pedir informaci n del usuario con o


a = raw_input('Dame el valor de a: ') print "El cuadrado de a es ", a*a

Las cadenas en Python son cadenas de caracteres entre ap strofes o comillas. o

2.5.

Listas

La estructura de datos principal en Python es la lista. Consiste literalmente en una lista ordenada de cosas, y reemplaza a los arreglos en otros lenguajes. La diferencia es que las listas en Python son autom ticamente de a longitud variable, y pueden contener objetos de cualquier tipo. Una lista se dene con corchetes ([ y \):
l = [3, 4, 6]

Puede contener cualquier cosa, incluyendo a otras listas!:

2.6. N-ADAS / TUPLES


l = [3.5, -1, "hola", [1.0, [3, 17]]]

Por lo tanto, es una estructura de datos muy sencillo. Los elementos de la lista se pueden extraer y cambiar usando la notaci n l[i], donde i indica el n mero del o u elemento, empezando desde 0:
l = [1, 2, 3] print l[0], l[1] l[0] = 5 l

Se pueden manipular rebanadas (slices) de la lista con la notaci n l[1:3]: o


l = [1, 2, 3, 6, 7] l[1:3] l[:3] l[3:]

Ejercicio: Qu hace l[-1]? e La longitud de una lista se puede encontrar con


len(l)

Se pueden agregar elementos a la lista con


l = [] # lista vacia l.append(17) l.append(3) print l, len(l)

Como siempre, las otras operaciones que se pueden llevar a cabo con la lista se pueden averiguar en ipython con l.<TAB>.

2.6. n-adas / tuples


Otra estructura parecida es una n-ada (tuple). Es parecido a una lista, pero se escribe con (o incluso, a veces, sin par ntesis), y no se puede modicar: e
t = (3, 5) t[0] t[0] = 1

# error!

Las n-adas se utilizan para agrupar informaci n. Se pueden asignar como sigue: o
a, b = 3, 5 print a; print b

2.7.

La biblioteca est ndar a

Python tiene una biblioteca est ndar amplia, lo cual siempre est disponible en cualquier instalaci n de Python. a a o La documentaci n para esta biblioteca est disponible en http://docs.python.org/library/ o a Por ejemplo, la secci n 9 incluye informaci n sobre el m dulo fractions: o o o
from fractions import Fraction a = Fraction(3, 5)

6
b c d d e = Fraction(1) = a + b = Fraction(4, 6) = a + d

CAPITULO 2. COMENZANDO CON PYTHON

Cada cosa en Python es un objeto, que tiene propiedades y operaciones disponibles. Fraction es un tipo de objeto (clase); sus operaciones est n disponibles en ipython a trav s de Fraction.<TAB>. Las que empiezan a e con __ son internos y deberan de ignorarse por el momento; las dem s son accesibles al usuario. a

2.8.

Programitas de Python: scripts

Una vez que las secuencias de comandos se complican, es util poder guardarlos en un programa, o script. Eso consiste en un archivo de texto, cuyo nombre termina en .py, donde se guarda la secuencia de comandos. Por ejemplo, guardemos el c digo anterior en el archivo cuad.py Podemos correr el c digo desde ipython o o con
run cuad

Al terminar de correr el programa, el control regresa a ipython, pero todava tenemos acceso a las variables y funciones denidas en el script. Alternativamente, podemos tratar el script como un programa en s al ejecutar desde el shell
python cuad.py

Al terminar, el control regresa al shell, y perdemos la informaci n adentro del script. o De hecho, un script se puede considerar un m dulo en s, que tambi n se puede importar: o e
from cuad import *

Captulo 3

Estructuras de control
Por estructuras de control, se entiende los comandos tales como condicionales, bucles, y funciones, que cambian el orden de ejecuci n de un programa. o Las estructuras de control tienen un formato en com n. A diferencia de C++ y Fortran, no existen instrucciones u que indiquen donde empieza y termina un bloque del programa: en Python, un bloque empieza por :, y su extensi n se indica por el uso de una cantidad denida de espacio en blanco al principio de cada lnea. Un buen o editor de texto te permite hacer eso de manera autom tica. a

3.1.

Condicionales

Para checar una condici n y ejecutar c digo dependiente del resultado, se ocupa if: o o
a = raw_input('Dame el valor de a') if a > 0: print "a es positiva" a = a + 1 elif a == 0: # NB: dos veces = print "a es 0" else: print "a es negativa"

En el primer caso, hay dos comandos en el bloque que se ejecutar en el caso de que a > 0. N tese que elif a o es una abreviaci n de else:if o Las condiciones que se pueden ocupar incluyen: <, <= y != (no es igual). Para combinar condiciones se ocupan las palabras and y or:
a = 3; b=7 if a>1 and b>2: print "Grandes" if a>0 or b>0: print "Al menos uno positivo"

3.2.

Bucles

La parte central de muchos c lculos cientcos consiste en llevar a cabo bucles, aunque en Python, como a veremos, eso se desenfatiza. 7

CAPITULO 3. ESTRUCTURAS DE CONTROL


while

3.2.1.

El tipo de bucle m s sencillo es un while, que ejecuta un bloque de c digo mientras una cierta condici n se a o o satisfaga, y suele ocuparse para llevar a cabo una iteraci n en la cual no se conoce de antemano el n mero de o u iteraciones necesario. El ejemplo m s sencillo de un while, donde s se conoce la condici n terminal, para contar hasta 9, se puede a o hacer como sigue:
i = 0 while i < 10: i += 1 print i

# equivalente a i = i + 1

N tese que si la condici n deseada es del tipo hasta. . . , entonces se tiene que utilizar un while con la o o condici n opuesta. o Ejercicio: Encuentra los n meros de Fibonacci menores que 1000. u Ejercicio: Implementa el llamado m todo babil nico para calcular la raz cuadrada de un n mero dado y. Este e o u m todo consiste en la iteraci n xn+1 = 1 [xn + (y/xn )]. Qu tan r pido converge? e o e a 2

3.2.2.

for

Un bucle de tipo for se suele ocupar para llevar a cabo un n mero de iteraciones que se conoce de antemano. u En el bucle de tipo for, encontramos una diferencia importante con respecto a lenguajes m s tradicionales: a podemos iterar sobre cualquier lista y ejecutar un bloque de c digo para cada elemento de la lista: o
l = [1, 2.5, -3.71, "hola", [2, 3]] for i in l: print 2*l

Si queremos iterar sobre muchos elementos, es m s util construir la lista. Por ejemplo, para hacer una iteraci n a o para todos los n meros hasta 100, podemos utilizar u
for i in range(100): print 2*i

Qu es lo que hace la funci n range? Para averiguarlo, lo investigamos de manera interactiva con ipython: e o
range(10) range(3, 10, 2)

N tese que range no acepta argumentos de punto otante. o Ejercicio: Toma una lista, y crea una nueva que contiene la duplicaci n de cada elemento de la lista anterior. o

3.3.

Funciones

Las funciones se pueden considerar como subprogramas que ejecutan una tarea dada. Corresponden a las subrutinas en Fortran. En Python, las funciones pueden o no aceptar argumentos, y pueden o no regresar resultados. La sintaxis para declarar una funci n es como sigue: o
def f(x): print "Argumento x = ", x return x*x

y se llama as:

3.4. BIBLIOTECAS MATEMATICAS


f(3) f(3.5)

Las funciones se pueden utilizar con argumentos de cualquier tipo el tipo de los argumentos nunca se especica. Si las operaciones llevadas a cabo no se permiten para el tipo que se provee, entonces Python regresa un error:
f("hola")

Las funciones pueden regresar varios resultados al juntarlos en un tuple:


def f(x, y): return 2*x, 3*y

Se puede proporcionar una forma sencilla de documentaci n de una funci n al proporcionar un docstring: o o
def cuad(x): """Funcion para llevar un numero al cuadrado. Funciona siempre y cuando el tipo de x permite multiplicacion. """ return x*x

Ahora si interrogamos al objeto cuad con ipython:


cuad?

nos da esta informaci n. Si la funci n est denida en un archivo, entonces cuad?? muestra el c digo de la o o a o denici n de la funci n. o o Ejercicio: Pon el c digo para calcular la raz cuadrada de un n mero adentro de una funci n. Calcula la raz o u o de los n meros de 0 hasta 10 en pasos de 0.2 e imprimir los resultados. u

3.4.

Bibliotecas matem ticas a

Para llevar a cabo c lculos con funciones m s avanzadas, es necesario importar la biblioteca est ndar de maa a a tem ticas: a
from math import *

Eso no es necesario al correr ipython -pylab, que invoca un modo especco de ipython1 . Sin embargo, eso importa mucho m s que la simple biblioteca de matem ticas. N tese que Python est escrito en C, as que a a o a la biblioteca math provee acceso a las funciones matem ticas que est n en la biblioteca est ndar de C. M s a a a a adelante veremos como acceder a otras funciones, tales como funciones especiales. Ejercicio: Cu l es la respuesta de la entrada sqrt(-1)? a Ejercicio: Intenta resolver la ecuaci n cuadr tica ax2 + bx + c = 0 para distintos valores de a, b y c. o a Para permitir operaciones con n meros complejos como posibles respuestas, se ocupa la biblioteca (m dulo) u o cmath. Si hacemos
from cmath import *

entonces se importan las funciones adecuadas:


sqrt(-1)
1 Yo encuentro conveniente declarar un nuevo comando pylab agregando la lnea alias pylab=ipython -pylab en el archivo .bashrc en mi directorio HOME.

10

CAPITULO 3. ESTRUCTURAS DE CONTROL

Sin embargo, ya se perdieron las funciones anteriores, es decir, las nuevas funciones han reemplazado a las distintas funciones con los mismos nombres que haba antes. Una soluci n es importar la biblioteca de otra manera: o
import cmath

Ahora las funciones que se han importado de cmath tienen nombres que empiezan por cmath.:
cmath.sqrt(-1) ipython ahora nos proporciona la lista de funciones adentro del m dulo si hacemos cmath.<TAB>. o

Captulo 4

Animaciones sencillas con Visual Python


En este captulo, veremos un paquete, Visual Python, que permite hacer animaciones en 3 dimensiones, en tiempo real, de una manera sencillsima. Casi vale la pena aprender Python solamente para eso! Y evidente mente es excelente para ense ar conceptos b sicos de la fsica. De hecho, fue dise ado principalmente para n a n este n.

4.1.

El paquete Visual Python

La biblioteca de Visual Python (de aqu en adelante, Visual) se carga con


from visual import *

La manera m s f cil de entender c mo utilizarlo es por ejemplo. a a o Empecemos creando una esfera:
s = sphere()

Podemos ver sphere() como una funci n que llamamos para crear un objeto tipo esfera. Para poder manipular o este objeto despu s, se lo asignamos el nombre s. e Al crear objetos en Visual Python, se despliegan por autom tico, y en 3 dimensiones! Como se puede imaginar, a hay una cantidad feroz de trabajo abajo que permite que funcione eso, pero afortunadamente no tenemos que preocuparnos por eso, y simplemente podemos aprovechar su existencia. Qu podemos hacer con la esfera s? Como siempre, ipython nos permite averiguarlo al poner s.<TAB>. e B sicamente, podemos cambiar sus propiedades internas, tales como su color, su radio y su posici n: a o
s.color = color.red s.radius = 0.5 s.pos = 1, 0, 0 # o s.color = 1, 0, 0

Aqu, s.pos es un vector, tambi n denido por Visual, como podemos ver al teclear type(s.pos). Los e vectores en Visual son diferentes de los que provee numpy. Los de Visual siempre tienen 3 componentes. Ahora podemos construir otros objetos, incluyendo a box, cylinder, etc. N tese que la gr ca se puede rotar o a en 3 dimensiones con el rat n, al arrastar con el bot n de derecho puesto, y se puede hacer un acercamiento o o con el bot n central. o

4.2.

Animaciones

Ahora llega lo bueno. C mo podemos hacer una animaci n? Una animaci n no es m s que una secuencia de o o o a im genes, desplegadas r pidamente una tras otra. As que eso es lo que tenemos que hacer: a a 11

12
s = sphere() b = box() for i in range(10000): rate(100) s.pos = i/1000., 0, 0

CAPITULO 4. ANIMACIONES SENCILLAS CON VISUAL PYTHON

4.3.

Agregando propiedades a objetos

Supongamos que queremos pensar en nuestra esfera como una pelota. Entonces la pelota tendr no solamente a una posici n, sino tambi n una velocidad. Se lo podemos crear as: o e
pelota = sphere() pelota.vel = vector(1,0,0)

N tese que se tiene que poner explcitamente vector, ya que sino sera una n-ada (tupla). Ahora qued denida o o la velocidad de la pelota como otra propiedad interna. Eso es b sicamente todo lo que hay que saber de Visual Python. Tambi n es posible interactuar con el teclado, a e extraer las coordenadas del rat n, etc. o

Captulo 5

C mo leer y escribir archivos o


Uno de los usos principales de Python para el c mputo cientco es el de procesar datos generados en otro o lado. Por lo tanto, es necesario saber c mo importar y exportar archivos. o

5.1.

Redirecci n de la salida o

En Linux, la manera m s f cil (pero no muy exible) de guardar datos en un archivo es utilizando la llamada a a redirecci n que provee el shell (Bash). Al correr un programa as desde Bash: o ./programa > salida.dat la salida est ndar (lo que aparece en la pantalla al correr el programa) se manda al archivo especicado. As que a
python prog.py > salida.dat

mandar la salida del programa de python prog.py al archivo salida.dat. a Ejercicio: Guarda los resultados de las raices cuadradas de diferentes n meros, y grafcalos con gnuplot: u plot "salida.dat" Ejercicio: Haz una gr ca de la velocidad de convergencia del m todo Babil nico para calcular la raz cuadraa e o da.

5.2.

Leer archivos

Para leer un archivo, primero es necesario abrirlo para leerse. Supongamos que tenemos un archivo llamado datos.dat, entonces lo podemos abrir para su lectura con
entrada = open("datos.dat", "r")

El segundo argumento, "r", es para indicar que se va a leer (read) el archivo. El objeto entrada ahora representa el archivo. Para leer del archivo abierto, hay varias posibilidades. Podemos leer todo de un golpe con entrada.read(), leer todo por lneas con entrada.readlines(), o lnea por lnea con entrada.readline(). [N tese que o lo que se ha ledo ya no se puede leer de nuevo sin cerrar el archivo con entrada.close() y volverlo a abrir.] Por ejemplo, podemos utilizar
for linea in entrada.readlines(): print linea

Sin embargo, tal vez la opci n m s f cil e intuitiva es o a a 13

14
for linea in entrada: print linea

CAPITULO 5. COMO LEER Y ESCRIBIR ARCHIVOS

Es decir, el archivo se comporta como una secuencia! Ahora, la lnea viene como una sola cadena, con espacios etc. Para extraer la informaci n, primero necesitamos o dividirlo en palabras:
palabras = linea.split()

Si todos los datos en realidad son n meros, entonces tenemos que procesar cada palabra, convirti ndola en un u e n mero: u
datos = [] for i in palabras: datos.append( float(i) )

Resulta que hay una manera m s f cil, de m s alto nivel, y (!) m s r pida de hacer eso: a a a a a
map(float, palabras)

Eso literalmente mapea la funci n float sobre la lista palabras. o Combinando todo, podemos escribir
entrada = open("datos.dat", "r") for linea in entrada: datos = map( float, linea.split() )

Ahora adentro del bucle podemos manipular los datos como queramos. Ejercicio: Para un archivo con dos columnas, leer los datos de cada columna en dos listas por separado.

5.3.

Escribir archivos

El m todo de redirigir la salida que vimos arriba es r pido y f cil. Sin embargo, no es de ninguna manera e a a exible, por ejemplo no podemos especicar desde nuestro programa el nombre del archivo de salida, ni escribir en dos archivos diferentes. Para hacer eso, necesitamos poder abrir un archivo para escribirse:
salida = open("resultados.dat", "w")

La parte m s complicada viene al momento de escribir en el archivo. Para hacerlo, ocupamos la funci n a o salida.write(). Sin embargo, esta funci n puede escribir solamente cadenas. Por lo tanto, si queremos o escribir n meros contenidos en variables, es necesario convertirlos primero a la forma de cadena. u Una manera de hacer eso es con la funci n str(), y concatenar distintas cadenas con +: o
a = 3 s = "El valor de a es " + str(a)

Sin embargo, para largas secuencias de datos eso se vuelve latoso.

5.4.

Sustituci n de variables en cadenas o

La manera m s elegante de hacerlo es con la sustituci n de variables en cadenas1 . En una cadena ponemos una a o secuencia especial de caracteres, empezando por %, que indica que se sustituir el valor de una variable: a
1 Eso

es muy parecido a printf en C.

5.4. SUSTITUCION DE VARIABLES EN CADENAS


a s b s = = = = 3 "El valor de a es %d" % a 3.5; c = 10.1 "b = %g; c = %g" % (b, c)

15

El caracter despues del % indica el tipo de variable que incluir en la cadena: d corresponde a un entero, g o f a un otante, y s a otra cadena. Tambi n se puede poner un n mero entero, que es el tama o del campo, y un e u n punto decimal seguido por un n mero, que da el n mero de decimales para el caso de f. u u Finalmente ahora podemos imprimir en el archivo, por ejemplo
salida.write(" %g\t %g" % (a,b) )

Aqu, \t representa un tabulador, y \n una nueva lnea.

16

CAPITULO 5. COMO LEER Y ESCRIBIR ARCHIVOS

Captulo 6

Operaciones matem ticas y la biblioteca de arrea glos numpy


6.1. Conversi n de numeros o

Acord monos que hay distintos tipos de n meros en Python, principalmente enteros (int) y otantes (float). e u Para convertir entre diferentes tipos, incluyendo cadenas, podemos utilizar
a = float(3) b = float('3.5')

6.2.

Aritm tica con precisi n arbitraria e o

A veces, es necesaria poder llevar a cabo operaciones aritm ticas con n meros otantes (reales) con precisi n e u o superior a los 16 dgitos que provee el float (n mero de doble precisi n) de Python. Para hacerlo, existen u o varios proyectos que proveen bibliotecas con este n. La mayora de estas bibliotecas son interfaces a otros proyectos escritos en C++. Aqu veremos una opci n, la biblioteca mpmath, que est escrito completamente en Python. En principio eso o a lo hace m s lento, pero m s f cil de entender y modicar el c digo. a a a o Para cargar la biblioteca, hacemos
from mpmath import *

Para cambiar la precisi n, hacemos o


mp.dps = 50

Ahora, para crear un n mero otante de esta precisi n, hacemos u o


x = mpf('1.0')

donde el n mero se expresa como cadena. u Al hacer manipulaciones con x, los c lculos se llevan a cabo en precisi n m ltiple. Por ejemplo, a o u
print x/6., x*10 print mpf('2.0')**2**2**2**2

Con mpmath, no hay lmite del exponente que se puede manejar. Tambi n est n denidas muchas funciones, e a por ejemplo sin, exp y log. Para imprimir un n mero con una precisi n dada, usamos u o 17

18

CAPITULO 6. OPERACIONES MATEMATICAS Y LA BIBLIOTECA DE ARREGLOS NUMPY

nprint(x, 20)

6.3.

La biblioteca numpy

Hasta ahora, hemos utilizado listas para guardar y manipular datos. Sin embargo, las listas no se comportan como vectores, y menos como matrices al sumarlos no se comportan de la manera adecuada, etc. El prop sito o de la biblioteca numpy es justamente el de proporcionar objetos que represantan a vectores y matrices matem ticos, con todas las bondades que traen consigo este tipo de objetos. a La biblioteca se carga con
from numpy import *

Provee muchas funciones para trabajar con vectores y matrices.

6.4.

Creando vectores

Los vectores se llaman (aunque es un poco confuso) arrays, y se pueden crear de distintas maneras. Son como listas, pero con propiedades y m todos adicionales para funcionar como objetos matem ticos. La manera m s e a a general de crear un vector es justamente convirtiendo desde una lista de n meros: u
from numpy import * a = array( [1, 2, -1, 100] )

Un vector de este tipo puede contener s lo un tipo de objetos, a diferencia de una lista normal de Python. Si o todos los n meros en la lista son enteros, entonces el tipo del arreglo tambi n lo es, como se puede comprobar u e con a.dtype. Es com n querer crear vectores de cierto tama o con todos ceros: u n
b = zeros( 10 ) print b

o todos unos:
b = ones( 10 ) print b

Tambi n hay distintas maneras de crear vectores que consisten en rangos ordenados, por ejemplo arange, que e funciona como range, con un punto inicial, un punto nal, y un paso:
a = arange(0., 10., 0.1)

y linspace, donde se especica puntos iniciales y nales y un n mero de entradas: u


l = linspace(0., 10., 11)

Una notaci n abreviada para construir vectores es r_, que se puede pensar como una abreviaci n de vector o o rengl n: o
a = r_[1,2,10,-1.]

Este m todo se extiende para dar una manera r pida de construir rangos: e a
r_[3:7] r_[3:7:0.5] r_[3:7:10j]

Este ultimo utiliza un n mero complejo simplemente como otra notaci n, y es el equivalente de linspace(3,7,10). u o

6.5. OPERANDO CON VECTORES

19

6.5.

Operando con vectores

Los vectores creados de esta manera se pueden sumar, restar etc., como si fueran vectores matem ticos. Todas a las operaciones se llevan a cabo entrada por entrada:
a = array( [1., 4., 7. ]) b = array( [1., 2., -2. ]) print a+b, a-b, a*b, a/b, a**b

Ejercicio: C mo se puede crear un vector de 100 veces 3? o Las funciones m s comunes entre vectores ya est n denidas en numpy, entre las cuales se encuentran dot(a,b) a a para productos escalares de dos vectores de la mismo longitud, y cross(a,b) para el producto cruz de dos vectores de longitud 3. Adem s, cualquier funci n matem tica como sin y exp se puede aplicar directamente a un vector, y regrea o a sar un vector compuesto por esta funci n aplicada a cada entrada del vector, tipo map. a o Es m s: al denir una funci n el usuario, esta funci n normalmente tambi n se pueden aplicar directamente a a o o e un vector:
def gauss(x): return 1./ (sqrt(2.)) * exp(-x*x / 2.) gauss( r_[0:10] )

6.6.

Extrayendo partes de un vector

Para extraer subpartes de un vector, la misma sintaxis funciona como para listas: se extraen componentes (entradas) individuales con
a = array([0, 1, 2, 3]) print a[0], a[2]

y subvectores con
b = a[1:3]

N tese, sin embargo, que en este caso la variable b no es una copia de esta parte de a. M s bien, es una vista o a de a, as que ahora si hacemos
b[1] = 10

entonces la entrada correspondiente de a tambi n cambia! Este fen meno tambi n funciona con listas: e o e
l=[1,2,3]; k=l; k[1] = 10

En general, en Python las variables son nombres de objetos; al poner b = a, tenemos un mismo objeto con dos nombres!

6.7.

Matrices

Las matrices se tratan como vectores de vectores, o listas de listas:


M = array( [ [1, 2], [3, 4] ] )

La forma de la matriz se puede ver con


M.shape

20

CAPITULO 6. OPERACIONES MATEMATICAS Y LA BIBLIOTECA DE ARREGLOS NUMPY

y se puede manipular con


M.shape = (4, 1); print M

o con
M.reshape( 2, 2 )

De hecho, eso es una manera util de crear las matrices:


M = r_[0:4].reshape(2,2)

Podemos crear una matriz desde una funci n: o


def f(i, j): return i+j M = fromfunction(f, (3, 3))

Dado que las matrices son vectores de vectores, al hacer


print M[0]

nos regresa la primera componente de M, que es justamente un vector, viz. el primer rengl n de M. Si queremos o cierta entrada de la matriz, entonces m s bien necesitamos especicar dos coordenadas: a
M[0][1] M[0, 1]

[Tambi n podemos poner M.item(1) que aparentemente es ma eciente.] e s Para extraer ciertas renglones o columnas de M, utilizamos una extensi n de la notaci n para vectores: o o
M = identity(10) M[3:5] M[:, 3:5] M[3:9, 3:5] # matriz identidad de 10x10

Una funci n poderosa para construir matrices repetidas es tile o


tile( M, (2,2) )

Otros m todos utiles son diagonal, que regresa una diagonal de un arreglo: e
diagonal(M) diagonal(M, 1)

y diag, que construye una matriz con el vector dado como diagonal:
diag([1,2,3]) diag([1,2,3], 2)

6.8. Algebra lineal


Adentro de numpy hay un m dulo de algebra lineal que permite hacer las operaciones m s frecuentes que o a involucran matrices y vectores. Para empezar, todava no adentro del m dulo numpy, est n los productos de una matriz M con un vector v y de o a dos matrices. Los dos se llevan a cabo con dot:

6.9. FUNCIONES PARA RESUMIR INFORMACION SOBRE VECTORES Y MATRICES


M = r_[0:4].reshape(2,2) v = r_[3, 5] dot(M, v) dot(M, M)

21

Ejercicio: Utiliza el m todo de potencias para calcular el vector propio de una matriz cuadrada M correspone diente al valor propio de mayor m dulo. Este m todo consiste en considerar la iteraci n M n v. o e o Para algebra lineal, se ocupa el m dulo linalg: o
from numpy import linalg

Entonces las funciones del m dulo se llaman e.g. norm para la norma de un vector se llama o
linalg.norm(v)

Una alternativa es importar todas las funciones de este subm dulo o


from numpy.linalg import *

entonces ya no se pone linalg., y se puede referir simplemente a norm. Algunas de las funciones utiles incluyen linalg.eig para calcular los valores y vectores propios de una matrix:
linalg.eig(M)

y linalg.eigvals para solamente los valores propios. Hay versiones especiales eigh y eigvalsh para matrices hermitianas o sim tricas reales. e Tambi n hay det para determinante, e inv para la inversa de una matriz. Finalmente, se puede resolver un e sistema de ecuaciones lineales M x = b con
linalg.solve(M, b)

6.9.

Funciones para resumir informaci n sobre vectores y matrices o

Hay varias funciones que regresan informaci n resumida sobre vectores y matrices, por ejemplo o
a = r_[0:16].reshape(4,4) a.max() a.min(1) a.mean(0) a.mean(1) a.sum(1)

# actua sobre solamente un eje y regresa un vector

Tambi n podemos seleccionar a los elementos de un arreglo que satisfacen cierta propiedad: e
a > 5 a[a > 5] = 0

Adem s existe una funci n where, que es como una versi n vectorizada de if: a o o
b = r_[0:16].reshape(4,4) c = list(b.flatten()) c.reverse() c = array(c).reshape(4,4) a = where(b < 5, b, c)

22

CAPITULO 6. OPERACIONES MATEMATICAS Y LA BIBLIOTECA DE ARREGLOS NUMPY

Este comando pone cada entrada de a igual a la entrada correspondiente de b si esta es menor que 5, o a la de c si no.

6.10.

Numeros aleatorios

La biblioteca numpy incluye un m dulo amplio para manipular n meros aleatorios, llamado random. Como o u siempre, las funciones se llaman, por ejemplo, random.random(). Para facilitarnos la vida, podemos importar todas estas funciones al espacio de nombres con
from numpy import * random? # informacion sobre el modulo from random import * # 'random' esta

o
from numpy.random import *

N tese que hay otro m dulo random que existe afuera de numpy, con distinta funcionalidad. o o La funcionalidad b sica del m dulo es la de generar n meros aleatorios distribuidos de manera uniforme en el a o u intervalo [0, 1):
random() for i in xrange(10): random()

Al poner random(N), nos regresa un vector de n meros aleatorios de longitud N. u Para generar una matriz aleatoria, podemos utilizar
rand(10, 20)

Para n meros en un cierto rango [a, b), podemos utilizar u


uniform(-5, 5, 10)

Tambi n hay diversas funciones para generar n meros aleatorios con distribuciones no-uniformes, por ejemplo e u exponential(10) y randn(10,5,10) para una distribuci n normal, o binomial(10,3,100). o Ejercicio: Calcula la distribuci n de distancias entre valores propios consecutivos de una matriz aleatoria real o y sim trica. e

6.11.

Transformadas de Fourier

Otro subm dulo util de numpy es fft, que provee transformadas r pidas de Fourier: o a
from numpy import * x = arange(1024) f = fft.fft(x) y = fft.ifft(f) linalg.norm( x - y )

Captulo 7

Gr cas con matplotlib a


En este captulo, veremos c mo podemos crear gr cas dentro de Python, usando el paquete matplotlib y o a su entorno pylab.

7.1.

Entorno pylab

El paquete matplotlib dibuja las gr cas. Para integrar mejor este m dulo con el uso interactivo, y en a o particular con ipython, incluye un m dulo pylab, que provee muchos comandos de utilidad para manejar o matplotlib. La manera m s efectiva de cargar la biblioteca pylab es al mero momento de correr ipython: se da la opci n a o -pylab en la lnea de comandos1 :
> ipython -pylab

Si todo funciona correctamente, deberas recibir el mensaje Welcome to pylab, a matplotlib-based Python environment. En este caso, ya se habr cargado el entorno pylab, que incluye el m dulo matplotlib para a o llevar a cabo gr cas, y tambi n carga autom ticamente numpy, por lo cual no es necesario volver a cargar estos a e a m dulos para uso interactivo. [S es necesario cargarlos explcitamente en cualquier script que ocupe gr cas.] o a

7.2.

Gr cas b sicas a a

El comando principal de matplotlib / pylab es plot. Acepta uno o dos listas o vectores de numpy, que corresponden a las coordenadas y (si hay un solo vector) o x y y de una gr ca 2D. Por ejemplo, si queremos a gracar los cuadrados de los n meros de 1 a 10, podemos hacer u
x = arange(10) y = x * x plot(x, y)

Si queremos puntos en lugar de lneas, hacemos


plot(x, y, 'o')

al estilo de MATLAB. (De hecho, pylab se cre bas ndose en el comportamiento de MATLAB.) o a N tese que por defecto las gr cas se acumulan. Este comportamiento se puede modcar con hold(False), o a que reemplaza las gr cas con las nuevas, y hold(True), que regresa a la funcionalidad por defecto. Tambi n a e se puede utilizar clf() para limpiar la gura.
encuentro conveniente declarar un nuevo comando pylab agregando la lnea alias pylab=ipython -pylab en el archivo .bashrc en mi directorio hogar.). Entonces se puede correr simplemente a poner pylab en la lnea de comandos.
1 Yo

23

24

CAPITULO 7. GRAFICAS CON MATPLOTLIB

La ventana que cree matplotlib incluye botones para poder hacer acercamientos y moverse a trav s de la e gr ca. Tambi n incluye un bot n para exportar la gura a un archivo en distintos formatos. Los formatos de a e o principal inter s son PDF, que es un formato vectorial (que incluye las instrucciones para dibujar la gura), e que da la calidad necesaria para las publicaciones, y PNG, que da una imagen de la gura, y es adecuada para p ginas web. a

7.3.

Cambiando el formato

Hay distintos tipos de lneas y puntos disponibles, y se puede modicar el tama o de ambos. Todas las opciones n est n disponible a trav s de la documentaci n de plot, a trav s de plot?. Adem s, los colores se pueden a e o e a especicar explcitamente:

x = arange(10) plot(x, x**2, 'ro', x, 2*x, 'gx') plot(x, 3*x, 'bo-', linewidth=3, markersize=5, markerfacecolor='red', markeredgecolor='green', mar

Se pueden dar cualquier n mero de gr cas que dibujar en un solo comando. Si el formato no se da explcitau a mente, entonces matplotlib escoge el siguiente de una secuencia razonable de estilos.

7.4.

Etiquetas

Se puede proporcionar un ttulo de la gr ca con title a


title("Algunas funciones sencillas")

Los ejes se pueden etiquetar con


xlabel("x") ylabel("f(x)")
A Una bondad de matplotlib es que las etiquetas se pueden expresar en formato LTEX y se interpretar aua tom ticamente de la forma adecuada: a

xlabel("$x$") ylabel("$x2, 2x, \exp(x)$", fontsize=16)

# cambia tamano de fuente

Tambi n se pueden colocar etiquetas arbitrarias con e


text(4.6, 35, "Punto de\ninteres")

Si se le asigna a una variable, entonces se puede volver a remover con


etiq = text(4.6, 35, "Punto de\ninteres") etiq.remove() draw()

Es necesario llamar a draw() para volver a dibujar la gura.

7.5.

Figuras desde scripts

Una vez que una gura se vuelve complicada, es necesario recurrir a un script que contenga las instrucciones para dibujarla. Eso es sumamente importante en particular para preparar guras para un documento, donde se ajustar varias veces una sola gura hasta que quede bien. a Para utilizar matplotlib desde un script, es necesario incluir la biblioteca pylab. Luego se puede utilizar plot. Para ver la imagen, a veces es necesario poner el comando show():

7.6. ESCALAS LOGARITMICAS


from pylab import * x = arange(10) plot(x, x**2) show()

25

Eso tambi n es necesario al utilizar pylab desde ipython sin poner ipython-pylab, pero en este caso, es e necesario cerrar la gr ca para poder volver a utilizar el ipython. a

7.6.

Escalas logartmicas

Para utilizar ejes con escalas logartimicas, hay tres funciones: loglog, semilogy y semilogx. Se utilizan en lugar de plot:
t = arange(1000) p = t**(-0.5) loglog(t, p, 'o')

7.7.

Multiples dibujos

Est f cil hacer m ltiples dibujos alineados con subplot. Su sintaxis es a a u


subplot(num_renglones, num_columnas, num_dibujo)

Es decir, se especican el n mero de renglones y columnas que uno quiere, y el ultimo n mero especica cu l u u a dibujo es los num_renglones num_columnas es. Aqu est un ejemplo adaptado de la documentaci n de a o matplotlib:
def f(t): """Oscilacion amortiguada""" c = cos(2*pi*t) e = exp(-t) return c*e t1 = arange(0.0, 5.0, 0.1) t2 = arange(0.0, 5.0, 0.02) t3 = arange(0.0, 2.0, 0.01) subplot(211) l = plot(t1, f(t1), 'bo', t2, f(t2), 'k--', markerfacecolor='green') grid(True) title('Amortiguacion de oscilaciones') ylabel('Amortiguada') subplot(212) plot(t3, cos(2*pi*t3), 'r.') grid(True) xlabel('tiempo $t$ (s)') ylabel('No amortiguada') show()

7.8.

Animaciones

Las gr cas hechas en matplotlib se pueden animar. La manera m s f cil es simplemente redibujar la gr ca a a a a completa cada vez que se cambian los datos. Sin embargo, eso no es eciente, ya que se tiene que recalcular cada vez las etiquetas etc.

26

CAPITULO 7. GRAFICAS CON MATPLOTLIB

Una mejor soluci n es que cada vez se cambie simplemente el contenido de datos de la gr ca. Primero es o a necesario asignarle a la gr ca un nombre: a
from pylab import * x = arange(10) y = x*x ion() p, = plot(x, y) for a in arange(0, 10, 0.1): x = arange(10) + a p.set_xdata(x) draw()

N tese el comando ion() (interactividad prendida). El comando p, = plot(x,y) es necesario ya que el o comando plot regresa una lista de todos los objetos en el plot. Se utiliza esta asignaci n de tuplas para extraer o realmente el primer elemento; sera equivalente (pero menos natural) poner p = plot(x,y)[0].

7.9.

Otros tipos de gr cas a

Aparte del tipo b sico de gr cas que hemos visto hasta ahora, que permiten llevar a cabo gr cas de datos a a a como puntos y/o lneas, existe en matplotlib una gran variedad de otros tipos de gr cas posibles; se reere a a la p gina principal http://matplotlib.sourceforge.net y a la p gina http://www.scipy. a a org/Cookbook/Matplotlib que contiene muchos ejemplos. Por ejemplo, podemos visualizar matrices 2D como heat-maps (mapas en los cuales el color corresponde al valor de la matriz) con pcolor y imshow. N tese que para crear una gura cuadrada, se puede utilizar o
f = figure( figsize=(8,8) )

Otro tipo de gr ca disponible es un histograma. pylab puede calcular y dibujar la gr ca en un solo comando: a a
from pylab import randn, hist x = randn(10000) hist(x, 100, normed=True)

Hay una funci n histogram en numpy que calcula histogramas sin dibujarlos. o Aqu va una versi n tomada de la documentaci n: o o
import numpy as np import matplotlib.mlab as mlab import matplotlib.pyplot as plt mu, sigma = 100, 15 x = mu + sigma*np.random.randn(10000) # the histogram of the data n, bins, patches = plt.hist(x, 50, normed=1, facecolor='green', alpha=0.75) # add a 'best fit' line y = mlab.normpdf( bins, mu, sigma) l = plt.plot(bins, y, 'r--', linewidth=1) plt.xlabel('Smarts') plt.ylabel('Probability') plt.title(r'$\mathrm{Histogram\ of\ IQ:}\ \mu=100,\ \sigma=15$') plt.axis([40, 160, 0, 0.03])

7.10. USO AVANZADO DE MATPLOTLIB


plt.grid(True) plt.show()

27

7.10.

Uso avanzado de matplotlib

Para usos m s avanzados de matplotlib, es necesario entender mejor la estructura interna del paquete, que a es justamente lo que esconde pylab. Por ejemplo, para colocar una echa en un dibujo, utilizamos patches (parches):
from pylab import * x = arange(10) y = x plot(x, y) arr = Arrow(2, 2, 1, 1, edgecolor='white') ax = gca() # obtener el objeto tipo "eje" ("axis") ax.add_patch(arr) arr.set_facecolor('g') show()

7.11.

Mallas con meshgrid

Por lo tanto, es necesario primero construir la malla donde se calcular el campo vectorial. Esto se hace con a
meshgrid, que acepta dos vectores 1D que dan las coordenadas x y y de los puntos de la malla. meshgrid

construye una malla cuyos v rtices son los puntos en el producto cartesiano de los dos conjuntos de puntos. e Regresa una tupla de dos matrices, que dan las coordenadas x y y respectivamente de los puntos de la malla:
x = r_[-5:5:11j] y = r_[-5:5:11j] X, Y = meshgrid(x, y) print X, Y

As que meshgrid en alg n sentido provee un mapa de las entradas de la matriz a sus coordenadas en el u espacio real 2D. El punto de esta construcci n es que ahora las funciones se pueden evaluar en cada punto de la red al mismo o tiempo. Por ejemplo, para tener una matriz que representa la suma de las componentes x y y en cada punto de la malla, hacemos
Z = X + Y

Para tener la distancia de la origen en cada punto, hacemos


R = sqrt(X*X + Y*Y)

Una abreviaci n del comando meshgrid, usando una notaci n indicial parecida a la que ocupa r_, es o o
X, Y = mgrid[-5:5:11j, -5:5:11j]

28

CAPITULO 7. GRAFICAS CON MATPLOTLIB

7.12.

Campos vectoriales

Los campos vectoriales se pueden dibujar con la funci n quiver2 . Esta funci n acepta 4 matrices, X y Y o o que dan las coordenadas X y Y de los puntos de la malla donde se especica el campo, y U y V , que son las componentes de los vectores que dibujar en cada punto. Por ejemplo, podemos dibujar un campo radial al poner
X, Y = mgrid[-5:5:11j, -5:5:11j] quiver(X, Y, X, Y)

ya que en el punto (x, y) de la malla ponemos el vector (x, y). Lo podemos colorear seg n el valor de la distancia u del origen con
X, Y = mgrid[-5:5:11j, -5:5:11j] R = sqrt(X*X + Y*Y) quiver(X, Y, X, Y, R)

Algunos campos m s interesantes son a


quiver(X, Y, Y, X) quiver(X, Y, Y, -X)

Resulta que se ven un poco deformados, ya que cada echa se dibuja empezando en el punto dado de la malla. Se ve m s ordenado al colocar el punto medio de la echa en el punto de la malla: a
quiver(X, Y, Y, X, R, pivot='middle')

7.13.

Gr cas en 3D a

En versiones recientes de matplotlib, hay soporte limitado para gr cas en 3D. El m dulo relevante es a o mplot3d. Un ejempo tomado de la documentaci n: o
from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm import matplotlib.pyplot as plt import numpy as np fig = plt.figure() ax = Axes3D(fig) X = np.arange(-5, 5, 0.25) Y = np.arange(-5, 5, 0.25) X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet) plt.show()

7.14.

Interacci n con el mouse y el teclado o

Se puede interactuar con el mouse y con el teclado de una manera relativamente sencilla. Para interactuar con el mouse, creamos una funci n que se llamar cuando pylab note que hay un evento o a que involucre el mouse. Esta funci n toma un solo argumento, que suele llamarse event. pylab manda a la o
2 Eso

es una broma nerd: quiver quiere decir carcaj (un objeto donde se guardan las echas).

7.14. INTERACCION CON EL MOUSE Y EL TECLADO

29

funci n un objeto que representa el evento, incluyendo cu l bot n se presion y en que posici n de la gr ca. o a o o o a La funci n se registra ante pylab con la funci n connect. o o Lo mismo tiene para el teclado. As que el c digo m s sencillo es el siguiente. N tese que es necesario que o a o haya una gr ca pre-existente antes de poder interactuar con ella. a
from pylab import * def teclado(event): print "Se tecleo %s en la posicion ( %g, %g)" % event.key, event.xdata, event.ydata def mouse(event): if event.button != 1: return x,y = event.xdata, event.ydata print "Se oprimio el boton izquierdo en ( %g, %g)" % (x, y) x = arange(10) y = x*x p, = plot(x, y) show() connect('button_press_event', mouse) connect('key_press_event', teclado)

30

CAPITULO 7. GRAFICAS CON MATPLOTLIB

Captulo 8

Ejemplos de c lculos y visualizaciones a


8.1. Integraci n de ecuaciones diferenciales ordinarias o

Veamos unas rutinas y herramientas para integrar ecuaciones diferenciales. Ocuparemos las t cnicas b sicas e a que se ven en el curso de Fsica Computacional los m todos de Euler y RungeKutta. e La ecuaci n que resolveremos es o x = f(x). Recordemos que eso es una notaci n para decir que o x(t) = f(x(t)). (8.2) (8.1)

Es decir, si estamos en el punto x(t) al tiempo t, entonces la derivada instant nea en este momento y este punto a del espacio fase est dada por f(x(t)). a Para resolver esta ecuaci n en la computadora, es necesario discretizarla de una manera u otra. La manera m s o a sencilla para hacerlo es discretizando el tiempo en pasos iguales de tama o t y aproximando la derivada por n una diferencia nita, o sea expandiendo en una serie de Taylor, lo cual da x(t + t) x(t) + t x(t) + O((t)2 ) = x(t) + hf(x(t)) + O((t)2 ), (8.3)

donde h = t es el paso de tiempo. Eso nos da el m todo de Euler. Lo podemos implementar como una funci n e o que regresa el valor nuevo de la variable:
def euler(t, x, h, f): return x + h*f(x)

N tese que la funci n euler toma el nombre de la funci n f que integrar como argumento. o o o Ahora para integrar la ecuaci n entre un tiempo initial t0 y un tiempo nal t f , repetimos este paso muchas o veces:
def integrar(t0, tf, h, x0, f): lista_t = [] lista_x = [] x = x0 for t in arange(t0, tf+h/2., h): x = euler(t, x, h, f) lista_t.append(t) lista_x.append(x) return lista_t, lista_x

31

32

CAPITULO 8. EJEMPLOS DE CALCULOS Y VISUALIZACIONES

Para integrar la ecuaci n x = x ponemos entonces o


def f(x): return x t, x = integrar(0, 10, 0.1, 10, f)

N tese que el mismo c digo funciona para ecuaciones vectoriales x = f(x), siempre y cuando la funci n f o o o acepte un vector y regresa un vector. Si tenemos varios m todos, entonces cambiamos la denici n de integrar a e o
def integrar(t0, tf, h, x0, f, metodo):

y la lnea que hace el trabajo a


x = metodo(t, x, h, f)

Ahora para integrar con respecto a distintos m todos, podemos hacer e


metodos = [euler, rk2, rk4] for metodo in metodos: t, x = integrar(0, 10, 0.1, 10, f, metodo)

Captulo 9

Comunic ndose con otros programas a


En este captulo, veremos c mo un programa de Python puede interactuar con otros programas. o

9.1.

Redirecci n o

En esta secci n veremos algunas t cnicas utiles del shell bash que no est n restringidos a python. o e a Ya hemos visto que la manera m s f cil de guardar informaci n en un archivo es con la redirecci n de la salida a a o o est ndar del programa: corriendo desde la terminal, ponemos a
python prog.py > salida.dat

y as creamos un archivo salida.dat, donde se capta la informaci n que anteriormente se mandaba a la o terminal. Lo mismo se puede hacer con la entrada est ndar: si tenemos un programa que lee informaci n que teclea el a o usuario:
a = raw_input("Dame a: ") b = raw_input("Dame b: ")

Entonces podemos tambi n mandarle valores de un archivo, al redirigir la entrada est ndar: e a
python prog.py < datos.dat

donde datos.dat contiene la informaci n deseada. A su vez, la salida de este programa se puede mandar a o otro archivo con >. Finalmente, si queremos conectar la salida de un programa con la entrada de otro, utilizamos un tubo (pipe):
python prog1.py | python prog2.py

Eso es equivalente a hacer


python prog1.py > temp.dat python prog2.py < temp.dat

pero sin la necesidad de crear el archivo temporal. Los pipes son muy utiles en unix, y se pueden encadenar. 33

34

CAPITULO 9. COMUNICANDOSE CON OTROS PROGRAMAS

9.2.

Argumentos de la lnea de comandos

Una manera m s exible y m s util para mandar informaci n a un programa es a trav s de argumentos que se a a o e ponen en la mera lnea de comandos. A menudo queremos mandar a un programa los valores de un par metro, a para despu s poder hacer barridos del mismo. e Para hacerlo, Python provee una variable llamada argv, que viene denida en el m dulo sys. Podemos ver o qu es lo que contiene esta variable al correr un programa sencillo: e
from sys import argv print "Argumentos: argv"

Si ahora llamamos a nuestro programa con


python prog.py 10 0.5 ising

entonces vemos que argv es una lista de cadenas, cada una representando uno de los argumentos, empezando por el nombre del script. Por lo tanto, podemos extraer la informaci n deseada con las herramientas normales o de Python, por ejemplo
from sys import argv T, h = map(float, argv[1:3]) modelo = argv[3]

Sin embargo, si no damos sucientes argumentos, entonces el programa fracasar . Podemos atrapar una excepa ci n de este tipo con un bloque try. . . except: o
from sys import argv, exit try: T, h = map(float, argv[1:3]) modelo = argv[3] except: print "Sintaxis: python prog.py T h modelo" exit(1)

Es util proveerle al usuario informaci n acerca de la raz n por la cual fracas el programa. Aqu hemos utilizado o o o la funci n exit que viene tambi n en el m dulo sys, para que salga del programa al encontrar un problema, o e o pero eso no es obligatorio podra poner valores por defecto de los par metros en este caso, por ejemplo. a

9.3.

Llamando a otros programas

El m dulo os provee unas herramientas para mandar llamar a otros programas hijos desde un programa o padre1 . La funci n m s util es system, que permite correr un comando a trav s de un nuevo bash; podemos enviar o a e cualquier comando que funciona en bash, en particular podemos correr otros programas. La funci n acepta o una cadena:
from os import system system("ls")

Ahora podemos empezar a hacer cosas interesantes al construir los comandos con la sustituci n de variables. o Por ejemplo, si tenemos un programa prog.py que acepta un argumento de la lnea de comandos, podemos correrlo de manera consecutiva con distintos valores del par metro con a
1 Hoy

en da, se recomienda m s bien el paquete subprocess para esta funcionalidad, pero es m s complicado. a a

9.4. EJEMPLOS
for T in range(10): comando = "python prog.py %g" % T system(comando)

35

Si queremos abrir un programa que se conectar al nuestro y recibir comandos, utilizamos popen para abrir a a un pipe:
from os import popen gp = popen("gnuplot -persist", "w") gp.write("plot sin(x)\n") gp.close()

Una manera f cil de hacer una animaci n es utilizar la terminal de GIF animado en gnuplot. Para utilizar esta a o terminal, es necesario contar con una versi n de gnuplot compilada de manera adecuada, con la librera gd. o En la terminal de GIF animado, cada vez que uno ejecuta un plot, otro cuadro se agrega a la animaci n. Por o ejemplo:
from os import popen from numpy import arange gp = popen("gnuplot", "w") gp.write("set term gif anim\n") gp.write("set out 'sin.gif'\n") # archivo de salida de gnuplot for a in arange(0., 10., 0.1): gp.write("plot sin(x + %g)\n title 'sin(x+ %g)'\n" % (a, a) ) gp.write("set out\n") # cerrar el archivo de salida de gnuplot gp.close()

9.4.

Ejemplos

Veamos algunos ejemplos de lo que podemos hacer utilizando Python para controlar otros programas. La sustituci n de variables juega un papel crucial. o

9.4.1.

A Generando archivos sencillos con L TEX

A Empecemos con una aplicaci n sencilla, en la cual utilizamos Python para crear un archivo de LTEX para una o carta de aceptaci n de un congreso, para la cual necesitamos el nombre del autor y el ttulo del cartel. o A Primero, para generar un archivo de LTEX, necesitamos poder manejar ciertos caracteres especiales en las cadenas. Para hacerlo, podemos poner r al principio de la cadena para formar una cadena raw (crudo); Python autom ticamente la convertir en una cadena normal: a a

s = r"\begin{document}" s print s

Adem s, Python nos permite declarar cadenas con varias lneas, al utilizar tres comillas. As que un archivo de a A LTEX sencillo se puede crear con
codigo_latex = r""" \documentclass{article} \usepackage{mathptmx} % fuente Times \begin{document} <Hola, David! \end{document} """

36

CAPITULO 9. COMUNICANDOSE CON OTROS PROGRAMAS

Ahora tenemos que guardar eso en un archivo, y compilarlo


from os import system archivo = open("temp.tex", "w") archivo.write(codigo_latex) # escribir contenido de variable en archivo archivo.close() comando = "pdflatex temp.tex" # comando para compilar el archivo .tex system(comando) # ejecutar el comando comando = "acroread temp.pdf" system(comando) # ver el archivo que creamos

Ahora est f cil reemplazar el nombre con el contenido de una variable, por ejemplo una que leemos de la lnea a a de comandos, con el siguiente c digo que guardamos como saludo.py: o
from sys import argv, exit try: nombre = argv[1] except: print "Sintaxis: python saludo.py nombre" exit(1) codigo_latex = r""" \documentclass{article} \usepackage{mathptmx} % fuente Times \begin{document} <Hola, %s! \end{document} """ % nombre

Lo guardamos y compilamos como antes. N tese que la sustituci n de variables tambi n se puede utilizar con o o e las cadenas crudas y las con m ltiples lneas. u
A Incluso podramos leer el c digo LTEX desde un archivo. En el archivo ponemos %s etc. donde queremos o sustituir variables. Leemos el contenido del archivo en una cadena, que entonces contendr explcitamente los a %s, y luego hacemos la sustituci n. As, si temp.tex contiene o

\documentclass{article} \usepackage{mathptmx} % fuente Times \begin{document} <Hola, %s! \end{document}

podemos hacer
entrada = open("temp.tex", "r") codigo_latex = entrada.read() # leer todo el contenido en una cadena nombre = "David" codigo_latex = codigo_latex % nombre

En la ultima lnea, reemplazamos el contenido de codigo_latex con el resultado de hacer la sustituci n de o variables.

9.4. EJEMPLOS

37

9.4.2.

Gr cas del comportamiento de un sistema para distintos valores de un par mea a tro

A Ahora veamos un ejemplo m s complicado, tambi n ocupando LTEX, donde crearemos un archivo con vaa e rias guras que retratan el comportamiento de un sistema con distintos valores de un par metro. Esta idea se a tom del excelente libro de Langtangen. Ah se dan varias variaciones sobre el tema, incluyendo c mo generar o o un reporte en HTML.

Lo primero que hay que hacer es generar las guras. Esto se puede hacer por ejemplo con gnuplot, pero aqu emplearemos pylab. Para enfatizar la idea, nuestro sistema ser una gr ca de sin(kx) para distintos k, a a pero basta con reemplazar la gr ca con datos reales. Primero generemos una gr ca: a a
from pylab import * t = arange(-2*pi, 2*pi, 0.1) plot(t, sin(t), '-o') savefig("sin.pdf")

Ahora repitamos eso para generar varias guras:


from pylab import * t = arange(-2*pi, 2*pi, 0.1) for k in range(1, 7): plot(t, sin(k*t), '-o') xlabel("$x$") ylabel("$sin( %dx)$" % k) savefig("sin %d.pdf" % k)

N tese el uso directo de la sustituci n de variables para generar la cadena correspondiente al nombre del archivo o o A al momento de utilizarla. Acord monos que pylab puede ocupar directamente etiquetas hechas con LTEX. e
A Ahora agarremos estas guras y pong moslas en un solo PDF, a trav s de LTEX. Para hacerlo, primero generea e mos el principio del archivo:

latex = r""" \documentclass{article} \usepackage{graphicx} % para incluir figuras \begin{document} \begin{figure} """
A Ahora para cada gura, tenemos que agregar el comando de LTEX para importarla:

for k in range(1, 7): latex += r"\includegraphics[scale=0.4]{sin %d}" % k + "\n"

N tese que es necesario separar el \n para que no aparezca adentro de la cadena cruda. Finalmente hay que o terminar la gura:
latex += "\end{figure}"

Podemos checar que todo pas bien con o


print latex
A Una mejor manera de incluir las guras es utilizando el paquete subfigure de LTEX, que provee una manera bonita de incluir subguras. Despu s de incluirlo con \usepackage{subfigure}, podemos utilizarlo e

38

CAPITULO 9. COMUNICANDOSE CON OTROS PROGRAMAS

adentro de entorno figure como sigue: \subfigure[subpie]{\includegraphics{subfigura}}, donde subpie es el pie de gura para la subgura, y subfigura el archivo. As que podemos poner:
subfigura = r""" \subfigure[$k= %d$] { \includegraphics[scale=0.4]{sin %d} } """ # cada figura se ve a s # Ahora incluir cada figura: for k in range(1, 7): latex += subfigura % (k, k)

Captulo 10

Programaci n orientada a objetos: clases o


En este captulo, veremos uno de los temas m s revolucionarios en materia de programaci n: la programaci n a o o orientada a objetos. Aunque hemos estado utilizando los objetos de manera implcita a trav s del curso, ahora e veremos c mo nosotros podemos denir nuestros propios tipos de objetos nuevos, y para qu sirve. o e

10.1.

La programaci n orientada a objetos: las clases o

Consideremos una situaci n cl sica en el c mputo cientco: un sistema que consiste en cierto n mero de o a o u partculas en 2 dimensiones, que tienen propiedades internas, como una posici n, una velocidad y una masa, y o que se pueden mover con una regla tipo Euler. Para una partcula, podramos denir sus variables simplemente como sigue:
x = y = 0.0 # posicion vx = vy = 1.0 # velocidad

Un paso de Euler de tama o dt se puede implementar con n


dt = 0.1 x += dt * vx; y += dt * vy;

Pero ahora, qu hacemos si necesitamos otra partcula m s? Podramos poner e a


x1 = y1 = x2 = y2 = vx1 = vy1 vx1 = vy1 0.0 0.0 = 1.0 = 1.0

Si las partculas tambi n tienen masas y colores, entonces se vuelve muy tedioso, ya que tenemos que actualizar e todo dos veces para cada propiedad nueva:
m1 = m2 = 0.0; c1 = c2 = 0.0;

Para muchas particulas podramos emplear arreglos (listas, en Python), que reducira el trabajo. Pero ahora podramos imaginarnos que por alguna raz n queremos agregar otra partcula, o incluso duplicar o toda la simulaci n. Entonces tendramos que duplicar a mano todas las variables, cambiando a la vez sus o nombres, lo cual seguramente conducir a introducir errores. a Sin embargo, conceptualmente tenemos muchas variables que est n relacionadas: todas pertenecen a una a partcula. Hasta ahora, no hay manera de expresar esto en el programa. 39

40

CAPITULO 10. PROGRAMACION ORIENTADA A OBJETOS: CLASES

10.2.

La soluci n: objetos, a trav s de clases o e

Lo que queremos hacer, entonces, es reunir todo lo que corresponde a una partcula en un nuevo tipo de objeto, llamado Particula. Luego podremos decir que p1 y p2 son Particulas, o incluso hacer un arreglo (lista) de Particulas. Toda la informaci n que le corresponde a una partcula dada estar contenida adentro del objeto; esta informao a ci n formar parte del objeto no s lo conceptualmente, sino tambi n en la representaci n en el programa. o a o e o Podemos pensar en un objeto, entonces, como un tipo de caja negra, que tiene propiedades internas, y que puede interactuar de alguna manera con el mundo externo. No es necesario saber o entender qu es lo que hay e adentro del objeto para entender c mo funciona. Se puede pensar que corresponde a una caja con palancas, o botones y luces: las palancas y los botones proveen una manera de darle informaci n o instrucciones a la caja, o y las luces dan informaci n de regreso al mundo externo. o Para implementar eso en Python, se declara una clase llamada Particula y se crea una instancia de esta clase, llamada p.
class Particula: x = 0.0 p = Particula() p.x

N tese que p tiene adentro una propiedad, que se llama x. Podemos interpretar p.x como una x que le pertenece o a p. Si ahora hacemos
p2 = Particula() p2.x

entonces tenemos una variable completamente distinta que tambi n se llama x, pero que ahora le pertenece a e p2, que es otro objeto de tipo Particula. De hecho, m s bien podemos pensar que p2.x es una manera de a escribir p2_x, que es como lo hubi ramos podido escribir antes, que tiene la bondad de que ahora tamben e tiene sentido pensar en el conjunto p como un todo. Remarquemos que ya estamos acostumbrados a pensar en cajas de este tipo en matem ticas, al tratar con a vectores, matrices, funciones, etc.

10.3.

M todos de clases e

Hasta ahora, una clase act a simplemente como una caja que contiene datos. Pero objetos no s lo tienen u o informaci n, sino tambi n pueden hacer cosas. Para hacerlo, tambi n se pueden denir funciones llamadas o e e m todos que le pertenecen al objeto. Simplemente se denen las funciones adentro de la declaraci n de la e o clase:
class Particula: x = 0.0 v = 1.0 def mover(self, dt): self.x += self.v*dt p = Particula() print p.x p.mover(0.1) print p.x

10.4. FUNCIONES INICIALIZADORAS

41

N tese que los m todos de las clases siempre llevan un argumento extra, llamado self, que quiere decir o e s mismo. Las variables que pertenecen a la clase, y que se utilizan adentro de estas funciones, llevan self., para indicar que son variables que forman parte de la clase, y no variables globales. Podemos pensar en las variables internas a la clase como variables pseudo-globales, ya que est n accesibles desde cualquier lugar a adentro de la clase.

10.4.

Funciones inicializadoras

Cuando creamos una instancia de un objeto, muchas veces queremos inicializar el objeto al mismo tiempo, es decir pasarle informaci n sobre su estado inicial. En Python, esto se hace a trav s de una funci n inicializadora, o e o como sigue:
class Particula: def __init__(self, xx=0.0, vv=1.0): self.x = xx self.v = vv def mover(self, dt): self.x += self.v*dt p1 = Particula() print p1.x p2 = Particula(2.5, 3.7) print p2.x p1.mover(0.1) p2.mover(0.1) print p1.x, p2.x

N tese que la funci n inicializadora debe llamarse __init__, con dos guiones bajos de cada lado del nombre o o init. Puede tomar argumentos que se utilizan para inicializar las variables de la clase.

10.5.

M todos internos de las clases e

Las clases pueden ocupar varios m todos para proveer un interfaz m s limpio para el usuario. Por ejemplo, al e a poner printp1 en el ultimo ejemplo, sale algo as como
<__main__.Particula instance at 0x2849cb0>

Podemos hacer que salga algo m s util al proveer adentro de la clase una funci n __str__: a o
class Particula: def __init__(self, xx=0.0, vv=1.0): self.x = xx self.v = vv def __str__(self): return "Particula( %g, %g)" % (self.x, self.v) p1 = Particula() print p1

Tambi n podemos denir funciones que permiten que podamos llevar a cabo operaciones aritm ticas etc. con e e objetos de este tipo, es decir, podemos sobrecargar los operadores para que funcionen con nuestro nuevo tipo. Eso es lo que pasa con los array de numpy, por ejemplo. Ejercicio: Haz un objeto para representar a una partcula en 2D. Haz una nube de tales partculas.

42

CAPITULO 10. PROGRAMACION ORIENTADA A OBJETOS: CLASES

10.6.

Herencia

Las clases tambi n pueden formar jerarquas al utilizar la herencia, que quiere decir que una clase es un tipo e de, o subtipo de otro.

Captulo 11

Paquetes para el c mputo cientco en Python o


Este captulo propone dar un breve resumen de algunos de los muchos paquetes disponibles para llevar a cabo distintas tareas de c mputo cientco en Python. o

11.1.

C lculos num ricos con scipy a e

El paquete scipy provee una colecci n de herramientas para llevar a cabo tareas num ricas, como son los sio e guientes subm dulos: funciones especiales (special); integraci n de funciones y de ecuaciones diferenciales o o ordinarias (integrate), optimizaci n y races de funciones (optimize), algebra lineal (linalg), incluyendo o para matrices escasas (sparse), y estadsticas (stats). Veamos algunos ejemplos. Para utilizar las funciones especiales, hacemos
from scipy import special for i in range(5):

special.gamma(3) special.gamma(3.5) x = arange(-2, 2, 0.05) for i in range(5): plot(x, map(special.hermite(i), x))

Para integrar la ecuaci n de Airy (un ejemplo de la documentaci n de scipy) o o d2w zw(z) = 0, dz2 podemos poner
from from y1_0 y0_0 y0 = scipy.integrate import odeint scipy.special import gamma, airy = 1.0/3**(2.0/3.0)/gamma(2.0/3.0) = -1.0/3**(1.0/3.0)/gamma(1.0/3.0) [y0_0, y1_0]

(11.1)

def func(y, t): return [t*y[1],y[0]] def gradiente(y,t):

43

44

CAPITULO 11. PAQUETES PARA EL COMPUTO CIENTIFICO EN PYTHON


return [[0,t],[1,0]]

x = arange(0,4.0, 0.01) t = x ychk = airy(x)[0] y = odeint(func, y0, t) y2 = odeint(func, y0, t, Dfun=gradient) print ychk[:36:6] print y[:36:6,1] print y2[:36:6,1]

En la segunda llamada a odeint, mandamos explcitamente la funci n que calcula la derivada (gradiente) de o f; en la primera llamada, no fue necesario contar con una funci n que calculara eso. o Encontrar races de funciones es m s o menos sencillo: a
def f(x): return x + 2*cos(x) def g(x): out = [x[0]*cos(x[1]) - 4] out.append(x[1]*x[0] - x[1] - 5) return out from scipy.optimize import fsolve x0 = fsolve(func, 0.3) x02 = fsolve(func2, [1, 1])

11.2.

C lculos simb licos con sympy a o

El m dulo sympy provee una colecci n de rutinas para hacer c lculos simb licos. Las variables se tienen que o o a o declarar como tal, y luego se pueden utilizar en expresiones simb licas: o
from sympy import * x, y, z = symbols('xyz') k, m, n = symbols('kmn', integer=True) f = Function("f") x + x (x + y) ** 2 z = _ z.expand() z.subs(x, 1) limit(sin(x) / x, x, 0) limit(1 - 1/x, x, oo) diff(sin(2*x), x) diff(sin(2*x), x, 3) cos(x).series(x, 0, 10) integrate(log(x), x) integrate(sin(x), (x, 0, pi/2))

11.3. MAYAVI2
f(x).diff(x, x) + f(x) dsolve(f(x).diff(x, x) + f(x), f(x)) solve(x**4 - 1, x) pi.evalf(50)

45

11.3. mayavi2
El paquete mayavi2 provee una manera de visualizar conjuntos de datos complejos en 3D. Para utilizarlo de manera interactiva, comenzamos con
ipython -wthread import numpy as np def V(x, y, z): """ A 3D sinusoidal lattice with a parabolic confinement. """ return np.cos(10*x) + np.cos(10*y) + np.cos(10*z) + 2*(x**2 + y**2 + z**2) X, Y, Z = np.mgrid[-2:2:100j, -2:2:100j, -2:2:100j] V(X, Y, Z) from numpy import * from enthought.mayavi import mlab x, y, z = random.rand(3, 10) mlab.points3d(x, y, z) c = random.rand(10) mlab.points3d(x, y, z, color=c) mlab.clf() mlab.contour3d(X, Y, Z, V)

11.4.

Entorno completo: sage

El paquete sage, disponible libremente de la p gina http://www.sagemath.org, pretende proveer una a manera de reemplazar a programas del estilo de Mathematica, al proveer un entorno completo para hacer c lculos matem ticos. Es un entorno que provee un interfaz tipo Python a muchos paquetes libres para hacer a a matem ticas. Adem s, provee un interfaz disponible por el internet para interactuar con los notebooks. a a

You might also like