├── progs ├── 2010-06-14 │ ├── prog.py │ ├── vars.py │ ├── nombres.txt │ ├── llamar.py │ ├── temp.tex │ ├── wl.py │ ├── carta.tex │ ├── correr-wl.py │ ├── usar-popen.py │ ├── simul.py │ └── generar-latex.py ├── 2010-06-02 │ ├── hola.py │ ├── factorial.py │ ├── while.py │ ├── if.py │ ├── numpy_log.py │ ├── intro_log.py │ └── estructuras_control.py ├── 2010-06-07 │ ├── mifunciones.py │ ├── matriz.bin.npy │ ├── tusfunciones.py │ └── matriz.dat ├── 2010-06-09 │ ├── datos.dat │ ├── cuad.pdf │ ├── migraf.py │ ├── animacion.py │ ├── pylab_log.py │ ├── oscilacion.py │ ├── campos_log.py │ ├── campos.py │ └── numpy_log.py ├── 2010-06-04 │ ├── leer.py │ ├── babilon.py │ ├── escribir.py │ ├── esferas.py │ └── estructuras_control.py ├── 2010-06-16 │ ├── clases.py │ ├── sins.tex │ ├── sins.aux │ ├── varias-figuras.py │ ├── mayavi_log.py │ ├── sympy_log.py │ ├── objetos_log.py │ └── sins.log └── 2010-06-11 │ ├── eventos.py │ └── euler.py ├── notas.pdf ├── multiprec.py ├── events.py ├── introduccion.tex ├── ejemplos.tex ├── animaciones-visual.tex ├── paquetes.tex ├── notas.kilepr ├── archivos.tex ├── ecuaciones-diferenciales.py ├── notas.tex ├── clases.tex ├── estructuras-de-control.tex ├── comenzando.tex ├── comunicaciones.tex ├── numpy.tex └── matplotlib.tex /progs/2010-06-14/prog.py: -------------------------------------------------------------------------------- 1 | print "1\n2" 2 | 3 | -------------------------------------------------------------------------------- /progs/2010-06-02/hola.py: -------------------------------------------------------------------------------- 1 | a = 3 2 | if a < 10: 3 | 4 | -------------------------------------------------------------------------------- /progs/2010-06-14/vars.py: -------------------------------------------------------------------------------- 1 | y = 3 2 | z = 1 3 | hola = 10 4 | -------------------------------------------------------------------------------- /notas.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/curso-python/master/notas.pdf -------------------------------------------------------------------------------- /progs/2010-06-07/mifunciones.py: -------------------------------------------------------------------------------- 1 | def f(x): return x 2 | def g(x): return x*x -------------------------------------------------------------------------------- /progs/2010-06-09/datos.dat: -------------------------------------------------------------------------------- 1 | # Un comentario 2 | 1 3 3 | 2 4 4 | 1.5 1 5 | 2 7 6 | -------------------------------------------------------------------------------- /progs/2010-06-09/cuad.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/curso-python/master/progs/2010-06-09/cuad.pdf -------------------------------------------------------------------------------- /progs/2010-06-09/migraf.py: -------------------------------------------------------------------------------- 1 | from pylab import * 2 | 3 | x = arange(10) 4 | plot(x, x*2, 'o') 5 | 6 | show() 7 | -------------------------------------------------------------------------------- /progs/2010-06-07/matriz.bin.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/curso-python/master/progs/2010-06-07/matriz.bin.npy -------------------------------------------------------------------------------- /progs/2010-06-14/nombres.txt: -------------------------------------------------------------------------------- 1 | Barack Obama,Presidencia actual 2 | George Bush,Anterior 3 | Felipe Calderon,De Mexico 4 | -------------------------------------------------------------------------------- /progs/2010-06-02/factorial.py: -------------------------------------------------------------------------------- 1 | resultado = 1 2 | 3 | for i in range(1, 10001): 4 | resultado *= i # equivalente: resultado = resultado * i 5 | 6 | 7 | -------------------------------------------------------------------------------- /progs/2010-06-02/while.py: -------------------------------------------------------------------------------- 1 | a = 1 2 | b = 1 3 | 4 | c = 1 5 | 6 | while c < 1000: 7 | c = a+b 8 | a, b = b, c 9 | print c 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /progs/2010-06-07/tusfunciones.py: -------------------------------------------------------------------------------- 1 | def f(x): 2 | """Funcion que calcula tal 3 | Es super divertido 4 | """ 5 | return x**3 6 | 7 | def g(x): 8 | """Doc de g""" 9 | return f(2*x) -------------------------------------------------------------------------------- /progs/2010-06-14/llamar.py: -------------------------------------------------------------------------------- 1 | #import os 2 | from os import system 3 | from numpy import arange 4 | 5 | for T in arange(0.5, 5, 0.5): 6 | comando = "python simul.py %g" % T 7 | system(comando) 8 | 9 | -------------------------------------------------------------------------------- /progs/2010-06-14/temp.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | \usepackage{mathptmx} 4 | 5 | \begin{document} 6 | 7 | Estimado %s: 8 | 9 | Su cartel titulado ``%s" ha sido aceptado para tal. 10 | 11 | \end{document} -------------------------------------------------------------------------------- /progs/2010-06-14/wl.py: -------------------------------------------------------------------------------- 1 | from sys import argv, exit 2 | from os import system 3 | 4 | #try: 5 | #Emin, Emax, L, traslape = map(int, argv[1:5]) 6 | #exc 7 | 8 | a, b = map(int, argv[1:3]) 9 | 10 | print "[%d, %d]" % (a, b) -------------------------------------------------------------------------------- /progs/2010-06-14/carta.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | \usepackage{mathptmx} 4 | 5 | \begin{document} 6 | 7 | Estimado Felipe Calderon: 8 | 9 | Su cartel titulado ``De Mexico 10 | " ha sido aceptado para tal. 11 | 12 | \end{document} -------------------------------------------------------------------------------- /progs/2010-06-02/if.py: -------------------------------------------------------------------------------- 1 | # a = 3 2 | 3 | a = float(raw_input("Dame valor de a: ")) 4 | 5 | if a < 0: 6 | print "a neg" 7 | a = -a 8 | print "otra linea mas" 9 | 10 | elif a == 0: 11 | print "a = 0" 12 | 13 | else: 14 | print "a pos" 15 | -------------------------------------------------------------------------------- /progs/2010-06-09/animacion.py: -------------------------------------------------------------------------------- 1 | from pylab import * 2 | 3 | x = arange(10) 4 | y = x*x 5 | 6 | ion() #interactive "on" 7 | 8 | p, = plot(x,y) 9 | #show() 10 | hold(False) 11 | 12 | for a in arange(0, 10, 0.1): 13 | x = arange(10) + a 14 | #plot(x, y) 15 | p.set_xdata(x) 16 | draw() 17 | -------------------------------------------------------------------------------- /progs/2010-06-04/leer.py: -------------------------------------------------------------------------------- 1 | entrada = open("distancia.dat", "r") # read = leer 2 | 3 | #lineas = entrada.readlines() 4 | 5 | #for linea in lineas: 6 | #datos = [] 7 | #for palabra in linea.split(): 8 | #datos.append( float(palabra) ) 9 | #print datos 10 | 11 | for linea in entrada: 12 | datos = map(float, linea.split() ) 13 | print datos 14 | 15 | -------------------------------------------------------------------------------- /multiprec.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from mpmath import * 3 | from sys import argv 4 | 5 | precision = int(argv[1]) 6 | 7 | mp.dps = precision # num de digitos decimales 8 | 9 | y = mpf('25.0') 10 | x = mpf('0.1') 11 | 12 | for i in range(20): 13 | x = 0.5*(x + (y/x)) 14 | #print x, 15 | diff = log10(x - 5.0, 10) 16 | #nprint (log10(x - 5.0), 10) 17 | -------------------------------------------------------------------------------- /progs/2010-06-04/babilon.py: -------------------------------------------------------------------------------- 1 | from mpmath import * # PRECISION ARBITRARIA 2 | 3 | # from math import * PARA PRECISION NORMAL 4 | 5 | #y = 25. 6 | #x0 = 0.1 7 | 8 | #x = x0 9 | 10 | mp.dps = 1000 11 | 12 | y = mpf('25.0') 13 | x = mpf('10000') 14 | 15 | 16 | for i in range(20): 17 | x_prima = 0.5 * ( x + (y / x) ) 18 | #print x_prima 19 | print i, 20 | nprint(log10(x - 5.), 10) 21 | x = x_prima -------------------------------------------------------------------------------- /progs/2010-06-14/correr-wl.py: -------------------------------------------------------------------------------- 1 | from sys import argv, exit 2 | from os import system 3 | 4 | try: 5 | Emin, Emax, L, traslape = map(int, argv[1:5]) 6 | except: 7 | print "Sintaxis: python correr-wl.py Emin Emax L traslape" 8 | exit(1) 9 | 10 | abajo = Emin 11 | 12 | while abajo < Emax: 13 | arriba = abajo + L 14 | comando = "python wl.py %d %d" % (abajo, arriba) 15 | system(comando) 16 | 17 | abajo = arriba - traslape -------------------------------------------------------------------------------- /progs/2010-06-14/usar-popen.py: -------------------------------------------------------------------------------- 1 | # Python Scripting for Computational Science", 3a edicion 2008, Springer, 2 | # H.P. Langtangen 3 | 4 | from os import popen 5 | from numpy import arange 6 | # mejor: modulo 'subprocess' 7 | 8 | gp = popen("gnuplot", "w") 9 | 10 | gp.write("set term gif anim\n") 11 | gp.write("set out 'sin.gif' \n ") 12 | for a in arange(0.1, 10, 0.1): 13 | gp.write("plot sin(x+%g)\n" % a) 14 | 15 | gp.write("set out") 16 | 17 | gp.close() -------------------------------------------------------------------------------- /progs/2010-06-14/simul.py: -------------------------------------------------------------------------------- 1 | #T = raw_input("Dame la temp: ") 2 | #h = raw_input("Dame el campo: ") 3 | 4 | ##print "T = ", T, "; h = ", h 5 | 6 | from sys import argv, exit 7 | 8 | #print "Argumentos: ", argv 9 | 10 | try: 11 | T = float(argv[1]) 12 | #h = float(argv[2]) 13 | #print T, h 14 | #modelo = argv[3] 15 | 16 | except: 17 | #print "OYE! Faltan args" 18 | #exit(1) 19 | T = 1 20 | h = 1 21 | modelo = 'ising' 22 | 23 | print "simul", 2*T 24 | #, h, modelo -------------------------------------------------------------------------------- /progs/2010-06-09/pylab_log.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'pylab_log.py', 'pylab': 1}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | _ip.magic("logstart pylab_log.py") 8 | 9 | x = arange(10) 10 | x 11 | y = x*x 12 | y 13 | plot(x, y) 14 | -------------------------------------------------------------------------------- /progs/2010-06-16/clases.py: -------------------------------------------------------------------------------- 1 | class Particula: 2 | def __init__(self, xx=0.0, vv=1.0): 3 | print "Estoy adentro de __init__" 4 | self.x = xx 5 | self.v = vv 6 | 7 | def mover(self, dt): 8 | self.x += dt * self.v 9 | 10 | def mover_n_veces(self, n, dt): 11 | for i in range(n): 12 | self.mover(dt) 13 | 14 | def __str__(self): 15 | return "Particula(%g, %g)" % (self.x, self.v) 16 | 17 | def __add__(self, otra): 18 | return Particula(self.x + otra.x, self.v + otra.v) 19 | 20 | -------------------------------------------------------------------------------- /progs/2010-06-04/escribir.py: -------------------------------------------------------------------------------- 1 | salida = open("hola.dat", "w") # write = escribir 2 | 3 | salida.write("Hola") 4 | 5 | a =3 6 | salida.write( "a = " + str(a) ) 7 | 8 | b = -7.6e-1 9 | 10 | salida.write("%d %g " % (a, b) ) 11 | 12 | salida.close() 13 | 14 | T = 2.5 15 | h = 0.1 16 | L = 200 17 | 18 | for T in [0.1, 0.2, 2.5, 2.6]: 19 | nombre = "ising_T%g_h%g_L%d.dat" % (T, h, L) 20 | salida = open(nombre, "w") 21 | salida.write("# Datos de Ising") 22 | salida.close() 23 | 24 | #ising_T2.5_h0.1_L200.dat 25 | 26 | -------------------------------------------------------------------------------- /progs/2010-06-16/sins.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass{article} 3 | \usepackage{graphicx} 4 | \usepackage{subfigure} 5 | \begin{document} 6 | \begin{figure} 7 | \subfigure[$i=1$]{ 8 | \includegraphics[scale=0.3]{sin1}} 9 | \subfigure[$i=2$]{ 10 | \includegraphics[scale=0.3]{sin2}} 11 | \subfigure[$i=3$]{ 12 | \includegraphics[scale=0.3]{sin3}} 13 | \subfigure[$i=4$]{ 14 | \includegraphics[scale=0.3]{sin4}} 15 | \subfigure[$i=5$]{ 16 | \includegraphics[scale=0.3]{sin5}} 17 | \subfigure[$i=6$]{ 18 | \includegraphics[scale=0.3]{sin6}} 19 | 20 | \end{figure} 21 | \end{document} -------------------------------------------------------------------------------- /progs/2010-06-16/sins.aux: -------------------------------------------------------------------------------- 1 | \relax 2 | \@writefile{lof}{\contentsline {subfigure}{\numberline{(a)}{\ignorespaces {$i=1$}}}{1}} 3 | \@writefile{lof}{\contentsline {subfigure}{\numberline{(b)}{\ignorespaces {$i=2$}}}{1}} 4 | \@writefile{lof}{\contentsline {subfigure}{\numberline{(c)}{\ignorespaces {$i=3$}}}{1}} 5 | \@writefile{lof}{\contentsline {subfigure}{\numberline{(d)}{\ignorespaces {$i=4$}}}{1}} 6 | \@writefile{lof}{\contentsline {subfigure}{\numberline{(e)}{\ignorespaces {$i=5$}}}{1}} 7 | \@writefile{lof}{\contentsline {subfigure}{\numberline{(f)}{\ignorespaces {$i=6$}}}{1}} 8 | -------------------------------------------------------------------------------- /events.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from pylab import * 3 | 4 | def teclado(event): 5 | #print event.key 6 | #print event.xdata 7 | #print event.ydata 8 | print "Se tecleó %s en la posicion (%g, %g)" % (event.key, event.xdata, event.ydata) 9 | 10 | def mouse(event): 11 | if event.button != 1: 12 | return 13 | x,y = event.xdata, event.ydata 14 | print "Se oprimió el botón izquierdo en (%g, %g)" % (x, y) 15 | 16 | x = arange(10) 17 | y = x*x 18 | p, = plot(x, y) 19 | 20 | show() 21 | 22 | connect('button_press_event', mouse) 23 | connect('key_press_event', teclado) -------------------------------------------------------------------------------- /progs/2010-06-09/oscilacion.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def f(t): 4 | c = cos(2 * pi * t) 5 | e = exp(-t) 6 | return c*e 7 | 8 | t = arange(0, 5, 0.1) 9 | 10 | subplot(221) # renglones, columnas, cual de los reng*col 11 | l = plot(t, f(t)) 12 | grid(True) 13 | ylabel('Amortiguada') 14 | 15 | subplot(222) 16 | plot(t, cos(2*pi*t)) 17 | grid(True) 18 | ylabel('No amortiguada') 19 | 20 | subplot(223) # renglones, columnas, cual de los reng*col 21 | l = plot(t, f(t)) 22 | grid(True) 23 | ylabel('Amortiguada') 24 | 25 | subplot(224) 26 | plot(t, cos(2*pi*t)) 27 | grid(True) 28 | ylabel('No amortiguada') 29 | -------------------------------------------------------------------------------- /progs/2010-06-04/esferas.py: -------------------------------------------------------------------------------- 1 | from visual import * 2 | 3 | lista_esferas = [] 4 | 5 | N = 100 6 | 7 | for i in range(N): 8 | s = sphere() 9 | lista_esferas.append( s ) 10 | 11 | i = 0 12 | for esfera in lista_esferas: 13 | #esfera.pos= cos(2.*pi*float(i)/N), sin(2*pi*float(i)/N), 0 14 | 15 | esfera.vel = vector(cos(2.*pi*float(i)/N), sin(2*pi*float(i)/N), 0) 16 | esfera.radius = 0.2 17 | #esfera.vel = esfera.pos 18 | i += 1 19 | 20 | dt = 0.1 21 | for t in range(1000): 22 | rate(100) 23 | for esfera in lista_esferas: 24 | esfera.pos += dt*esfera.vel 25 | 26 | x 27 | 28 | #s = sphere() 29 | #lista_esferas.append( sphere() ) 30 | 31 | -------------------------------------------------------------------------------- /progs/2010-06-11/eventos.py: -------------------------------------------------------------------------------- 1 | from pylab import * 2 | 3 | def mouse(evento): 4 | print "Boton ", evento.button 5 | print "en el lugar ", evento.xdata, evento.ydata 6 | 7 | x, y = evento.xdata, evento.ydata 8 | #plot(x, y, 'o') 9 | #axis([-5, 5, -5, 5]) 10 | 11 | datos_x.append(x) 12 | datos_y.append(y) 13 | 14 | p.set_xdata(datos_x) 15 | p.set_ydata(datos_y) 16 | 17 | draw() 18 | 19 | def teclado(evento): 20 | print "Tecla ", evento.key 21 | print "en el lugar ", evento.xdata, evento.ydata 22 | 23 | if evento.key == "r": 24 | datos_x.pop() 25 | datos_y.pop() 26 | 27 | p.set_xdata(datos_x) 28 | p.set_ydata(datos_y) 29 | 30 | draw() 31 | 32 | 33 | datos_x = [0] 34 | datos_y = [0] 35 | 36 | p, = plot(datos_x, datos_y, 'o') 37 | axis([-5, 5, -5, 5]) 38 | 39 | show() 40 | 41 | connect('button_press_event', mouse) 42 | connect('key_press_event', teclado) 43 | -------------------------------------------------------------------------------- /progs/2010-06-16/varias-figuras.py: -------------------------------------------------------------------------------- 1 | 2 | from pylab import plot, xlabel, ylabel, savefig, clf, sin 3 | from numpy import arange 4 | from os import system 5 | 6 | t = arange(-6.3, 6.3, 0.1) 7 | 8 | for i in range(1, 7): 9 | print "i = ", i 10 | clf() 11 | plot(t, sin(i*t)) 12 | xlabel('$x$') 13 | ylabel('$\sin(%dx)$' % i) 14 | 15 | savefig("sin%d.pdf" % i) 16 | 17 | latex = r""" 18 | \documentclass{article} 19 | \usepackage{graphicx} 20 | \usepackage{subfigure} 21 | \begin{document} 22 | \begin{figure} 23 | """ 24 | 25 | for i in range(1, 7): 26 | latex += r"""\subfigure[$i=%d$]{ 27 | \includegraphics[scale=0.3]{sin%d}"""% (i, i) + "}\n" 28 | 29 | latex += r""" 30 | \end{figure} 31 | \end{document}""" 32 | 33 | salida = open("sins.tex", "w") 34 | salida.write(latex) 35 | salida.close() 36 | 37 | comando = "pdflatex sins" 38 | system(comando) 39 | 40 | comando = "acroread sins.pdf" 41 | system(comando) -------------------------------------------------------------------------------- /progs/2010-06-14/generar-latex.py: -------------------------------------------------------------------------------- 1 | from os import system 2 | from sys import exit, argv 3 | 4 | #try: 5 | #nombre, titulo = argv[1:3] 6 | 7 | #except: 8 | #print "Sintaxis: python generar-carta.py nombre" 9 | #exit(1) 10 | 11 | 12 | nombre_archivo = open("nombres.txt") 13 | for linea in nombre_archivo: 14 | nombre, titulo = linea.split(",") 15 | 16 | entrada = open("temp.tex", "r") 17 | latex = entrada.read() 18 | latex = latex % (nombre, titulo) 19 | 20 | #latex = r""" 21 | #\documentclass{article} 22 | 23 | #\begin{document} 24 | 25 | #Estimado %s: 26 | 27 | #Su cartel titulado "%s" ha sido aceptado para tal. 28 | 29 | #\end{document} 30 | #""" % (nombre, titulo) 31 | 32 | 33 | salida = open("carta.tex", "w") 34 | salida.write(latex) 35 | salida.close() 36 | 37 | comando = "pdflatex carta" 38 | system(comando) 39 | 40 | comando = """cp carta.pdf "%s".pdf""" % nombre 41 | system(comando) 42 | #comando = "okular carta.pdf" 43 | #system(comando) 44 | 45 | -------------------------------------------------------------------------------- /progs/2010-06-04/estructuras_control.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'estructuras_control.py'}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | _ip.magic("run escribir.py ") 8 | _ip.system("less hola.dat ") 9 | _ip.magic("run escribir.py ") 10 | str(a) 11 | "a = " + str(a) 12 | _ip.magic("run escribir.py ") 13 | a = 3 14 | b = -7.6e-1 15 | s = "%d %g " % (a, b) 16 | s 17 | 18 | a = 10 19 | s 20 | s = "%d %g " % (a, b) 21 | s 22 | s = "%dHola %g " % (a, b) 23 | s 24 | 25 | s = "%d\t%g " % (a, b) 26 | s 27 | print(s) 28 | _ip.magic("run escribir.py ") 29 | _ip.magic("logstart estructuras_control.py") 30 | 31 | _ip.magic("run escribir.py ") 32 | _ip.magic("run escribir.py ") 33 | _ip.magic("run escribir.py ") 34 | _ip.system("less ising_T2.5_h0.1_L200.dat ") 35 | _ip.magic("run escribir.py ") 36 | _ip.system("ls -F ") 37 | -------------------------------------------------------------------------------- /progs/2010-06-16/mayavi_log.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'mayavi_log.py', 'wthread': 1}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | _ip.magic("logstart mayavi_log.py") 8 | 9 | _ip.magic("logstart mayavi_log.py") 10 | z.series (x, 0, 10) 11 | x,y, z = random.rand(3, 10) 12 | from numpy import * 13 | from numpy import *A 14 | from numpy import *AA 15 | x,y, z = random.rand(3, 10) 16 | c = random.rand() 17 | from enthought.mayavi import mlab 18 | mlab.points3d(x, y, z, c) 19 | x 20 | y 21 | z 22 | c 23 | c = random.rand(10) 24 | mlab.points3d(x, y, z, c) 25 | clf() 26 | c 27 | def V(x,y,z): 28 | return cos( 29 | def V(x,y,z): 30 | return cos(10*x) + cos(10*y) + cos(10*z) + 2*(x**2+y**2+z**2) 31 | X, Y, Z = mgrid[-2:2:100j, -2:2:100j, -2:2:100j] 32 | X 33 | V(X,Y,Z) 34 | mlab.clf() 35 | mlab.contour3d(X, Y, Z, V) 36 | -------------------------------------------------------------------------------- /progs/2010-06-09/campos_log.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'campos_log.py', 'pylab': 1}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | _ip.magic("logstart campos_log.py") 8 | 9 | _ip.magic("run campos") 10 | _ip.magic("run -i campos") 11 | show)( 12 | show() 13 | _ip.magic("run -i campos") 14 | clf() 15 | _ip.magic("run -i campos") 16 | show() 17 | _ip.magic("run campos") 18 | clf() 19 | _ip.magic("run campos") 20 | show() 21 | clf() 22 | _ip.magic("run campos") 23 | show() 24 | _ip.magic("run campos") 25 | clf() 26 | clf() 27 | _ip.magic("run campos") 28 | show() 29 | clf() 30 | _ip.magic("run campos") 31 | show() 32 | _ip.magic("run campos") 33 | show() 34 | clf() 35 | _ip.magic("run campos") 36 | show() 37 | _ip.magic("run campos") 38 | clf() 39 | show() 40 | clf() 41 | _ip.magic("run campos") 42 | show() 43 | clf() 44 | figure(figsize(8,8)) 45 | figure(figsize=(8,8)) 46 | clf() 47 | _ip.magic("run campos") 48 | show() 49 | clf() 50 | _ip.magic("run campos") 51 | show() 52 | clf() 53 | _ip.magic("run campos") 54 | show() 55 | #?quiver 56 | clf)( 57 | clf() 58 | _ip.magic("run campos") 59 | show() 60 | #?quiver 61 | -------------------------------------------------------------------------------- /progs/2010-06-16/sympy_log.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'sympy_log.py', 'pylab': 1}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | _ip.magic("logstart sympy_log.py") 8 | 9 | from sympy import * 10 | x 11 | x, y, z = symbols('xyz') 12 | x 13 | x = symbols('y') 14 | x 15 | x, y, z = symbols('xyz') 16 | x 17 | x + x 18 | #?symbols 19 | jamon = symbols('jamon') 20 | jamon 21 | jamon = symbols('jamon ') 22 | jamon 23 | jamon + jamon 24 | x 25 | y 26 | z 27 | z = x + y 28 | z = z*z 29 | z 30 | z.expand () 31 | z = x*x + 2*x + 1 32 | z 33 | z = (1+x)**2 34 | z = x*x + 2*x + 1 35 | z == (1+x)**2 36 | (1+x)**2 37 | z == ( (1+x)**2 ).expand() 38 | z 39 | z.coeff (x**2) 40 | z.subs(x, 1) 41 | limit(sin(x) / x, x, 0) 42 | limit(2 - 1/ x, x, 0) 43 | oo 44 | limit(2 - 1/x, x, oo) 45 | diff(sin(2*x), x) 46 | diff(sin(2*x), x, 3) 47 | cos(x).series(x, 0, 10) 48 | z = cos(x) + sin(x) 49 | z.series (x, 0, 10) 50 | (cos(x) + sin(x)).series() 51 | (cos(x) + sin(x)).series(x, 10) 52 | #?z.series 53 | #?normal 54 | integrate(log(x), x) 55 | x 56 | x.__repr__ 57 | #?x.__repr__ 58 | x.__repr__() 59 | x.__str__() 60 | type(x) 61 | #?x.__add__? 62 | -------------------------------------------------------------------------------- /progs/2010-06-11/euler.py: -------------------------------------------------------------------------------- 1 | 2 | #from numpy import * 3 | from pylab import * 4 | 5 | def f(x): 6 | return -x 7 | 8 | #x0 = 10 9 | 10 | def harmonico(xvec): 11 | x, y = xvec 12 | return array([y, -x]) 13 | 14 | def pendulo(xvec): 15 | x, y = xvec 16 | return array([y, -sin(x)]) 17 | 18 | 19 | def euler(t, x, dt, f): 20 | return x + f(x) * dt 21 | 22 | def rk2(t, x, dt, f): 23 | k1 = f(x) 24 | k2 = f(x + dt * k1/2.) 25 | return x + dt * k2 26 | 27 | def mouse(evento): 28 | x0, y0 = evento.xdata, evento.ydata 29 | 30 | t, x = integrar([x0, y0], 0., 10., 0.1, pendulo, rk2) 31 | #t2, x2 = integrar(10, 0., 10., 0.1, f, rk2) 32 | x = array(x) 33 | #plot(x, 'o') 34 | plot(x[:,0], x[:,1], 'o') 35 | 36 | 37 | def integrar(x0, t0, tf, dt, f, metodo): 38 | 39 | x = x0 40 | t = t0 41 | 42 | dt = 0.1 43 | 44 | datos_t = [t0] 45 | datos_x = [x0] 46 | 47 | 48 | #f = harmonico 49 | 50 | while t < tf: 51 | 52 | x_nuevo = metodo(t, x, dt, f) 53 | t += dt 54 | x = x_nuevo 55 | 56 | datos_t.append(t) 57 | datos_x.append(x) 58 | 59 | return datos_t, datos_x 60 | 61 | 62 | #metodos = [euler, rk2] 63 | metodos = [rk2] 64 | 65 | for metodo in metodos: 66 | t, x = integrar([1,0], 0., 10., 0.1, pendulo, metodo) 67 | #t2, x2 = integrar(10, 0., 10., 0.1, f, rk2) 68 | x = array(x) 69 | #plot(x, 'o') 70 | plot(x[:,0], x[:,1], 'o') 71 | 72 | connect('button_press_event', mouse) 73 | -------------------------------------------------------------------------------- /progs/2010-06-02/numpy_log.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'numpy_log.py'}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | _ip.magic("logstart numpy_log.py") 8 | 9 | from numpy import *( 10 | from numpy import * 11 | who 12 | #?who 13 | _ip.magic("whos ") 14 | who 15 | _ip.magic("who ") 16 | v = [1, 2, 3] 17 | type(v) 18 | v = array( [1, 2, 3] ) 19 | v 20 | v + v 21 | #?v.conjugate 22 | v 23 | v.conjugate () 24 | 2 * v 25 | v * v 26 | dot(v, v) 27 | #?dot 28 | v[2] 29 | cross (v,v) 30 | sin(v) 31 | v + [1,2,3] 32 | M = array( [ [2, 1], [1, 1] ) 33 | M = array( [ [2, 1], [1, 1] ] ) 34 | M 35 | M = array( [ [2, 1], [5\, 1] ] ) 36 | M = array( [ [2, 1], [5, 1] ] ) 37 | M 38 | M.transpose 39 | M.transpose() 40 | M.T 41 | #?M.T 42 | r_ (1,2,3) 43 | r_ [1,2,3] 44 | c_ [1,2,3] 45 | print(_) 46 | a 47 | v 48 | a 49 | v 50 | list(v) 51 | sqrt(dot(v,v)) 52 | linalg.norm (v) 53 | linalg.norm (v) 54 | linalg.eig(M) 55 | fromfunction(?\) 56 | #?fromfunction 57 | M 58 | w 59 | w = r_[1,2] 60 | dot(M, w) 61 | M * M 62 | M 63 | dot(M, M) 64 | a = array([1,2,3]) 65 | dot(M, a) 66 | a = array([1,2]) 67 | dot(M, a) 68 | a = c_[1,2] 69 | dot(M, a) 70 | a 71 | a 72 | dot(a, r_[1,2]) 73 | dot(r_[1,2], a) 74 | outer(r_[1,2], r_[3,4]) 75 | #?c_ 76 | -------------------------------------------------------------------------------- /progs/2010-06-09/campos.py: -------------------------------------------------------------------------------- 1 | from pylab import * 2 | 3 | def calcular_campo(x, y, q, malla_X, malla_Y): 4 | """Calcular campo de una carga q ubicada en (x,y), 5 | en la malla (malla_X, malla_Y) 6 | """ 7 | 8 | #desp = array([X-x, Y-y]) 9 | desp_x = malla_X - x # cpte x del desplazamiento de cada punto de la malla 10 | desp_y = malla_Y - y # cpte x del desplazamiento de cada punto de la malla 11 | 12 | R = sqrt(desp_x*desp_x + desp_y*desp_y) 13 | 14 | Ex = q * desp_x / (R**3) 15 | Ey = q * desp_y / (R**3) 16 | 17 | V = q / R 18 | 19 | #distancia = sqrt(dot(desp, desp)) 20 | #E = q * desp / (distancia**3) 21 | 22 | return (Ex, Ey, V) 23 | 24 | 25 | def teclado(evento): 26 | if evento.key == "q": 27 | cargacarga = raw_input("Dame la carga: ") 28 | 29 | a = linspace(-5, 5, 21) 30 | b = linspace(-5, 5, 21) 31 | 32 | X,Y = meshgrid(a, b) 33 | 34 | x, y = 1.5, 0.5 35 | 36 | cargas = [ [1.5, 1.5, 1], [-1.5, -1.5, -1] ] 37 | 38 | Ex_total = zeros( X.shape, dtype='float') 39 | Ey_total = zeros( X.shape, dtype='float') 40 | V_total = zeros( X.shape, dtype='float') 41 | 42 | for carga in cargas: 43 | x, y, q = carga 44 | 45 | Ex, Ey, V = calcular_campo(x, y, q, X, Y) 46 | 47 | Ex_total += Ex 48 | Ey_total += Ey 49 | V_total += V 50 | 51 | 52 | norm = sqrt(Ex_total*Ex_total + Ey_total*Ey_total) 53 | Ex_total /= norm 54 | Ey_total /= norm 55 | 56 | #Ex = where(Ex < 1, Ex, 1) 57 | #Ey = where(Ey < 1, Ey, 1) 58 | 59 | quiver(X, Y, Ex_total, Ey_total, norm, pivot='middle') 60 | 61 | connect('key_press_event', teclado) 62 | 63 | show() 64 | -------------------------------------------------------------------------------- /introduccion.tex: -------------------------------------------------------------------------------- 1 | \chapter{>Qué es Python?} 2 | 3 | Python es un lenguaje de programación que surgió en 1990. Desde entonces se ha desarrollado enormemente, para volverse un lenguaje de programación 4 | moderno, y uno de los más utilizados en el mundo. 5 | 6 | Python es un lenguaje \emph{interpretado} --no es necesario compilar constantemente cada programa, si no se puede utilizar de manera interactiva. 7 | Por lo tanto, es una herramienta idónea para llevar a cabo tareas de cómputo científico, tales como análisis de datos, graficación de resultados, y exploración de problemas. En este sentido, se puede comparar con programas comerciales tales como Matlab. También hay paquetes que permiten llevar a cabo cálculos simbólicos a través de Python, de los cuales destaca \texttt{sage} (\url{www.sagemath.org}), por lo cual también se puede considerar como competidor de Mathematica y Maple. 8 | 9 | Python viene con una filosofía de ``baterías 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 científico hasta la manipulación de páginas web. Por lo tanto, Python es un lenguaje sumamente versátil. 10 | 11 | Cabe enfatizar que se suele encontrar Python fácil de aprenderse y de utilizarse. Por lo tanto, considero que Python es también el lenguaje idóneo para la enseñanza del cómputo científico en la Facultad de Ciencias, un campo que se ha vuelto de suma importancia. 12 | 13 | \section{Meta del curso} 14 | La meta principal de este curso es la de enseñar las técnicas básicas de Python en el contexto del cómputo científico, y en particular de la física computacional, 15 | con un fin de actualización docente en la Facultad de Ciencias. -------------------------------------------------------------------------------- /progs/2010-06-02/intro_log.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'intro_log.py'}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | 2 8 | 2+ 2 9 | 2 + (17 * 16.5) 10 | 2 ** 2 11 | 2 ** 2 ** 2 12 | 2 ** 2 ** 2 ** 2 13 | 2 ** _ 14 | 15 | 2 ** _ 16 | a = 3\ 17 | a 18 | 2 *( 19 | a 20 | 2*a 21 | j 22 | 1j 23 | 1 + 3j 24 | a = 1 + 3j 25 | a * a 26 | 1j * 1j 27 | _ip.magic("logstart intro_log.py") 28 | 29 | 1 / 2 30 | 3 2/ 31 | 3 / 2 32 | 5 / 2\ 33 | 5 / 2. 34 | a = raw_input ("Dame el valor de a") 35 | a 36 | print("El cuadrado de a es ", a) 37 | a 38 | 2*a 39 | int(a) 40 | float(a) 41 | a = float ( raw_input ("Dame el valor de a") ) 42 | a 43 | l = [3, 4, 5] 44 | l 45 | print(l) 46 | l[0] 47 | l[1] 48 | l[2] 49 | l[3] 50 | _ip.magic("pdb ") 51 | _ip.magic("pdb off") 52 | l 53 | l[0] = 27 54 | l 55 | l[3] = 10 56 | l 57 | l.append (10) 58 | l 59 | l.pop() 60 | l 61 | l 62 | l.sort() 63 | l 64 | l.sort 65 | l 66 | dir(l) 67 | type(l) 68 | l 69 | l.sort 70 | #?l.sort 71 | l.sort(reverse = True) 72 | l 73 | ordenar = l.sort 74 | ordenar 75 | ordenar() 76 | l 77 | l.size 78 | #?len 79 | len(l) 80 | l = [1,2,3][ 81 | l = [1,2,3] 82 | l2 = [3,4,5] 83 | l + l2 84 | _ 85 | _.sort() 86 | _ 87 | nuevo = l + l2 88 | nuevo 89 | nuevo.sort(reverse = True) 90 | nuevo 91 | variables_cuyos_nojmbres_largos = 3 92 | l 93 | l + l 94 | (l + l).sort)( 95 | (l + l).sort() 96 | nuevo = (l + l).sort() 97 | nuevo 98 | nuevo 99 | nuevo = l + l 100 | nuevo 101 | nuevo.sort() 102 | nuevo = l + l; nuevo.sort() 103 | nuevo 104 | 3, 5 105 | a = (3,5) 106 | a 107 | a[0] 108 | a[0] = 3 109 | a, b = 3, 5 110 | a 111 | b 112 | a, b, c, d, e = 1, 2, 3, 4, -17 113 | e 114 | e 115 | sin(a) 116 | from math import * 117 | sin 118 | sin(a) 119 | _ip.magic("who ") 120 | sqrt(4) 121 | l 122 | sin(l) 123 | -------------------------------------------------------------------------------- /progs/2010-06-07/matriz.dat: -------------------------------------------------------------------------------- 1 | 0.000000000000000000e+00 1.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00 4.000000000000000000e+00 5.000000000000000000e+00 6.000000000000000000e+00 7.000000000000000000e+00 8.000000000000000000e+00 9.000000000000000000e+00 2 | 1.000000000000000000e+01 1.200000000000000000e+02 1.200000000000000000e+02 1.200000000000000000e+02 1.200000000000000000e+02 1.500000000000000000e+01 1.600000000000000000e+01 1.700000000000000000e+01 1.800000000000000000e+01 1.900000000000000000e+01 3 | 2.000000000000000000e+01 1.200000000000000000e+02 1.200000000000000000e+02 1.200000000000000000e+02 1.200000000000000000e+02 2.500000000000000000e+01 2.600000000000000000e+01 2.700000000000000000e+01 2.800000000000000000e+01 2.900000000000000000e+01 4 | 3.000000000000000000e+01 1.200000000000000000e+02 1.200000000000000000e+02 1.200000000000000000e+02 1.200000000000000000e+02 3.500000000000000000e+01 3.600000000000000000e+01 3.700000000000000000e+01 3.800000000000000000e+01 3.900000000000000000e+01 5 | 4.000000000000000000e+01 1.200000000000000000e+02 1.200000000000000000e+02 1.200000000000000000e+02 1.200000000000000000e+02 4.500000000000000000e+01 4.600000000000000000e+01 4.700000000000000000e+01 4.800000000000000000e+01 4.900000000000000000e+01 6 | 5.000000000000000000e+01 5.100000000000000000e+01 5.200000000000000000e+01 5.300000000000000000e+01 5.400000000000000000e+01 5.500000000000000000e+01 5.600000000000000000e+01 5.700000000000000000e+01 5.800000000000000000e+01 5.900000000000000000e+01 7 | 6.000000000000000000e+01 6.100000000000000000e+01 6.200000000000000000e+01 6.300000000000000000e+01 6.400000000000000000e+01 6.500000000000000000e+01 6.600000000000000000e+01 6.700000000000000000e+01 6.800000000000000000e+01 6.900000000000000000e+01 8 | 7.000000000000000000e+01 7.100000000000000000e+01 7.200000000000000000e+01 7.300000000000000000e+01 7.400000000000000000e+01 7.500000000000000000e+01 7.600000000000000000e+01 7.700000000000000000e+01 7.800000000000000000e+01 7.900000000000000000e+01 9 | 8.000000000000000000e+01 8.100000000000000000e+01 8.200000000000000000e+01 8.300000000000000000e+01 8.400000000000000000e+01 8.500000000000000000e+01 8.600000000000000000e+01 8.700000000000000000e+01 8.800000000000000000e+01 8.900000000000000000e+01 10 | 9.000000000000000000e+01 9.100000000000000000e+01 9.200000000000000000e+01 9.300000000000000000e+01 9.400000000000000000e+01 9.500000000000000000e+01 9.600000000000000000e+01 9.700000000000000000e+01 9.800000000000000000e+01 9.900000000000000000e+01 11 | -------------------------------------------------------------------------------- /ejemplos.tex: -------------------------------------------------------------------------------- 1 | \chapter{Ejemplos de cálculos y visualizaciones} 2 | 3 | \section{Integración de ecuaciones diferenciales ordinarias} 4 | 5 | Veamos unas rutinas y herramientas para integrar ecuaciones diferenciales. Ocuparemos las técnicas básicas que se ven en el curso de Física Computacional --los métodos de Euler y Runge--Kutta. 6 | 7 | La ecuación que resolveremos es 8 | \begin{equation} 9 | \dot{\x} = \f(\x). 10 | \end{equation} 11 | Recordemos que eso es una notación para decir que 12 | \begin{equation} 13 | \dot{\x}(t) = \f(\x(t)). 14 | \end{equation} 15 | Es decir, si estamos en el punto $\x(t)$ al tiempo $t$, entonces la derivada instantánea en este momento y este punto del espacio fase está dada por $\f(\x(t))$. 16 | 17 | Para resolver esta ecuación en la computadora, es necesario discretizarla de una manera u otra. 18 | La manera más sencilla para hacerlo es discretizando el tiempo en pasos iguales de tamaño $\delta t$ y aproximando la derivada por una diferencia finita, o sea expandiendo en una serie de Taylor, lo cual da 19 | \begin{equation} 20 | \x(t+\delta t) \simeq \x(t) + \delta t \dot{\x}(t) + O( (\delta t) ^2) = \x(t) + h \f(\x(t)) + O( (\delta t) ^2), 21 | \end{equation} 22 | donde $h = \delta t$ es el paso de tiempo. 23 | Eso nos da el \defn{método de Euler}. Lo podemos implementar como una función que regresa el valor nuevo de la variable: 24 | \begin{python} 25 | def euler(t, x, h, f): 26 | return x + h*f(x) 27 | \end{python} 28 | Nótese que la función \inl{euler} toma \emph{el nombre de la función \inl{f} que integrar} como argumento. 29 | 30 | Ahora para integrar la ecuación entre un tiempo initial $t_0$ y un tiempo final $t_f$, repetimos este paso muchas veces: 31 | \begin{python} 32 | def integrar(t0, tf, h, x0, f): 33 | lista_t = [] 34 | lista_x = [] 35 | 36 | x = x0 37 | for t in arange(t0, tf+h/2., h): 38 | x = euler(t, x, h, f) 39 | 40 | lista_t.append(t) 41 | lista_x.append(x) 42 | 43 | return lista_t, lista_x 44 | \end{python} 45 | 46 | Para integrar la ecuación $\dot{x} = -x$ ponemos entonces 47 | \begin{python} 48 | def f(x): 49 | return x 50 | 51 | t, x = integrar(0, 10, 0.1, 10, f) 52 | \end{python} 53 | 54 | Nótese que el \emph{mismo código} funciona para ecuaciones vectoriales $\dot{\x} = \f(\x)$, siempre y cuando la función \inl{f} acepte un vector y regresa un vector. 55 | 56 | Si tenemos varios métodos, entonces cambiamos la definición de \inl{integrar} a 57 | \begin{python} 58 | def integrar(t0, tf, h, x0, f, metodo): 59 | \end{python} 60 | y la línea que hace el trabajo a 61 | \begin{python} 62 | x = metodo(t, x, h, f) 63 | \end{python} 64 | 65 | Ahora para integrar con respecto a distintos métodos, podemos hacer 66 | \begin{python} 67 | metodos = [euler, rk2, rk4] 68 | 69 | for metodo in metodos: 70 | t, x = integrar(0, 10, 0.1, 10, f, metodo) 71 | \end{python} 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /progs/2010-06-16/objetos_log.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'objetos_log.py', 'pylab': 1}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | _ip.magic("logstart objetos_log.py") 8 | 9 | pos = 0.0 10 | vel = 1.0 11 | pos2 = 0.0 12 | vel2 = 1.0 13 | from numpy import * 14 | pos = array([1., 3.]) 15 | vel = array([1., 1.]) 16 | class Particula: 17 | pos = 0.0 18 | vel = 1.0 19 | 20 | Particula 21 | p = Particula () 22 | p 23 | p.pos 24 | p.vel 25 | p2 = Particula () 26 | p2 27 | p1 28 | p1 29 | p 30 | p2 31 | p.pos 32 | p2.pos 33 | p.pos = 10.0 34 | p2.pos 35 | Particula.pos 36 | Particula.pos = 10 37 | p.pos 38 | p2.pos 39 | Particula.pos = 20 40 | p2.pos 41 | p1.pos 42 | p.pos 43 | _ip.magic("run varias-figuras.py ") 44 | _ip.magic("run clases.py ") 45 | p = Particula () 46 | p.x 47 | p,.v 48 | p.v 49 | _ip.magic("run clases.py ") 50 | p.v 51 | p = Particula () 52 | p.v 53 | p.x 54 | p.mover () 55 | _ip.magic(r"run clases.py \_"[:-1]) 56 | _ip.magic("run clases.py") 57 | p.mover () 58 | _ip.magic("run clases.py") 59 | p = Particula () 60 | p.mover () 61 | p.mover (0.2) 62 | p 63 | p.x 64 | p.v 65 | p2 = Particula () 66 | p2.mover (10) 67 | p2.x 68 | p.x 69 | _ip.magic("run clases.py") 70 | p.mover (0.2) 71 | x 72 | v 73 | _ip.magic("run clases.py") 74 | p = Particula 75 | _ip.magic("run clases.py") 76 | p = Particula () 77 | _ip.magic("run clases.py") 78 | p= Particula (0, 1) 79 | p2 = Particula (3, 10) 80 | p2.pos 81 | p2.x 82 | p.x 83 | p2.v 84 | p.v 85 | p3 = Particula () 86 | _ip.magic("run clases.py") 87 | p3 = Particula () 88 | print(p3.x, p3.v) 89 | p3.mover() 90 | p3.mover(0.1) 91 | _ip.magic("run clases.py") 92 | p = Particula () 93 | p.mover_n_veces (10, 0.1) 94 | _ip.magic("run clases.py") 95 | p = Particula () 96 | p.mover_n_veces (10, 0.1) 97 | p.mover_n_veces (10, 0.1) 98 | p = Particula () 99 | _ip.magic("run clases.py") 100 | p = Particula () 101 | p.mover_n_veces (10, 0.1) 102 | p = Particula () 103 | _ip.magic("run clases.py") 104 | p = Particula () 105 | p.mover_n_veces (10, 0.1) 106 | print(p) 107 | _ip.magic("run clases.py") 108 | p = Particula () 109 | print(p) 110 | _ip.magic("run clases.py") 111 | p = Particula () 112 | print(pAA) 113 | print(p) 114 | _ip.magic("run clases.py") 115 | p = Particula () 116 | print(p) 117 | a = str(p) 118 | a 119 | exec(a) 120 | x = arange(10) 121 | x.__repr__ 122 | #?x.__repr__ 123 | #?repr 124 | #?x.__add__ 125 | _ip.magic("run clases.py") 126 | p = Particula () 127 | p2 = Particula () 128 | p + p2 129 | p3 = p + p2 130 | p3 131 | p.x 132 | p2.x 133 | p3.x 134 | p.v 135 | p2.v 136 | p3.v 137 | x.__add__ 138 | #?x.__add__ 139 | p4 = p + p2 + p3 140 | p4.v 141 | p4 - p3 142 | x. 143 | #?x.__sub__ 144 | x 145 | #?x.__add__ 146 | #?x.__add__? 147 | -------------------------------------------------------------------------------- /animaciones-visual.tex: -------------------------------------------------------------------------------- 1 | \chapter{Animaciones sencillas con Visual Python} 2 | 3 | En este capítulo, veremos un paquete, Visual Python, que permite hacer animaciones en 3 dimensiones, en tiempo real, de una manera sencillísima. Qué podemos hacer con la esfera \inl{s}? Como siempre, \inl{ipython} nos permite averiguarlo al poner \inl{s.}. 23 | Básicamente, podemos cambiar sus \defn{propiedades internas}, tales como su color, su radio y su posición: 24 | \begin{python} 25 | s.color = color.red # o s.color = 1, 0, 0 26 | s.radius = 0.5 27 | s.pos = 1, 0, 0 28 | \end{python} 29 | Aquí, \inl{s.pos} es un vector, también definido por Visual, como podemos ver al teclear \inl{type(s.pos)}. 30 | Los vectores en Visual son diferentes de los que provee \inl{numpy}. Los de Visual siempre tienen 3 componentes. 31 | 32 | Ahora podemos construir otros objetos, incluyendo a \inl{box}, \inl{cylinder}, etc. 33 | Nótese que la gráfica se puede rotar en 3 dimensiones con el ratón, al arrastar con el botón de derecho puesto, y se puede hacer un acercamiento con el botón central. 34 | 35 | \section{Animaciones} 36 | Ahora llega lo bueno. >Cómo podemos hacer una animación? Una animación no es más que una secuencia de imágenes, desplegadas rápidamente una tras otra. Así que eso es lo que tenemos que hacer: 37 | \begin{python} 38 | s = sphere() 39 | b = box() 40 | for i in range(10000): 41 | rate(100) 42 | s.pos = i/1000., 0, 0 43 | \end{python} 44 | 45 | \section{Agregando propiedades a objetos} 46 | Supongamos que queremos pensar en nuestra esfera como una pelota. Entonces la pelota tendrá no solamente una posición, sino también una velocidad. Se lo podemos crear así: 47 | \begin{python} 48 | pelota = sphere() 49 | pelota.vel = vector(1,0,0) 50 | \end{python} 51 | Nótese que se tiene que poner explícitamente \inl{vector}, ya que sino sería una $n$-ada (tupla). 52 | Ahora quedó definida la velocidad de la pelota como otra propiedad interna. 53 | 54 | 55 | Eso es básicamente todo lo que hay que saber de Visual Python. También es posible interactuar con el teclado, extraer las coordenadas del ratón, etc. 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /progs/2010-06-02/estructuras_control.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'estructuras_control.py'}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | _ip.magic("logstart estructuras_control.py") 8 | 9 | a = 3 10 | if a < 5: 11 | print "a es pequeno" 12 | a = 2 * a 13 | a = 6 14 | if a < 5: 15 | print("a es pequeno") 16 | a = 2 * a 17 | if a < 5: 18 | print("a es pequeno") 19 | a = 2 * a 20 | if a < 5: 21 | print "a es pequeno" 22 | a *= 2 23 | 24 | a 25 | 26 | _ip.magic("run if.py ") 27 | a = 5 28 | _ip.magic("run if.py ") 29 | _ip.magic("run -I if.py ") 30 | _ip.magic("run -i if.py ") 31 | a = 5 32 | _ip.magic("run if.py") 33 | _ip.magic("run -i if.py ") 34 | a = 10 35 | _ip.magic("run -i if.py ") 36 | a = 010 37 | a = -10 38 | _ip.magic("run -i if.py ") 39 | _ip.magic("pwd ") 40 | _ip.magic("cd ..") 41 | _ip.magic("cd 2010-06-02/ ") 42 | _ip.system("ls") 43 | _ip.system("less if.py") 44 | a = 1 45 | b = 10 46 | if a>0 and b>0: 47 | print "2 pos" 48 | 49 | if not a>0: 50 | print "nopositivo"{ 51 | if not a>0: 52 | print("nopositivo"\) 53 | if not a>0: 54 | print("nopositivo"\) 55 | if not a>0: 56 | print("nopositivo") 57 | if not a>0: 58 | print "nonpos" 59 | 60 | _ip.magic("run -i if.py ") 61 | _ip.magic("run -i if.py ") 62 | datos = raw_input("Dame ") 63 | datos 64 | i = 0 65 | while i < 10: 66 | print i 67 | 68 | while i < 10: 69 | print(i) 70 | while i < 10: 71 | print(i) 72 | while i < 10: 73 | print i 74 | i += 1 75 | 76 | i 77 | _ip.magic("run -i while.py ") 78 | _ip.magic("run -i while.py ") 79 | _ip.magic("run -i while.py ") 80 | l = [1, 3, 17, -100] 81 | for i in l: 82 | print i 83 | 84 | for i in l: 85 | print 2*i 86 | 87 | l = [1, 2, 7.5, "hola", [3, 4], 1+3j] 88 | l. 89 | l 90 | l[4] 91 | for i in l: 92 | print i 93 | 94 | l[4] 95 | l[4][2] 96 | l[4][1] 97 | l[4][0] 98 | l[4, 0] 99 | from numpy import * 100 | a = array([1,2,17])\ 101 | for i in a: 102 | print i 103 | 104 | M = array([1,2,3,5]).reshape(2,2) 105 | M] 106 | M 107 | for i in M: 108 | print i 109 | 110 | M 111 | M[0] 112 | for i in M:\ 113 | for i in M: 114 | for j in i: 115 | print i, j 116 | 117 | M 118 | M + M 119 | range(10000) 120 | range(10) 121 | for i in range(10): 122 | print i 123 | 124 | for i in range(10000): 125 | print i 126 | 127 | resultado = 1 128 | for i in range(100): 129 | resultado *= i 130 | 131 | resultado 132 | resultado = 1 133 | for i in range(1, 101): 134 | resultado *= i\ 135 | 136 | resultado \ 137 | from math import * 138 | factorial (100) 139 | #?factorial ? 140 | #?time 141 | _ip.magic("time factorial (100)") 142 | factorial (100) 143 | _ip.magic("time factorial (10000)") 144 | factorial (10000) 145 | _ip.magic("time run factorial.py") 146 | _ip.magic("run factorial.py") 147 | float( factorial(100) ) 148 | float( factorial(1000) ) 149 | #?range 150 | range(3, 10, 2) 151 | #?xrange 152 | for i in xrange(10000000): 153 | pass 154 | _ip.magic("time for in xrange(1e7): pass") 155 | for in xrange(1e7): pass 156 | _ip.magic("time for in xrange(10000000): pass") 157 | for in xrange(10000000): pass 158 | _ip.magic(r"time for in xrange(10000000): \_"[:-1]) 159 | for in xrange(10000000): \ 160 | _ip.magic("time for in xrange(10000000):") 161 | for in xrange(10000000): 162 | _ip.magic("time for i in xrange(10000000):") 163 | for i in xrange(10000000): 164 | _ip.magic("time for i in xrange(10000000): pass") 165 | for i in xrange(10000000): pass 166 | _ip.magic("time for i in range(10000000): pass") 167 | for i in range(10000000): pass 168 | l = range(10000000) 169 | def f(x): 170 | return x*x 171 | f(10) 172 | f(10.) 173 | f("hola") 174 | def g(x): return 2*x 175 | g("hola") 176 | def h(x, y): 177 | return 2*x, 3*y 178 | h(10, "hola") 179 | def f(x): 180 | return [x, x*x, x**3] 181 | f(10) 182 | def f(x): 183 | """Esta es la descrip[cion de fn f que regresa potencias 184 | Puedo segiur por varias lienas 185 | """ 186 | return [x,x**2, x**10] 187 | f(100 188 | ) 189 | #?f 190 | s = """Una cadena 191 | Que se extiende 192 | por 193 | bla 194 | """ 195 | s 196 | -------------------------------------------------------------------------------- /paquetes.tex: -------------------------------------------------------------------------------- 1 | \chapter{Paquetes para el cómputo científico en Python} 2 | 3 | Este capítulo propone dar un breve resumen de algunos de los muchos paquetes disponibles para llevar a cabo distintas tareas de cómputo científico en Python. 4 | 5 | \section{Cálculos numéricos con \texttt{scipy}} 6 | El paquete \inl{scipy} provee una colección de herramientas para llevar a cabo tareas numéricas, como son los siguientes submódulos: 7 | funciones especiales (\inl{special}); integración de funciones y de ecuaciones diferenciales ordinarias (\inl{integrate}), optimización y raíces de funciones (\inl{optimize}), álgebra lineal (\inl{linalg}), incluyendo para matrices escasas (\inl{sparse}), y estadísticas (\inl{stats}). 8 | 9 | Veamos algunos ejemplos. Para utilizar las funciones especiales, hacemos 10 | \begin{python} 11 | from scipy import special 12 | for i in range(5): 13 | 14 | 15 | special.gamma(3) 16 | special.gamma(3.5) 17 | 18 | x = arange(-2, 2, 0.05) 19 | 20 | for i in range(5): 21 | plot(x, map(special.hermite(i), x)) 22 | \end{python} 23 | 24 | Para integrar la ecuación de Airy (un ejemplo de la documentación de \inl{scipy}) 25 | \begin{equation} 26 | \frac{d^2 w}{d z^2} - z w(z) = 0, 27 | \end{equation} 28 | podemos poner 29 | \begin{python} 30 | from scipy.integrate import odeint 31 | from scipy.special import gamma, airy 32 | y1_0 = 1.0/3**(2.0/3.0)/gamma(2.0/3.0) 33 | y0_0 = -1.0/3**(1.0/3.0)/gamma(1.0/3.0) 34 | y0 = [y0_0, y1_0] 35 | 36 | def func(y, t): 37 | return [t*y[1],y[0]] 38 | 39 | def gradiente(y,t): 40 | return [[0,t],[1,0]] 41 | 42 | x = arange(0,4.0, 0.01) 43 | t = x 44 | ychk = airy(x)[0] 45 | y = odeint(func, y0, t) 46 | y2 = odeint(func, y0, t, Dfun=gradient) 47 | 48 | print ychk[:36:6] 49 | print y[:36:6,1] 50 | print y2[:36:6,1] 51 | \end{python} 52 | En la segunda llamada a \inl{odeint}, mandamos explícitamente la función que calcula la derivada (gradiente) de \inl{f}; en la primera llamada, no fue necesario contar con una función que calculara eso. 53 | 54 | Encontrar raíces de funciones es más o menos sencillo: 55 | \begin{python} 56 | def f(x): 57 | return x + 2*cos(x) 58 | 59 | def g(x): 60 | out = [x[0]*cos(x[1]) - 4] 61 | out.append(x[1]*x[0] - x[1] - 5) 62 | return out 63 | 64 | from scipy.optimize import fsolve 65 | x0 = fsolve(func, 0.3) 66 | x02 = fsolve(func2, [1, 1]) 67 | \end{python} 68 | 69 | 70 | \section{Cálculos simbólicos con \texttt{sympy}} 71 | El módulo \inl{sympy} provee una colección de rutinas para hacer cálculos simbólicos. 72 | Las variables se tienen que declarar como tal, y luego se pueden utilizar en expresiones simbólicas: 73 | \begin{python} 74 | from sympy import * 75 | x, y, z = symbols('xyz') 76 | k, m, n = symbols('kmn', integer=True) 77 | f = Function("f") 78 | 79 | x + x 80 | (x + y) ** 2 81 | z = _ 82 | z.expand() 83 | 84 | z.subs(x, 1) 85 | 86 | limit(sin(x) / x, x, 0) 87 | limit(1 - 1/x, x, oo) 88 | 89 | diff(sin(2*x), x) 90 | diff(sin(2*x), x, 3) 91 | 92 | cos(x).series(x, 0, 10) 93 | 94 | integrate(log(x), x) 95 | integrate(sin(x), (x, 0, pi/2)) 96 | 97 | f(x).diff(x, x) + f(x) 98 | dsolve(f(x).diff(x, x) + f(x), f(x)) 99 | 100 | solve(x**4 - 1, x) 101 | 102 | pi.evalf(50) 103 | \end{python} 104 | 105 | 106 | \section{\texttt{mayavi2}} 107 | 108 | El paquete \inl{mayavi2} provee una manera de visualizar conjuntos de datos complejos en 3D. Para utilizarlo de manera interactiva, comenzamos con 109 | \begin{python} 110 | ipython -wthread 111 | 112 | import numpy as np 113 | 114 | def V(x, y, z): 115 | """ A 3D sinusoidal lattice with a parabolic confinement. """ 116 | return np.cos(10*x) + np.cos(10*y) + np.cos(10*z) + 2*(x**2 + y**2 + z**2) 117 | 118 | X, Y, Z = np.mgrid[-2:2:100j, -2:2:100j, -2:2:100j] 119 | V(X, Y, Z) 120 | 121 | from numpy import * 122 | from enthought.mayavi import mlab 123 | 124 | x, y, z = random.rand(3, 10) 125 | mlab.points3d(x, y, z) 126 | c = random.rand(10) 127 | mlab.points3d(x, y, z, color=c) 128 | 129 | mlab.clf() 130 | 131 | mlab.contour3d(X, Y, Z, V) 132 | 133 | 134 | \end{python} 135 | 136 | 137 | \section{Entorno completo: \texttt{sage}} 138 | El paquete \inl{sage}, disponible libremente de la página \url{http://www.sagemath.org}, pretende proveer una 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 matemáticas. 139 | 140 | También vien con un interfaz disponible por el internet para interactuar con los ``notebooks''. 141 | Al bajar e iniciar \inl{sage}, provee solamente el interfaz tipo línea de comandos. El comando \inl{notebook()} corre este interfaz gráfico, a lo cual conecta uno a través de su navegador (browser). Este interfaz igual se puede utilizar de manera remota para conectarse a un servidor de \inl{sage}, por ejemplo el que se puede utilizar libremente en la dirección 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /notas.kilepr: -------------------------------------------------------------------------------- 1 | [General] 2 | def_graphic_ext=eps 3 | img_extIsRegExp=false 4 | img_extensions=.eps .jpg .jpeg .png .pdf .ps .fig .gif 5 | kileprversion=2 6 | kileversion=2.0.85 7 | lastDocument=comunicaciones.tex 8 | masterDocument= 9 | name=notas 10 | pkg_extIsRegExp=false 11 | pkg_extensions=.cls .sty .bbx .cbx .lbx 12 | src_extIsRegExp=false 13 | src_extensions=.tex .ltx .latex .dtx .ins 14 | 15 | [Tools] 16 | MakeIndex= 17 | QuickBuild= 18 | 19 | [document-settings,item:animaciones-visual.tex] 20 | Bookmarks= 21 | Encoding=UTF-8 22 | Highlighting=LaTeX 23 | Indentation Mode= 24 | Mode=LaTeX 25 | ReadWrite=true 26 | 27 | [document-settings,item:archivos.tex] 28 | Bookmarks= 29 | Encoding=UTF-8 30 | Highlighting=LaTeX 31 | Indentation Mode= 32 | Mode=LaTeX 33 | ReadWrite=true 34 | 35 | [document-settings,item:comunicaciones.tex] 36 | Bookmarks= 37 | Encoding=UTF-8 38 | Highlighting=LaTeX 39 | Indentation Mode= 40 | Mode=LaTeX 41 | ReadWrite=true 42 | 43 | [document-settings,item:estructuras-de-control.tex] 44 | Bookmarks= 45 | Encoding=UTF-8 46 | Highlighting=LaTeX 47 | Indentation Mode= 48 | Mode=LaTeX 49 | ReadWrite=true 50 | 51 | [document-settings,item:introduccion.tex] 52 | Bookmarks= 53 | Encoding=UTF-8 54 | Highlighting=LaTeX 55 | Indentation Mode= 56 | Mode=LaTeX 57 | ReadWrite=true 58 | 59 | [document-settings,item:matplotlib.tex] 60 | Bookmarks= 61 | Encoding=UTF-8 62 | Highlighting=LaTeX 63 | Indentation Mode= 64 | Mode=LaTeX 65 | ReadWrite=true 66 | 67 | [document-settings,item:notas.tex] 68 | Bookmarks= 69 | Encoding=UTF-8 70 | Highlighting=LaTeX 71 | Indentation Mode= 72 | Mode=LaTeX 73 | ReadWrite=true 74 | 75 | [document-settings,item:numpy.tex] 76 | Bookmarks= 77 | Encoding=UTF-8 78 | Highlighting=LaTeX 79 | Indentation Mode= 80 | Mode=LaTeX 81 | ReadWrite=true 82 | 83 | [document-settings,item:paquetes.tex] 84 | Bookmarks= 85 | Encoding=UTF-8 86 | Highlighting=LaTeX 87 | Indentation Mode= 88 | Mode=LaTeX 89 | ReadWrite=true 90 | 91 | [item:animaciones-visual.tex] 92 | archive=true 93 | column=0 94 | encoding=UTF-8 95 | highlight=LaTeX 96 | line=0 97 | mode=LaTeX 98 | open=false 99 | order=-1 100 | 101 | [item:archivos.tex] 102 | archive=true 103 | column=0 104 | encoding=UTF-8 105 | highlight=LaTeX 106 | line=4 107 | mode=LaTeX 108 | open=false 109 | order=-1 110 | 111 | [item:clases.tex] 112 | archive=true 113 | column=0 114 | encoding= 115 | highlight= 116 | line=0 117 | mode= 118 | open=false 119 | order=-1 120 | 121 | [item:comenzando.tex] 122 | archive=true 123 | column=3080307 124 | encoding= 125 | highlight= 126 | line=0 127 | mode= 128 | open=false 129 | order=-1 130 | 131 | [item:comunicaciones.tex] 132 | archive=true 133 | column=20 134 | encoding=UTF-8 135 | highlight=LaTeX 136 | line=98 137 | mode=LaTeX 138 | open=true 139 | order=3 140 | 141 | [item:ejemplos.tex] 142 | archive=true 143 | column=7077985 144 | encoding= 145 | highlight= 146 | line=0 147 | mode= 148 | open=false 149 | order=-1 150 | 151 | [item:estructuras-de-control.tex] 152 | archive=true 153 | column=0 154 | encoding=UTF-8 155 | highlight=LaTeX 156 | line=2 157 | mode=LaTeX 158 | open=false 159 | order=1 160 | 161 | [item:introduccion.tex] 162 | archive=true 163 | column=0 164 | encoding=UTF-8 165 | highlight=LaTeX 166 | line=0 167 | mode=LaTeX 168 | open=true 169 | order=2 170 | 171 | [item:matplotlib.tex] 172 | archive=true 173 | column=0 174 | encoding=UTF-8 175 | highlight=LaTeX 176 | line=309 177 | mode=LaTeX 178 | open=true 179 | order=4 180 | 181 | [item:notas.kilepr] 182 | archive=true 183 | column=0 184 | encoding= 185 | highlight= 186 | line=0 187 | mode= 188 | open=false 189 | order=-1 190 | 191 | [item:notas.tex] 192 | archive=true 193 | column=22 194 | encoding=UTF-8 195 | highlight=LaTeX 196 | line=172 197 | mode=LaTeX 198 | open=true 199 | order=0 200 | 201 | [item:numpy.tex] 202 | archive=true 203 | column=0 204 | encoding=UTF-8 205 | highlight=LaTeX 206 | line=0 207 | mode=LaTeX 208 | open=false 209 | order=-1 210 | 211 | [item:paquetes.tex] 212 | archive=true 213 | column=0 214 | encoding=UTF-8 215 | highlight=LaTeX 216 | line=92 217 | mode=LaTeX 218 | open=true 219 | order=1 220 | 221 | [view-settings,view=0,item:animaciones-visual.tex] 222 | CursorColumn=0 223 | CursorLine=0 224 | 225 | [view-settings,view=0,item:archivos.tex] 226 | CursorColumn=0 227 | CursorLine=4 228 | 229 | [view-settings,view=0,item:comunicaciones.tex] 230 | CursorColumn=20 231 | CursorLine=98 232 | 233 | [view-settings,view=0,item:estructuras-de-control.tex] 234 | CursorColumn=0 235 | CursorLine=2 236 | 237 | [view-settings,view=0,item:introduccion.tex] 238 | CursorColumn=0 239 | CursorLine=0 240 | 241 | [view-settings,view=0,item:matplotlib.tex] 242 | CursorColumn=0 243 | CursorLine=309 244 | 245 | [view-settings,view=0,item:notas.tex] 246 | CursorColumn=22 247 | CursorLine=172 248 | 249 | [view-settings,view=0,item:numpy.tex] 250 | CursorColumn=0 251 | CursorLine=0 252 | 253 | [view-settings,view=0,item:paquetes.tex] 254 | CursorColumn=0 255 | CursorLine=92 256 | -------------------------------------------------------------------------------- /progs/2010-06-09/numpy_log.py: -------------------------------------------------------------------------------- 1 | #log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE *** 2 | #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW 3 | #log# opts = Struct({'__allownew': True, 'logfile': 'numpy_log.py', 'pylab': 1}) 4 | #log# args = [] 5 | #log# It is safe to make manual edits below here. 6 | #log#----------------------------------------------------------------------- 7 | plot(x, x*x) 8 | 9 | _ip.magic("logstart numpy_log.py") 10 | 11 | x = arange(10) 12 | plot(x, x*x) 13 | _ip.system("acroread cuad.pdf ") 14 | savefig("cuad.pdf") 15 | _ip.system("acroread cuad.pdf ") 16 | xlabel("x") 17 | ylabel("f(x)") 18 | title("Una grafica de sumo interes") 19 | plot(x, 2*x) 20 | f = figure() 21 | #?figure 22 | plot(x, 3*x) 23 | plot(x, 3*x, 'o') 24 | figure(2) 25 | plot(x, 3*x, 'o') 26 | figure(1) 27 | plot(x, 5*x, 'o') 28 | figure(2) 29 | plot(x, 6*x, 'o') 30 | #?plot 31 | plot(x, 7*x, 'ko', linewidth=3, markersize=5) 32 | plot(x, 7*x, 'ko-, linewidth=3, markersize=5) 33 | plot(x, 7*x, 'ko-', linewidth=3, markersize=5) 34 | plot(x, 7*x, 'ko-', linewidth=3, markersize=10) 35 | #?plot 36 | plot(x, 7*x, 'ko-', linewidth=3, markersize=10, markercolor=blue) 37 | plot(x, 7*x, 'ko-', linewidth=3, markersize=10, markercolor="blue") 38 | #?PLOT 39 | #?plot 40 | plot(x, 7*x, 'ko-', linewidth=3, markersize=10, markerfacecolor="blue") 41 | clf() 42 | p = plot(x, 7*x, 'ko-', linewidth=3, markersize=10, markerfacecolor="blue") 43 | p 44 | p[0] 45 | p[0].remove() 46 | draw() 47 | p, = plot(x, 7*x, 'ko-', linewidth=3, markersize=10, markerfacecolor="blue") 48 | p 49 | p.remove() 50 | plot(x) 51 | plot(x, 2*x, x, 3*x)\ 52 | p, q = plot(x, 4*x, x, 5*x)\ 53 | p 54 | q 55 | p.remove() 56 | draw() 57 | ax = gca() 58 | #?gca 59 | _ip.system("cat > datos.dat") 60 | clf() 61 | X = loadtxt ("datos.dat") 62 | X 63 | X.reshape(8) 64 | plot(X) 65 | clf() 66 | plot(X[:,0], X[:,1]) 67 | clf() 68 | plot(X[:,0], X[:,1], 'x') 69 | plot(X[:,0], X[:,1], 'x', markersize=10) 70 | plot(X[:,0], X[:,1], 'x', markersize=10, clip=False) 71 | #?plot 72 | plot(X[:,0], X[:,1], 'x', markersize=10, clip_on = False 73 | ) 74 | plot(X[:,0], X[:,1], 'kx', markersize=20, clip_on = False 75 | ) 76 | #?loadtxt 77 | _ip.system("vim datos.dat ") 78 | X = loadtxt ("datos.dat", comments="#") 79 | X 80 | X = loadtxt ("datos.dat") 81 | Z 82 | X 83 | #?loadtxt 84 | x, y = loadtxt ("datos.dat", unpack=True) 85 | x 86 | y 87 | loadtxt ("datos.dat", unpack=True) 88 | plot(x, y, 'o') 89 | f = figure(figsize=(8,8)) 90 | plot(x, y, 'o') 91 | a = arange(1000) 92 | a 93 | clf() 94 | plot(a, a**(-0.5)) 95 | clf() 96 | loglog(a, a**(-0.5)) 97 | a = arange(1, ]1000) 98 | a = arange(1, \1000) 99 | a = arange(1, 000) 100 | a = arange(1, 1000) 101 | loglog(a, a**(-0.5)) 102 | a**(-0.5) 103 | y = a**(-0.5) 104 | clf() 105 | loglog(a, y) 106 | clf() 107 | semilogx(a,y) 108 | semilogy(a,y) 109 | clf() 110 | semilogy(a,y) 111 | hold(False) 112 | plot(x, x*2) 113 | plot(x, x*3) 114 | plot(x, x*10) 115 | hold(True) 116 | plot(x, x*10) 117 | plot(x, x*3) 118 | xlabel("$\exp(x)+x^2 + \sqrt(67)") 119 | xlabel("$\exp(x)+x^2 + \sqrt(67)$") 120 | xlabel("$\exp(x)+x^2$") 121 | clf() 122 | xlabel("$\exp(x)+x^2$") 123 | hold(True 124 | hold(False) 125 | hold(True) 126 | plot(x) 127 | figure() 128 | plot(x) 129 | xlabel("$\exp(x)+x^2$") 130 | xlabel("$\exp(x)+x^2$", fontsize=16) 131 | xlabel("$\exp(x)+x^2$", fontsize=24) 132 | text(1.5, 2, "y=x+z / \sqrt{7}") 133 | text(1.5, 2, "$y=x+z / \sqrt{7}$") 134 | t = text(.5, 2, "$y=x+z / \sqrt{7}$") 135 | t.remove() 136 | draw() 137 | _ip.magic("run migraf.py ") 138 | clf() 139 | _ip.magic("run migraf.py ") 140 | show() 141 | clf() 142 | _ip.magic("run oscilacion.py ") 143 | _ip.magic("run oscilacion.py ") 144 | show() 145 | _ip.magic("run oscilacion.py ") 146 | _ip.magic("run -i oscilacion.py ") 147 | show() 148 | #?subplot 149 | _ip.magic("run animacion.py ") 150 | _ip.magic("run animacion.py ") 151 | _ip.magic("run animacion.py ") 152 | p, = plot(x) 153 | p 154 | p.set_xdata (x+5) 155 | draw() 156 | _ip.magic("run animacion.py ") 157 | clf() 158 | x = randn(1000000) 159 | x 160 | #?randn 161 | #?normal 162 | #?randn 163 | X 164 | x 165 | hist(x, 100) 166 | #?hist 167 | M = rand(1000) 168 | M = M+M.T 169 | valores_propios = eigvalsh(M) 170 | M = rand(1000, 10000) 171 | M = rand(1000, 10000) 172 | M = rand(1000, 1000) 173 | M = M+M.T 174 | valores_propios = eigvalsh(M) 175 | valores_propios.sort() 176 | clf() 177 | plot(valores_propios) 178 | plot(valores_propios, 'o') 179 | valores_propios = valores_propios [:-1] 180 | clf() 181 | plot(valores_propios, 'o') 182 | dif = valores_propios[1:] - valores_propios[:-1] 183 | clf() 184 | plot(dif) 185 | clf() 186 | hist(dif, 100) 187 | clf)( 188 | clf() 189 | hist(dif, 100, normed=False) 190 | clf() 191 | hist(dif, 100, normed=True) 192 | #?quiver 193 | a = r_[-5:5:11j] 194 | a 195 | b = r_[-5:5:11j] 196 | a 197 | b 198 | X, Y = meshgrid(a, b) 199 | clf() 200 | quiver(X, Y, X, Y) 201 | X 202 | clf() 203 | quiver(X, Y, Y, X) 204 | #?quiver 205 | quiver(X, Y, Y, X, pivot='middle') 206 | a 207 | b 208 | X 209 | Y 210 | zip(X, Y) 211 | X 212 | x = 0.5 213 | y = 0.56 214 | y = 0.5 215 | X - x 216 | Y - y 217 | _ip.magic("run campos.py ") 218 | clf() 219 | _ip.magic("run campos.py ") 220 | show() 221 | -------------------------------------------------------------------------------- /archivos.tex: -------------------------------------------------------------------------------- 1 | \chapter{Cómo leer y escribir archivos} 2 | Uno de los usos principales de Python para el cómputo científico es el de procesar datos generados en otro lado. 3 | Por lo tanto, es necesario saber cómo importar y exportar archivos. 4 | 5 | 6 | 7 | 8 | \section{Redirección de la salida} 9 | En Linux, la manera más fácil (pero no muy flexible) de guardar datos en un archivo es utilizando la llamada ``redirección'' que provee el shell (Bash). Al correr un programa así desde Bash: 10 | \begin{verbatim} 11 | ./programa > salida.dat 12 | \end{verbatim} 13 | la salida estándar (lo que aparece en la pantalla al correr el programa) se manda al archivo especificado. 14 | Así que 15 | \begin{python} 16 | python prog.py > salida.dat 17 | \end{python} 18 | mandará la salida del programa de python \inl{prog.py} al archivo \inl{salida.dat}. 19 | 20 | \ej Guarda los resultados de las raices cuadradas de diferentes números, y grafícalos con \inl{gnuplot}: 21 | \texttt{plot "salida.dat"} 22 | 23 | \ej Haz una gráfica de la velocidad de convergencia del método Babilónico para calcular la raíz cuadrada. 24 | 25 | \section{Leer archivos} 26 | Para leer un archivo, primero es necesario abrirlo para leerse. Supongamos que tenemos un archivo llamado \inl{datos.dat}, entonces lo podemos abrir para su lectura con 27 | \begin{python} 28 | entrada = open("datos.dat", "r") 29 | \end{python} 30 | El segundo argumento, \inl{"r"}, es para indicar que se va a leer (``read'') el archivo. 31 | El objeto \inl{entrada} ahora representa el archivo. 32 | 33 | Para leer del archivo abierto, hay varias posibilidades. Podemos leer todo de un golpe con \inl{entrada.read()}, leer todo por líneas con \inl{entrada.readlines()}, o línea por línea con \inl{entrada.readline()}. [Nótese que lo que se ha leído ya no se puede leer de nuevo sin cerrar el archivo con \inl{entrada.close()} y volverlo a abrir.] 34 | 35 | Por ejemplo, podemos utilizar 36 | \begin{python} 37 | for linea in entrada.readlines(): 38 | print linea 39 | \end{python} 40 | Sin embargo, tal vez la opción más fácil e intuitiva es 41 | \begin{python} 42 | for linea in entrada: 43 | print linea 44 | \end{python} 45 | Es decir, el archivo 7 | Babel and hyphenation patterns for english, usenglishmax, dumylang, noh 8 | yphenation, loaded. 9 | (/usr/share/texmf-texlive/tex/latex/base/article.cls 10 | Document Class: article 2005/09/16 v1.4f Standard LaTeX document class 11 | (/usr/share/texmf-texlive/tex/latex/base/size10.clo 12 | File: size10.clo 2005/09/16 v1.4f Standard LaTeX file (size option) 13 | ) 14 | \c@part=\count79 15 | \c@section=\count80 16 | \c@subsection=\count81 17 | \c@subsubsection=\count82 18 | \c@paragraph=\count83 19 | \c@subparagraph=\count84 20 | \c@figure=\count85 21 | \c@table=\count86 22 | \abovecaptionskip=\skip41 23 | \belowcaptionskip=\skip42 24 | \bibindent=\dimen102 25 | ) 26 | (/usr/share/texmf-texlive/tex/latex/graphics/graphicx.sty 27 | Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR) 28 | 29 | (/usr/share/texmf-texlive/tex/latex/graphics/keyval.sty 30 | Package: keyval 1999/03/16 v1.13 key=value parser (DPC) 31 | \KV@toks@=\toks14 32 | ) 33 | (/usr/share/texmf-texlive/tex/latex/graphics/graphics.sty 34 | Package: graphics 2006/02/20 v1.0o Standard LaTeX Graphics (DPC,SPQR) 35 | 36 | (/usr/share/texmf-texlive/tex/latex/graphics/trig.sty 37 | Package: trig 1999/03/16 v1.09 sin cos tan (DPC) 38 | ) 39 | (/etc/texmf/tex/latex/config/graphics.cfg 40 | File: graphics.cfg 2007/01/18 v1.5 graphics configuration of teTeX/TeXLive 41 | ) 42 | Package graphics Info: Driver file: pdftex.def on input line 90. 43 | 44 | (/usr/share/texmf-texlive/tex/latex/pdftex-def/pdftex.def 45 | File: pdftex.def 2007/01/08 v0.04d Graphics/color for pdfTeX 46 | \Gread@gobject=\count87 47 | )) 48 | \Gin@req@height=\dimen103 49 | \Gin@req@width=\dimen104 50 | ) 51 | (/usr/share/texmf-texlive/tex/latex/subfigure/subfigure.sty 52 | Package: subfigure 2002/03/15 v2.1.5 subfigure package 53 | \subfigtopskip=\skip43 54 | \subfigcapskip=\skip44 55 | \subfigcaptopadj=\dimen105 56 | \subfigbottomskip=\skip45 57 | \subfigcapmargin=\dimen106 58 | \subfiglabelskip=\skip46 59 | \c@subfigure=\count88 60 | \c@lofdepth=\count89 61 | \c@subtable=\count90 62 | \c@lotdepth=\count91 63 | 64 | **************************************** 65 | * Local config file subfigure.cfg used * 66 | **************************************** 67 | (/usr/share/texmf-texlive/tex/latex/subfigure/subfigure.cfg) 68 | \subfig@top=\skip47 69 | \subfig@bottom=\skip48 70 | ) (./sins.aux) 71 | \openout1 = `sins.aux'. 72 | 73 | LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 5. 74 | LaTeX Font Info: ... okay on input line 5. 75 | LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 5. 76 | LaTeX Font Info: ... okay on input line 5. 77 | LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 5. 78 | LaTeX Font Info: ... okay on input line 5. 79 | LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 5. 80 | LaTeX Font Info: ... okay on input line 5. 81 | LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 5. 82 | LaTeX Font Info: ... okay on input line 5. 83 | LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 5. 84 | LaTeX Font Info: ... okay on input line 5. 85 | 86 | (/usr/share/texmf/tex/context/base/supp-pdf.tex 87 | [Loading MPS to PDF converter (version 2006.09.02).] 88 | \scratchcounter=\count92 89 | \scratchdimen=\dimen107 90 | \scratchbox=\box26 91 | \nofMPsegments=\count93 92 | \nofMParguments=\count94 93 | \everyMPshowfont=\toks15 94 | \MPscratchCnt=\count95 95 | \MPscratchDim=\dimen108 96 | \MPnumerator=\count96 97 | \everyMPtoPDFconversion=\toks16 98 | ) 99 | File: sin1.pdf Graphic file (type pdf) 100 | 101 | LaTeX Font Info: External font `cmex10' loaded for size 102 | (Font) <8> on input line 8. 103 | LaTeX Font Info: External font `cmex10' loaded for size 104 | (Font) <6> on input line 8. 105 | LaTeX Font Info: External font `cmex10' loaded for size 106 | (Font) <5> on input line 8. 107 | 108 | 109 | File: sin2.pdf Graphic file (type pdf) 110 | 111 | 112 | File: sin3.pdf Graphic file (type pdf) 113 | 114 | 115 | File: sin4.pdf Graphic file (type pdf) 116 | 117 | 118 | File: sin5.pdf Graphic file (type pdf) 119 | 120 | 121 | File: sin6.pdf Graphic file (type pdf) 122 | 123 | Overfull \hbox (10.78752pt too wide) in paragraph at lines 8--19 124 | [][] [] 125 | [] 126 | 127 | 128 | Overfull \hbox (10.78752pt too wide) in paragraph at lines 8--19 129 | [] [] 130 | [] 131 | 132 | 133 | Overfull \hbox (10.78752pt too wide) in paragraph at lines 8--19 134 | [] [] 135 | [] 136 | 137 | [1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map} <./sin1.pdf> <./sin2.pdf> 138 | <./sin3.pdf> <./sin4.pdf> <./sin5.pdf> <./sin6.pdf>] (./sins.aux) ) 139 | Here is how much of TeX's memory you used: 140 | 1057 strings out of 95086 141 | 13173 string characters out of 1183254 142 | 59124 words of memory out of 1500000 143 | 4271 multiletter control sequences out of 10000+50000 144 | 5463 words of font info for 20 fonts, out of 1200000 for 2000 145 | 28 hyphenation exceptions out of 8191 146 | 25i,7n,24p,199b,229s stack positions out of 5000i,500n,6000p,200000b,5000s 147 | 151 | Output written on sins.pdf (1 page, 93965 bytes). 152 | PDF statistics: 153 | 204 PDF objects out of 1000 (max. 8388607) 154 | 0 named destinations out of 1000 (max. 131072) 155 | 31 words of extra memory for PDF output out of 10000 (max. 10000000) 156 | 157 | -------------------------------------------------------------------------------- /ecuaciones-diferenciales.py: -------------------------------------------------------------------------------- 1 | 2 | # Codigo para implementar los distintos metodos para la tarea 2 3 | # Las funciones euler etc. funcionan de manera **igual** para ecuaciones 4 | # de orden superior si utilizamos *vectores* 5 | 6 | from pylab import * # para graficas 7 | 8 | 9 | 10 | def euler_completo(x0, t_final, dt, f): 11 | lista_t = [] 12 | lista_x = [] 13 | 14 | x = x0 15 | t = 0. 16 | 17 | while t < t_final+dt: # para incluir t_final 18 | lista_t.append(t) 19 | lista_x.append(x) 20 | 21 | x += dt * f(x,t) 22 | t += dt 23 | 24 | return lista_t, lista_x 25 | 26 | 27 | def rk2_completo(x0, t_final, h, f): # aqui se decidio utilizar h en lugar de dt para el incremento 28 | lista_t = [] 29 | lista_x = [] 30 | 31 | x = x0 32 | t = 0. 33 | 34 | while t < t_final+h: # para incluir t_final 35 | lista_t.append(t) 36 | lista_x.append(x) 37 | 38 | k1 = f(x,t) 39 | k2 = f(x + 0.5*h*k1, t+0.5*h) 40 | 41 | x += h * k2 42 | t += h 43 | 44 | return lista_t, lista_x 45 | 46 | 47 | def rk4_completo(x0, t_final, h, f): 48 | lista_t = [] 49 | lista_x = [] 50 | 51 | x = x0 52 | t = 0. 53 | 54 | while t < t_final+h: # para incluir t_final 55 | lista_t.append(t) 56 | lista_x.append(x) 57 | 58 | k1 = f(x,t) 59 | k2 = f(x + 0.5*h*k1, t+0.5*h) 60 | k3 = f(x + 0.5*h*k2, t+0.5*h) 61 | k4 = f(x + h*k3, t+h) 62 | 63 | x += h/6. * (k1 + 2.*k2 + 2.*k3 + k4) 64 | t += h 65 | 66 | return lista_t, lista_x 67 | 68 | 69 | # Dado que las funciones euler, rk2 y rk4 son tan similares, podemos extraer la parte comun, tal que 70 | # hay una sola funcion ' integrar' , y los metodos nada mas hacen un paso, regresando el estimado 71 | # de la derivada segun el metodo, como sigue: 72 | 73 | 74 | def euler(x, t, h, f): 75 | 76 | return f(x,t) 77 | 78 | def rk2(x, t, h, f): 79 | k1 = f(x,t) 80 | k2 = f(x + 0.5*dt*k1, t+0.5*dt) 81 | 82 | return k2 83 | 84 | def rk4(x, t, h, f): 85 | k1 = f(x,t) 86 | k2 = f(x + 0.5*h*k1, t+0.5*h) 87 | k3 = f(x + 0.5*h*k2, t+0.5*h) 88 | k4 = f(x + h*k3, t+h) 89 | 90 | return (k1 + 2.*k2 + 2.*k3 + k4) / 6. 91 | 92 | 93 | def integrar_1er_orden(x0, t_final, h, f, metodo): 94 | # metodo es el metodo que utilizar, que estima la derivada 95 | lista_t = [] 96 | lista_x = [] 97 | 98 | x = x0 99 | t = 0. 100 | 101 | while t < t_final+h: # para incluir t_final 102 | lista_t.append(t) 103 | lista_x.append(x) 104 | 105 | derivada = metodo(x, t, h, f) 106 | 107 | x += h * derivada 108 | t += h 109 | 110 | return lista_t, lista_x 111 | 112 | 113 | 114 | 115 | # Hasta ahora, nada mas hemos *definido* las funciones, 116 | # es decir, le hemos dicho a la maquina como se *implementa* 117 | # el metodo de Euler etc. 118 | 119 | # Pero no le hemos dicho que *ejecute* (corra) ninguna funcion 120 | # Para hacerlo, tenemos que *llamar* a la funcion como sigue 121 | 122 | # Tampoco hemos definido ninguna funcion que se integrara: 123 | 124 | def logistica(x,t): 125 | return x*(5. - x) 126 | 127 | 128 | 129 | # Las variables que definimos aqui son *independientes* de las que 130 | # hay adentro de las funciones euler etc. 131 | 132 | dt = 0.2 133 | t_final = 5 134 | x0 = 0.1 135 | 136 | t, x = euler_completo(x0, t_final, dt, logistica) 137 | # utiliza ' logistica' como la f dentro de euler, y guarda el resultado en t y x 138 | # esta es la primera linea en el programa que realmente *hace* algo (aparte de las definiciones de las variables) 139 | plot(t, x, 'bo-', label='euler') 140 | show() 141 | 142 | t, x = rk2_completo(x0, t_final, dt, logistica) 143 | plot(t, x, 'go-', label='RK2') 144 | show() 145 | 146 | t, x = rk4_completo(x0, t_final, dt, logistica) 147 | plot(t, x, 'ro-', label='RK4') 148 | show() 149 | 150 | 151 | # Para no repitir tanto, podemos hacer algo mas listo: 152 | metodos = [euler, rk2, rk4] # una lista de los metodos que queremos utilizar 153 | 154 | f = figure() # crear nueva figura 155 | 156 | for metodo in metodos: # iterar por la lista 157 | t, x = integrar_1er_orden(x0, t_final, dt, logistica, metodo) # integrar con este metodo 158 | plot(t, x, 'o-', label=metodo.__name__) # cualquier funcion f tiene f.__name__, que es el nombre de la funcion 159 | show() 160 | 161 | legend() # mostrar la leyenda del plot 162 | 163 | 164 | # Pregunta 3: 165 | # Las funciones definidas *no tienen que cambiar*!! 166 | # Utilizamos vectores 167 | 168 | # Ecuaciones 169 | # x' = y 170 | # y' = -omega^2 * x 171 | 172 | # En vectores: 173 | # x' = f(x) 174 | # f(x) = (y, -omega^2*x) 175 | 176 | omega = 1. 177 | omega_cuadrado = omega*omega # para no tener que hacer la multiplicacion cada vez 178 | 179 | def harmonico(x_vec, t): 180 | # tratar x_vec como vector! 181 | xx, yy = x_vec # separar sus componentes 182 | # Alternativa: x, y = x_vec[0], x_vec[1] 183 | 184 | return array([yy, -omega_cuadrado*xx]) # regresamos un arreglo (vector) para poder utilizarlo en calculos 185 | 186 | 187 | 188 | def integrar(x0, t_final, h, f, metodo): # funciona nada mas para arreglos 189 | # metodo es el metodo que utilizar, que estima la derivada 190 | lista_t = [] 191 | lista_x = [] 192 | 193 | x = x0 194 | t = 0. 195 | 196 | while t < t_final+h: # para incluir t_final 197 | lista_t.append(t) 198 | lista_x.append(x.copy()) 199 | # x.copy() hace una copia de x como una lista 200 | # si no hacemos esto, entonces los elementos "cambian" cuando x cambia! 201 | 202 | # una alternativa es lista_x.append(list(x)) -- agrega una version de x como lista 203 | 204 | derivada = metodo(x, t, h, f) 205 | 206 | x += h * derivada 207 | t += h 208 | 209 | return lista_t, lista_x 210 | 211 | # Crear una nueva figura: 212 | f = figure(figsize=(8,8)) # figsize cambia el tamano / forma de la figura -- aqui es cuadrada 213 | 214 | x0 = array([1., 0.]) 215 | t_final = 10. 216 | dt = 0.1 217 | 218 | 219 | metodos = [euler, rk2, rk4] # una lista de los metodos que queremos utilizar 220 | 221 | for metodo in metodos: 222 | t, x = integrar(x0, t_final, dt, harmonico, metodo) 223 | x = array(x) # convertir la lista de listas en un arreglo para poder extraer componentes: 224 | 225 | plot(x[:,0], x[:,1], 'o-', label=metodo.__name__) 226 | show() 227 | 228 | legend() # mostrar la leyenda del plot 229 | 230 | -------------------------------------------------------------------------------- /notas.tex: -------------------------------------------------------------------------------- 1 | \documentclass[letterpaper,10pt]{book} 2 | 3 | \usepackage{mathptmx} 4 | \usepackage{color} 5 | 6 | \usepackage[utf8]{inputenc} 7 | 8 | \usepackage{courier} 9 | 10 | \usepackage{amsmath} 11 | 12 | \usepackage[spanish]{babel} 13 | 14 | % \usepackage{listings} 15 | 16 | \usepackage[letterpaper, margin=1.2in]{geometry} 17 | 18 | \usepackage{hyperref} 19 | 20 | % \newcommand{\defn}[1]{{\color{red} \emph{#1}}} 21 | 22 | \usepackage[procnames]{listings} 23 | \usepackage{textcomp} 24 | \usepackage{setspace} 25 | \usepackage{amssymb} 26 | 27 | \definecolor{gray}{gray}{0.5} 28 | \definecolor{green}{rgb}{0,0.5,0} 29 | \definecolor{lightgreen}{rgb}{0,0.7,0} 30 | \definecolor{purple}{rgb}{0.5,0,0.5} 31 | \definecolor{darkred}{rgb}{0.5,0,0} 32 | \definecolor{orange}{rgb}{1,0.5,0} 33 | % \lstnewenvironment{python}[1][]{ 34 | % \lstnewenvironment{python}[1][]{ 35 | \lstset{ 36 | language=python, 37 | basicstyle=\ttfamily\small\setstretch{1}, 38 | stringstyle=\color{green}, 39 | showstringspaces=false, 40 | alsoletter={1234567890}, 41 | otherkeywords={\ , \}, \{}, 42 | keywordstyle=\color{blue}, 43 | emph={access,and,as,break,class,continue,def,del,elif,else,% 44 | except,exec,finally,for,from,global,if,import,in,is,% 45 | lambda,not,or,pass,print,raise,return,try,while,assert}, 46 | emphstyle=\color{orange}\bfseries, 47 | emph={[2]self}, 48 | emphstyle=[2]\color{gray}, 49 | emph={[4]ArithmeticError,AssertionError,AttributeError,BaseException,% 50 | DeprecationWarning,EOFError,Ellipsis,EnvironmentError,Exception,% 51 | False,FloatingPointError,FutureWarning,GeneratorExit,IOError,% 52 | ImportError,ImportWarning,IndentationError,IndexError,KeyError,% 53 | KeyboardInterrupt,LookupError,MemoryError,NameError,None,% 54 | NotImplemented,NotImplementedError,OSError,OverflowError,% 55 | PendingDeprecationWarning,ReferenceError,RuntimeError,RuntimeWarning,% 56 | StandardError,StopIteration,SyntaxError,SyntaxWarning,SystemError,% 57 | SystemExit,TabError,True,TypeError,UnboundLocalError,UnicodeDecodeError,% 58 | UnicodeEncodeError,UnicodeError,UnicodeTranslateError,UnicodeWarning,% 59 | UserWarning,ValueError,Warning,ZeroDivisionError,abs,all,any,apply,% 60 | basestring,bool,buffer,callable,chr,classmethod,cmp,coerce,compile,% 61 | complex,copyright,credits,delattr,dict,dir,divmod,enumerate,eval,% 62 | execfile,exit,file,filter,float,frozenset,getattr,globals,hasattr,% 63 | hash,help,hex,id,input,int,intern,isinstance,issubclass,iter,len,% 64 | license,list,locals,long,map,max,min,object,oct,open,ord,pow,property,% 65 | quit,range,raw_input,reduce,reload,repr,reversed,round,set,setattr,% 66 | slice,sorted,staticmethod,str,sum,super,tuple,type,unichr,unicode,% 67 | vars,xrange,zip}, 68 | emphstyle=[4]\color{purple}\bfseries, 69 | upquote=true, 70 | morecomment=[s][\color{lightgreen}]{"""}{"""}, 71 | commentstyle=\color{red}\slshape, 72 | literate={>>>}{\textbf{\textcolor{darkred}{>{>}>}}}3% 73 | {...}{{\textcolor{gray}{...}}}3, 74 | procnamekeys={def,class}, 75 | procnamestyle=\color{blue}\textbf, 76 | % framexleftmargin=1mm, framextopmargin=1mm, frame=shadowbox, 77 | frame=none, 78 | rulesepcolor=\color{blue}, 79 | % }}{} 80 | } 81 | \lstnewenvironment{python}[1][]{ 82 | \lstset{ 83 | language=python, 84 | basicstyle=\ttfamily\small\setstretch{1}, 85 | stringstyle=\color{green}, 86 | showstringspaces=false, 87 | alsoletter={1234567890}, 88 | otherkeywords={\ , \}, \{}, 89 | keywordstyle=\color{blue}, 90 | emph={access,and,as,break,class,continue,def,del,elif,else,% 91 | except,exec,finally,for,from,global,if,import,in,is,% 92 | lambda,not,or,pass,print,raise,return,try,while,assert}, 93 | emphstyle=\color{orange}\bfseries, 94 | emph={[2]self}, 95 | emphstyle=[2]\color{gray}, 96 | emph={[4]ArithmeticError,AssertionError,AttributeError,BaseException,% 97 | DeprecationWarning,EOFError,Ellipsis,EnvironmentError,Exception,% 98 | False,FloatingPointError,FutureWarning,GeneratorExit,IOError,% 99 | ImportError,ImportWarning,IndentationError,IndexError,KeyError,% 100 | KeyboardInterrupt,LookupError,MemoryError,NameError,None,% 101 | NotImplemented,NotImplementedError,OSError,OverflowError,% 102 | PendingDeprecationWarning,ReferenceError,RuntimeError,RuntimeWarning,% 103 | StandardError,StopIteration,SyntaxError,SyntaxWarning,SystemError,% 104 | SystemExit,TabError,True,TypeError,UnboundLocalError,UnicodeDecodeError,% 105 | UnicodeEncodeError,UnicodeError,UnicodeTranslateError,UnicodeWarning,% 106 | UserWarning,ValueError,Warning,ZeroDivisionError,abs,all,any,apply,% 107 | basestring,bool,buffer,callable,chr,classmethod,cmp,coerce,compile,% 108 | complex,copyright,credits,delattr,dict,dir,divmod,enumerate,eval,% 109 | execfile,exit,file,filter,float,frozenset,getattr,globals,hasattr,% 110 | hash,help,hex,id,input,int,intern,isinstance,issubclass,iter,len,% 111 | license,list,locals,long,map,max,min,object,oct,open,ord,pow,property,% 112 | quit,range,raw_input,reduce,reload,repr,reversed,round,set,setattr,% 113 | slice,sorted,staticmethod,str,sum,super,tuple,type,unichr,unicode,% 114 | vars,xrange,zip}, 115 | emphstyle=[4]\color{purple}\bfseries, 116 | upquote=true, 117 | morecomment=[s][\color{lightgreen}]{"""}{"""}, 118 | commentstyle=\color{red}\slshape, 119 | literate={>>>}{\textbf{\textcolor{darkred}{>{>}>}}}3% 120 | {...}{{\textcolor{gray}{...}}}3, 121 | procnamekeys={def,class}, 122 | procnamestyle=\color{blue}\textbf, 123 | % framexleftmargin=1mm, framextopmargin=1mm, frame=shadowbox, 124 | frame=none, 125 | rulesepcolor=\color{blue},#1 126 | }}{} 127 | 128 | 129 | \usepackage[medium, bf, compact]{titlesec} 130 | 131 | 132 | % \lstset{% general command to set parameter(s) 133 | % basicstyle=\small\ttfamily, % print whole listing small 134 | % keywordstyle=\color{black}\bfseries, 135 | % % underlined bold black keywords 136 | % identifierstyle=, % nothing happens 137 | % commentstyle=, % white comments 138 | % stringstyle=, % typewriter type for strings 139 | % showstringspaces=false} % no special string spaces 140 | 141 | \newcommand{\cmd}[1]{{\color{blue}\texttt{gnuplot}}} 142 | 143 | \newcommand{\x}{\mathbf{x}} 144 | \newcommand{\f}{\mathbf{f}} 145 | 146 | 147 | \newcommand{\mean}[1]{\left \langle #1 \right \rangle} 148 | \newcommand{\defeq}{:=} 149 | 150 | \setlength{\parskip}{5pt} 151 | \setlength{\parindent}{0pt} 152 | 153 | \title{Notas del curso \\ 154 | \textbf{ {\huge Programación en Python} }\\[20pt] 155 | Curso de actualización docente\\ Facultad de Ciencias 156 | } 157 | \author{\Large David P.~Sanders} 158 | \date{\large \today} 159 | 160 | \newcommand{\ej}{\noindent \textbf{Ejercicio:\ }} 161 | 162 | \newcommand{\defn}[1]{{\color{red} \emph{#1}}} 163 | 164 | \let\inl\lstinline 165 | 166 | \begin{document} 167 | 168 | \pagenumbering{roman} 169 | 170 | \maketitle 171 | % \tableofcontents 172 | 173 | \pagenumbering{arabic} 174 | 175 | \include{introduccion} 176 | \include{comenzando} 177 | \include{estructuras-de-control} 178 | \include{animaciones-visual} 179 | \include{archivos} 180 | \include{numpy} 181 | \include{matplotlib} 182 | \include{ejemplos} 183 | \include{comunicaciones} 184 | \include{clases} 185 | \include{paquetes} 186 | 187 | 188 | \end{document} 189 | -------------------------------------------------------------------------------- /clases.tex: -------------------------------------------------------------------------------- 1 | \chapter{Programación orientada a objetos: clases} 2 | 3 | En este capítulo, veremos uno de los temas más revolucionarios en materia de programación: la \defn{programación orientada a objetos}. Aunque hemos estado utilizando los objetos de manera implícita a través del curso, ahora veremos cómo nosotros podemos definir nuestros propios tipos de objetos nuevos, y para qué sirve. 4 | 5 | \section{La programación orientada a objetos: las clases} 6 | 7 | Consideremos una situación clásica en el cómputo científico: un sistema que consiste en cierto número de partículas en 2 dimensiones, que tienen \defn{propiedades internas}, como una posición, una velocidad y una masa, y que se pueden mover con una regla tipo Euler. 8 | 9 | Para una partícula, podríamos definir sus variables simplemente como sigue: 10 | \begin{python} 11 | x = y = 0.0 # posicion 12 | vx = vy = 1.0 # velocidad 13 | \end{python} 14 | Un paso de Euler de tamaño \inl{dt} se puede implementar con 15 | \begin{python} 16 | dt = 0.1 17 | x += dt * vx; 18 | y += dt * vy; 19 | \end{python} 20 | 21 | 22 | Pero ahora, >qué hacemos si necesitamos otra partícula más? Podríamos poner 23 | \begin{python} 24 | x1 = y1 = 0.0 25 | x2 = y2 = 0.0 26 | vx1 = vy1 = 1.0 27 | vx1 = vy1 = 1.0 28 | \end{python} 29 | Si las partículas también tienen masas y colores, entonces se vuelve muy tedioso, ya que tenemos que actualizar todo dos veces para cada propiedad nueva: 30 | \begin{lstlisting} 31 | m1 = m2 = 0.0; 32 | c1 = c2 = 0.0; 33 | \end{lstlisting} 34 | Para muchas particulas podríamos emplear arreglos (listas, en Python), que reduciría el trabajo. 35 | 36 | Pero ahora podríamos imaginarnos que por alguna razón queremos agregar otra partícula, o incluso duplicar toda la simulación. 37 | Entonces tendríamos que duplicar a mano todas las variables, cambiando a la vez sus nombres, lo cual 38 | seguramente conducirá a introducir errores. 39 | 40 | Sin embargo, \emph{conceptualmente} tenemos muchas variables que están relacionadas: todas \emph{pertenecen} a una partícula. 41 | Hasta ahora, no hay manera de expresar esto en el programa. 42 | 43 | \section{La solución: objetos, a través de clases} 44 | 45 | Lo que queremos hacer, entonces, es reunir todo lo que corresponde a una partícula en un \emph{nuevo tipo de objeto}, llamado \inl{Particula}. Luego podremos decir que \inl{p1} y \inl{p2} son \inl{Particula}s, 46 | o incluso hacer un arreglo (lista) de \inl{Particula}s. 47 | 48 | Toda la información que le corresponde a una partícula dada estará contenida adentro del objeto; esta información formará parte del objeto no sólo 49 | conceptualmente, sino también en la representación en el programa. 50 | 51 | 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 adentro del objeto para entender cómo funciona. Se puede pensar que corresponde a una caja con palancas, botones y luces: las palancas y los botones proveen una manera de darle información o instrucciones a la caja, y las luces dan información de regreso al mundo externo. 52 | 53 | Para implementar eso en Python, se declara una \defn{clase} llamada \inl{Particula} y se crea una \defn{instancia} de esta clase, llamada \inl{p}. 54 | \begin{python} 55 | class Particula: 56 | x = 0.0 57 | 58 | p = Particula() 59 | p.x 60 | \end{python} 61 | Nótese que \inl{p} tiene \emph{adentro} una propiedad, que se llama \inl{x}. Podemos interpretar \inl{p.x} como una \inl{x} que le \emph{pertenece} a \inl{p}. 62 | 63 | Si ahora hacemos 64 | \begin{lstlisting} 65 | p2 = Particula() 66 | p2.x 67 | \end{lstlisting} 68 | entonces tenemos una variable completamente \emph{distinta} que también se llama \inl{x}, pero que ahora le pertenece a \inl{p2}, que es otro objeto de tipo \inl{Particula}. De hecho, más bien podemos pensar que \inl{p2.x} es una manera de escribir \inl{p2_x}, que es como lo hubiéramos podido escribir antes, que tiene la bondad de que ahora tambíen tiene sentido pensar en el conjunto \inl{p} como un todo. 69 | 70 | Remarquemos que ya estamos acostumbrados a pensar en cajas de este tipo en matemáticas, al tratar con vectores, matrices, funciones, etc. 71 | 72 | \section{Métodos de clases} 73 | 74 | Hasta ahora, una clase actúa simplemente como una caja que contiene datos. 75 | Pero objetos no sólo tienen información, sino también pueden \emph{hacer cosas}. 76 | Para hacerlo, también se pueden definir \emph{funciones} --llamadas \defn{métodos}-- que le pertenecen al objeto. 77 | Simplemente se definen las funciones adentro de la declaración de la clase: 78 | \begin{python} 79 | class Particula: 80 | x = 0.0 81 | v = 1.0 82 | 83 | def mover(self, dt): 84 | self.x += self.v*dt 85 | 86 | p = Particula() 87 | print p.x 88 | p.mover(0.1) 89 | print p.x 90 | \end{python} 91 | 92 | Nótese que los métodos de las clases siempre llevan un argumento extra, llamado \inl{self}, que quiere decir ``sí mismo''. 93 | Las variables que pertenecen a la clase, y que se utilizan adentro de estas funciones, llevan \inl{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 \emph{adentro} de la clase. 94 | 95 | 96 | \section{Funciones inicializadoras} 97 | Cuando creamos una instancia de un objeto, muchas veces queremos \defn{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, como sigue: 98 | \begin{python} 99 | class Particula: 100 | def __init__(self, xx=0.0, vv=1.0): 101 | self.x = xx 102 | self.v = vv 103 | 104 | def mover(self, dt): 105 | self.x += self.v*dt 106 | 107 | p1 = Particula() 108 | print p1.x 109 | p2 = Particula(2.5, 3.7) 110 | print p2.x 111 | p1.mover(0.1) 112 | p2.mover(0.1) 113 | print p1.x, p2.x 114 | \end{python} 115 | Nótese que la función inicializadora debe llamarse \inl{__init__}, con dos guiones bajos de cada lado del nombre \inl{init}. 116 | Puede tomar argumentos que se utilizan para inicializar las variables de la clase. 117 | 118 | \section{Métodos internos de las clases} 119 | Las clases pueden ocupar varios métodos para proveer un interfaz más limpio para el usuario. Por ejemplo, al poner 120 | \inl{print p1} en el último ejemplo, sale algo así como 121 | \begin{python} 122 | <__main__.Particula instance at 0x2849cb0> 123 | \end{python} 124 | Podemos hacer que salga algo más útil al proveer adentro de la clase una función \inl{__str__}: 125 | \begin{python} 126 | class Particula: 127 | def __init__(self, xx=0.0, vv=1.0): 128 | self.x = xx 129 | self.v = vv 130 | 131 | def __str__(self): 132 | return "Particula(%g, %g)" % (self.x, self.v) 133 | 134 | p1 = Particula() 135 | print p1 136 | \end{python} 137 | 138 | También podemos definir funciones que permiten que podamos llevar a cabo operaciones aritméticas etc.\ con objetos de este tipo, es decir, podemos \defn{sobrecargar} los operadores para que funcionen con nuestro nuevo tipo. Eso es lo que pasa con los \inl{array} de \inl{numpy}, por ejemplo. 139 | 140 | \ej Haz un objeto para representar a una partícula en 2D. Haz una nube de tales partículas. 141 | 142 | \section{Herencia} 143 | Las clases también pueden formar jerarquías al utilizar la \defn{herencia}, que quiere decir que una clase es un ``tipo de'', o ``subtipo de'' otro. 144 | -------------------------------------------------------------------------------- /estructuras-de-control.tex: -------------------------------------------------------------------------------- 1 | \chapter{Estructuras de control} 2 | 3 | Por estructuras de control, se entiende los comandos tales como condicionales, bucles, y funciones, que cambian el orden de ejecución de un programa. 4 | 5 | Las estructuras de control tienen un formato en común. A diferencia de C++ y Fortran, no existen instrucciones que indiquen donde empieza y termina un bloque del programa: en Python, un bloque empieza por \inl{:}, y su extensión se indica por el uso de una cantidad definida de \defn{espacio en blanco} al principio de cada línea. Un buen editor de texto te permite hacer eso de manera automática. 6 | 7 | \section{Condicionales} 8 | Para checar una condición y ejecutar código dependiente del resultado, se ocupa \inl{if}: 9 | \begin{python} 10 | a = raw_input('Dame el valor de a') 11 | if a > 0: 12 | print "a es positiva" 13 | a = a + 1 14 | elif a == 0: # NB: dos veces = 15 | print "a es 0" 16 | else: 17 | print "a es negativa" 18 | \end{python} 19 | En el primer caso, hay dos comandos en el bloque que se ejecutará en el caso de que $a > 0$. 20 | Nótese que \inl{elif} es una abreviación de \inl{else: if} 21 | 22 | Las condiciones que se pueden ocupar incluyen: \inl{<}, \inl{<=} y \inl {!=} (no es igual). 23 | Para combinar condiciones se ocupan las palabras \inl{and} y \inl{or}: 24 | \begin{python} 25 | a = 3; b=7 26 | if a>1 and b>2: 27 | print "Grandes" 28 | if a>0 or b>0: 29 | print "Al menos uno positivo" 30 | \end{python} 31 | 32 | 33 | \section{Bucles} 34 | La parte central de muchos cálculos científicos consiste en llevar a cabo bucles, aunque en Python, como veremos, eso se desenfatiza. 35 | 36 | \subsection{\inl{while}} 37 | El tipo de bucle más sencillo es un \inl{while}, que ejecuta un bloque de código \defn{mientras} una cierta condición se satisfaga, y suele ocuparse para llevar a cabo una iteración en la cual no se conoce de antemano el número de iteraciones necesario. 38 | 39 | El ejemplo más sencillo de un \inl{while}, donde sí se conoce la condición terminal, para contar hasta 9, se puede hacer como sigue: 40 | \begin{python} 41 | i = 0 42 | while i < 10: 43 | i += 1 # equivalente a i = i + 1 44 | print i 45 | \end{python} 46 | Nótese que si la condición deseada es del tipo ``hasta\ldots'', entonces se tiene que utilizar un \inl{while} con la condición opuesta. 47 | 48 | \ej Encuentra los números de Fibonacci menores que 1000. 49 | 50 | \ej Implementa el llamado método babilónico para calcular la raíz cuadrada de un número dado $y$. Este método consiste en la iteración 51 | $x_{n+1} = \frac{1}{2} \left[x_n + (y / x_n) \right]$. >Qué tan rápido converge? 52 | 53 | 54 | 55 | \subsection{\inl{for}} 56 | Un bucle de tipo \inl{for} se suele ocupar para llevar a cabo un número de iteraciones que se conoce de antemano. 57 | En el bucle de tipo \inl{for}, encontramos una diferencia importante con respecto a lenguajes más tradicionales: podemos iterar sobre \emph{cualquier} lista y ejecutar un bloque de código \defn{para} cada elemento de la lista: 58 | \begin{python} 59 | l = [1, 2.5, -3.71, "hola", [2, 3]] 60 | for i in l: 61 | print 2*l 62 | \end{python} 63 | 64 | Si queremos iterar sobre muchos elementos, es más útil construir la lista. Por ejemplo, para hacer una iteración para todos los números hasta 100, podemos utilizar 65 | \begin{python} 66 | for i in range(100): 67 | print 2*i 68 | \end{python} 69 | >Qué es lo que hace la función \inl{range}? Para averiguarlo, lo investigamos de manera interactiva con \inl{ipython}: 70 | \begin{python} 71 | range(10) 72 | range(3, 10, 2) 73 | \end{python} 74 | Nótese que \inl{range} no acepta argumentos de punto flotante. 75 | 76 | \ej Toma una lista, y crea una nueva que contiene la duplicación de cada elemento de la lista anterior. 77 | 78 | % \subsection{Cómo evitar bucles} 79 | % Los bucles en Python suelen ser lentos, por ser un lenguaje interpretado. En ciertas circum 80 | 81 | \section{Funciones} 82 | 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. 83 | 84 | La sintaxis para declarar una función es como sigue: 85 | \begin{python} 86 | def f(x): 87 | print "Argumento x = ", x 88 | return x*x 89 | \end{python} 90 | y se llama así: 91 | \begin{python} 92 | f(3) 93 | f(3.5) 94 | \end{python} 95 | 96 | Las funciones se pueden utilizar con argumentos de \emph{cualquier} tipo --el tipo de los argumentos nunca se especifica. Si las operaciones llevadas a cabo no se permiten para el tipo que se provee, entonces Python regresa un error: 97 | \begin{python} 98 | f("hola") 99 | \end{python} 100 | 101 | Las funciones pueden regresar varios resultados al juntarlos en un tuple: 102 | \begin{python} 103 | def f(x, y): 104 | return 2*x, 3*y 105 | \end{python} 106 | 107 | Se puede proporcionar una forma sencilla de documentación de una función al proporcionar un ``docstring": 108 | \begin{python} 109 | def cuad(x): 110 | """Funcion para llevar un numero al cuadrado. 111 | Funciona siempre y cuando el tipo de x permite multiplicacion. 112 | """ 113 | return x*x 114 | \end{python} 115 | Ahora si interrogamos al objeto cuad con \inl{ipython}: 116 | \begin{python} 117 | cuad? 118 | \end{python} 119 | nos da esta información. Si la función está definida en un archivo, entonces 120 | \inl{cuad??} muestra el código de la definición de la función. 121 | 122 | \ej Pon el código para calcular la raíz cuadrada de un número adentro de una función. Calcula la raíz de los números de 0 hasta 10 en pasos de 0.2 e imprimir los resultados. 123 | 124 | 125 | 126 | 127 | 128 | \section{Bibliotecas matemáticas} 129 | Para llevar a cabo cálculos con funciones más avanzadas, es necesario \emph{importar} la biblioteca estándar de matemáticas: 130 | \begin{python} 131 | from math import * 132 | \end{python} 133 | Eso no es necesario al correr \texttt{ipython -pylab}, que invoca un modo específico de \texttt{ipython}\footnote{Yo encuentro conveniente declarar un nuevo comando \texttt{pylab} agregando la línea \\ \texttt{alias pylab='ipython -pylab'} en el archivo \texttt{.bashrc} en mi directorio HOME.}. 134 | Sin embargo, eso importa mucho más que la simple biblioteca de matemáticas. Nótese que Python está escrito en C, así que la biblioteca \inl{math} provee acceso a las funciones matemáticas que están en la biblioteca estándar de C. Más adelante veremos como acceder a otras funciones, tales como funciones especiales. 135 | 136 | \ej >Cuál es la respuesta de la entrada \inl{sqrt(-1)}? 137 | 138 | \ej Intenta resolver la ecuación cuadrática $a x^2 + b x + c = 0$ para distintos valores de $a$, $b$ y $c$. 139 | 140 | 141 | 142 | Para permitir operaciones con números complejos como posibles respuestas, se ocupa la biblioteca (\defn{módulo}) \inl{cmath}. 143 | Si hacemos 144 | \begin{python} 145 | from cmath import * 146 | \end{python} 147 | entonces se importan las funciones adecuadas: 148 | \begin{python} 149 | sqrt(-1) 150 | \end{python} 151 | Sin embargo, ya se ``perdieron'' las funciones anteriores, es decir, las nuevas funciones han reemplazado a las distintas funciones con los mismos nombres que había antes. 152 | 153 | Una solución es importar la biblioteca de otra manera: 154 | \begin{python} 155 | import cmath 156 | \end{python} 157 | Ahora las funciones que se han importado de \inl{cmath} tienen nombres que empiezan por \inl{cmath.}: 158 | \begin{python} 159 | cmath.sqrt(-1) 160 | \end{python} 161 | \inl{ipython} ahora nos proporciona la lista de funciones adentro del módulo si hacemos \inl{cmath.}. 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /comenzando.tex: -------------------------------------------------------------------------------- 1 | \chapter{Comenzando con Python} 2 | 3 | En este capítulo, empezaremos a explorar el lenguaje Python. Se darán las bases tanto de la sintáxis básica, como de las herramientas principales para escribir programas en el lenguaje. En todo el curso se hará énfasis en las aplicaciones al cómputo científico y a la enseñanza del mismo. 4 | 5 | La versión de Python que ocuparemos es la 2.6. La nueva versión 3 rompe la compatibilidad con los paquetes básicos para el cómputo científico por el momento. 6 | 7 | 8 | \section{El entorno \texttt{ipython}} 9 | 10 | El entorno principal que ocuparemos para trabajar de manera interactiva es \texttt{ipython}. Otro posible es \texttt{idle}. 11 | 12 | \texttt{ipython} está diseñado para maximar la productividad al utilizar Python. 13 | En particular, tiene ciertos comandos que no existen en otros interpretadores de Python. 14 | Uno muy útil es 15 | \begin{python} 16 | In [1]: logstart primero_log.py 17 | \end{python} 18 | Este comando graba un ``log'' (bitácora) de todo lo que se teclea en la sesión actual en el archivo dado, aqui \inl{primero_log.py}. 19 | 20 | Otra función de suma utilidad en \texttt{ipython} es que la de completar palabras parciales con la tecla \inl{}. 21 | Además, los comandos \inl{who} y \inl{whos} proveen información de las funciones nuevas agregadas en la sesión. 22 | 23 | La documentación para cualquier función o comando está disponible en \inl{ipython} al poner \inl{?}, por ejemplo 24 | \begin{python} 25 | who? 26 | \end{python} 27 | Para funciones, \inl{??} muestra el código fuente de la función, cuando está disponible. 28 | 29 | 30 | \section{Aritmética} 31 | Python se puede utilizar como una calculadora: 32 | \begin{python} 33 | 3 34 | 3 + 2 35 | 3 * (-7.1 + 10**2) 36 | \end{python} 37 | Aquí, \inl{**} indica una potencia, como en Fortran, y las paréntesis alteran la prioridad en las operaciones. 38 | 39 | 40 | Es necesario\footnote{En Python 2.6; la situación cambia en Python 3.} tener cuidado al hacer manipulaciones con enteros: 41 | \begin{python} 42 | 1 / 2 43 | 3 / 2 44 | 5 / 2 45 | \end{python} 46 | ya que el resultado se redondea al entero más cercano. Para evitar eso, basta un punto decimal: 47 | \begin{python} 48 | 1 / 2. 49 | \end{python} 50 | 51 | 52 | Los números sin punto decimal se consideran enteros, y los con punto decimal flotantes (de doble precisión). 53 | Los enteros pueden ser \emph{arbitrariamente grandes}: 54 | \begin{python} 55 | 2 ** 2 ** 2 ** 2 ** 2 56 | \end{python} 57 | 58 | 59 | 60 | Python cuenta con números complejos, utilizando la notación \inl{1j} para la raiz de $-1$: 61 | \begin{python} 62 | 1 + 3j 63 | 1j * 1j 64 | j # da un error 65 | \end{python} 66 | `\inl{#}' indica un comentario que se extiende hasta el final de la línea. 67 | 68 | 69 | 70 | \section{Variables} 71 | Para llevar a cabo cálculos, necesitamos \defn{variables}. Las variables se declaran como debe de ser: 72 | \begin{python} 73 | a = 3 74 | b = 17.5 75 | c = 1 + 3j 76 | 77 | print a + b / c 78 | \end{python} 79 | Python reconece de manera \emph{automática} el tipo de la variable según su forma. 80 | El comando \inl{print} imprime su argumento de una manera bonita. 81 | 82 | Al reasignar una variable, se pierde la información de su valor interior, incluyendo el tipo: 83 | \begin{python} 84 | a = 3 85 | a = -5.5 86 | \end{python} 87 | 88 | 89 | \section{Entrada por parte del usuario} 90 | Se puede pedir información del usuario con 91 | \begin{python} 92 | a = raw_input('Dame el valor de a: ') 93 | print "El cuadrado de a es ", a*a 94 | \end{python} 95 | Las cadenas en Python son cadenas de caracteres entre apóstrofes o comillas. 96 | 97 | 98 | 99 | 100 | 101 | 102 | \section{Listas} 103 | La estructura de datos principal en Python es la \defn{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 longitud \emph{variable}, y pueden contener objetos de \emph{cualquier} tipo. 104 | 105 | Una lista se define con corchetes (\inl{[} y \inl{\}): 106 | \begin{python} 107 | l = [3, 4, 6] 108 | \end{python} 109 | Puede contener cualquier cosa, Qué hace \inl{l[-1]}? 133 | 134 | La longitud de una lista se puede encontrar con 135 | \begin{python} 136 | len(l) 137 | \end{python} 138 | Se pueden agregar elementos a la lista con 139 | \begin{python} 140 | l = [] # lista vacia 141 | l.append(17) 142 | l.append(3) 143 | print l, len(l) 144 | \end{python} 145 | 146 | Como siempre, las otras operaciones que se pueden llevar a cabo con la lista se pueden 147 | averiguar en \inl{ipython} con \inl{l.}. 148 | 149 | \section{$n$-adas / tuples} 150 | Otra estructura parecida es una $n$-ada (``tuple''). 151 | Es parecido a una lista, pero se escribe con (o incluso, a veces, sin paréntesis), y no se puede modificar: 152 | \begin{python} 153 | t = (3, 5) 154 | t[0] 155 | t[0] = 1 # error! 156 | \end{python} 157 | 158 | Las $n$-adas se utilizan para agrupar información. Se pueden asignar como sigue: 159 | \begin{python} 160 | a, b = 3, 5 161 | print a; print b 162 | \end{python} 163 | 164 | 165 | 166 | \section{La biblioteca estándar} 167 | Python tiene una biblioteca estándar amplia, lo cual siempre está disponible en cualquier instalación de Python. 168 | La documentación para esta biblioteca está disponible en \url{http://docs.python.org/library/} 169 | 170 | Por ejemplo, la sección 9 incluye información sobre el módulo \inl{fractions}: 171 | \begin{python} 172 | from fractions import Fraction 173 | 174 | a = Fraction(3, 5) 175 | b = Fraction(1) 176 | c = a + b 177 | d = Fraction(4, 6) 178 | d 179 | e = a + d 180 | \end{python} 181 | 182 | Cada `cosa' en Python es un \defn{objeto}, que tiene propiedades y operaciones disponibles. 183 | \inl{Fraction} es un tipo de objeto (\defn{clase}); sus operaciones están disponibles en \inl{ipython} a través de 184 | \inl{Fraction.}. Las que empiezan con \inl{__} son internos y deberían de ignorarse por el momento; las demás son accesibles al usuario. 185 | 186 | 187 | 188 | \section{Programitas de Python: scripts} 189 | Una vez que las secuencias de comandos se complican, es útil poder guardarlos en un programa, o \defn{script}. 190 | Eso consiste en un archivo de texto, cuyo nombre termina en \inl{.py}, donde se guarda la secuencia de comandos. 191 | 192 | Por ejemplo, guardemos el código anterior en el archivo \inl{cuad.py} 193 | Podemos correr el código desde \inl{ipython} con 194 | \begin{python} 195 | run cuad 196 | \end{python} 197 | Al terminar de correr el programa, el control regresa a \inl{ipython}, pero todavía tenemos acceso a las variables y funciones definidas en el script. 198 | 199 | Alternativamente, podemos tratar el script como un programa en sí al ejecutar desde el shell 200 | \begin{python} 201 | python cuad.py 202 | \end{python} 203 | Al terminar, el control regresa al shell, y perdemos la información adentro del script. 204 | 205 | De hecho, un script se puede considerar un módulo en sí, que también se puede importar: 206 | \begin{python} 207 | from cuad import * 208 | \end{python} 209 | 210 | 211 | 212 | -------------------------------------------------------------------------------- /comunicaciones.tex: -------------------------------------------------------------------------------- 1 | \chapter{Comunicándose con otros programas} 2 | 3 | En este capítulo, veremos cómo un programa de Python puede interactuar con otros programas. 4 | 5 | \section{Redirección} 6 | 7 | En esta sección veremos algunas técnicas útiles del shell \inl{bash} que no están restringidos a \inl{python}. 8 | 9 | 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 estándar del programa: corriendo desde la terminal, ponemos 10 | \begin{python} 11 | python prog.py > salida.dat 12 | \end{python} 13 | y así creamos un archivo \inl{salida.dat}, donde se capta la información que anteriormente se mandaba a la terminal. 14 | 15 | Lo mismo se puede hacer con la entrada estándar: si tenemos un programa que lee información que teclea el usuario: 16 | \begin{python} 17 | a = raw_input("Dame a: ") 18 | b = raw_input("Dame b: ") 19 | \end{python} 20 | Entonces podemos también mandarle valores de un archivo, al redirigir la entrada estándar: 21 | \begin{python} 22 | python prog.py < datos.dat 23 | \end{python} 24 | donde \inl{datos.dat} contiene la información deseada. A su vez, la salida de este programa se puede mandar a otro archivo con \inl{>}. 25 | 26 | Finalmente, si queremos conectar la salida de un programa con la entrada de otro, utilizamos un ``tubo'' (``pipe''): 27 | \begin{python} 28 | python prog1.py | python prog2.py 29 | \end{python} 30 | Eso es equivalente a hacer 31 | \begin{python} 32 | python prog1.py > temp.dat 33 | python prog2.py < temp.dat 34 | \end{python} 35 | pero sin la necesidad de crear el archivo temporal. 36 | 37 | Los pipes son muy útiles en unix, y se pueden encadenar. 38 | 39 | 40 | 41 | 42 | \section{Argumentos de la línea de comandos} 43 | 44 | Una manera más flexible y más útil para mandar información a un programa es a través de argumentos que se ponen en la mera línea de comandos. A menudo queremos 45 | mandar a un programa los valores de un parámetro, para después poder hacer barridos del mismo. 46 | 47 | Para hacerlo, Python provee una variable llamada \inl{argv}, que viene definida en el módulo \inl{sys}. Podemos ver qué es lo que contiene esta variable al correr un programa sencillo: 48 | \begin{python} 49 | from sys import argv 50 | 51 | print "Argumentos: argv" 52 | \end{python} 53 | Si ahora llamamos a nuestro programa con 54 | \begin{python} 55 | python prog.py 10 0.5 ising 56 | \end{python} 57 | entonces vemos que \inl{argv} es una lista de cadenas, cada una representando uno de los argumentos, empezando por el nombre del script. 58 | Por lo tanto, podemos extraer la información deseada con las herramientas normales de Python, por ejemplo 59 | \begin{python} 60 | from sys import argv 61 | T, h = map(float, argv[1:3]) 62 | modelo = argv[3] 63 | \end{python} 64 | 65 | Sin embargo, si no damos suficientes argumentos, entonces el programa fracasará. Podemos atrapar una \defn{excepción} de este tipo con un bloque \inl{try}\ldots\inl{except}: 66 | \begin{python} 67 | from sys import argv, exit 68 | try: 69 | T, h = map(float, argv[1:3]) 70 | modelo = argv[3] 71 | except: 72 | print "Sintaxis: python prog.py T h modelo" 73 | exit(1) 74 | \end{python} 75 | Es útil proveerle al usuario información acerca de la razón por la cual fracasó el programa. Aquí hemos utilizado la función \inl{exit} que viene también en el módulo \inl{sys}, para que salga del programa al encontrar un problema, pero eso no es obligatorio --podría poner valores por defecto de los parámetros en este caso, por ejemplo. 76 | 77 | 78 | \section{Llamando a otros programas} 79 | 80 | El módulo \inl{os} provee unas herramientas para mandar llamar a otros programas ``hijos'' desde un programa ``padre''\footnote{Hoy en día, se recomienda más bien el paquete \inl{subprocess} para esta funcionalidad, pero es más complicado.}. 81 | 82 | La función más útil es \inl{system}, que permite correr un comando a través de un nuevo \inl{bash}; podemos enviar cualquier comando que funciona en \inl{bash}, en particular podemos correr otros programas. La función acepta una cadena: 83 | \begin{python} 84 | from os import system 85 | system("ls") 86 | \end{python} 87 | 88 | Ahora podemos empezar a hacer cosas interesantes al construir los comandos con la sustitución de variables. Por ejemplo, si tenemos un programa \inl{prog.py} que acepta un argumento de la línea de comandos, podemos correrlo de manera consecutiva con distintos valores del parámetro con 89 | \begin{python} 90 | for T in range(10): 91 | comando = "python prog.py %g" % T 92 | system(comando) 93 | \end{python} 94 | 95 | Si queremos abrir un programa que se conectará al nuestro y recibirá comandos, utilizamos \inl{popen} para abrir un \emph{pipe}: 96 | \begin{python} 97 | from os import popen 98 | gp = popen("gnuplot -persist", "w") 99 | gp.write("plot sin(x)\n") 100 | gp.close() 101 | \end{python} 102 | 103 | Una manera fácil de hacer una animación es utilizar la terminal de GIF animado en \inl{gnuplot}. Para utilizar esta terminal, es necesario contar con una versión de \inl{gnuplot} compilada de manera adecuada, con la librería \inl{gd}. 104 | 105 | En la terminal de GIF animado, cada vez que uno ejecuta un \inl{plot}, otro cuadro se agrega a la animación. Por ejemplo: 106 | \begin{python} 107 | from os import popen 108 | from numpy import arange 109 | gp = popen("gnuplot", "w") 110 | gp.write("set term gif anim\n") 111 | gp.write("set out 'sin.gif'\n") # archivo de salida de gnuplot 112 | 113 | for a in arange(0., 10., 0.1): 114 | gp.write("plot sin(x + %g)\n title 'sin(x+%g)'\n" % (a, a) ) 115 | gp.write("set out\n") # cerrar el archivo de salida de gnuplot 116 | gp.close() 117 | \end{python} 118 | 119 | 120 | \section{Ejemplos} 121 | 122 | Veamos algunos ejemplos de lo que podemos hacer utilizando Python para controlar otros programas. 123 | La sustitución de variables juega un papel crucial. 124 | 125 | \subsection{Generando archivos sencillos con \LaTeX} 126 | Empecemos con una aplicación sencilla, en la cual utilizamos Python para crear un archivo de \LaTeX\ para una carta de aceptación de un congreso, para la cual necesitamos el nombre del autor y el título del cartel. 127 | 128 | Primero, para generar un archivo de \LaTeX, necesitamos poder manejar ciertos caracteres especiales en las cadenas. Para hacerlo, podemos poner \inl{r} al principio de la cadena para formar una cadena ``raw'' (``crudo''); Python automáticamente la convertirá en una cadena normal: 129 | \begin{python} 130 | s = r"\begin{document}" 131 | s 132 | print s 133 | \end{python} 134 | Además, Python nos permite declarar cadenas con varias líneas, al utilizar tres comillas. Así que un archivo de \LaTeX\ sencillo se puede crear con 135 | \begin{python} 136 | codigo_latex = r""" 137 | \documentclass{article} 138 | \usepackage{mathptmx} % fuente Times 139 | \begin{document} 140 | Cómo se puede crear un vector de 100 veces $-3$? 113 | 114 | Las funciones más comunes entre vectores ya están definidas en \inl{numpy}, entre las cuales se encuentran \inl{dot(a, b)} para productos escalares de dos vectores de la mismo longitud, y \inl{cross(a, b)} para el producto cruz de dos vectores de longitud $3$. 115 | 116 | Además, cualquier función matemática como \inl{sin} y \inl{exp} se puede aplicar directamente a un vector, y regresará un vector compuesto por esta función aplicada a cada entrada del vector, tipo \inl{map}. 117 | 118 | Es más: al definir una función el usuario, esta función normalmente también se pueden aplicar directamente a un vector: 119 | \begin{python} 120 | def gauss(x): 121 | return 1./ (sqrt(2.)) * exp(-x*x / 2.) 122 | 123 | gauss( r_[0:10] ) 124 | \end{python} 125 | 126 | \section{Extrayendo partes de un vector} 127 | Para extraer subpartes de un vector, la misma sintaxis funciona como para listas: se extraen componentes (entradas) individuales con 128 | \begin{python} 129 | a = array([0, 1, 2, 3]) 130 | print a[0], a[2] 131 | \end{python} 132 | y subvectores con 133 | \begin{python} 134 | b = a[1:3] 135 | \end{python} 136 | Nótese, sin embargo, que en este caso la variable \inl{b} \emph{no} es una \emph{copia} de esta parte de \inl{a}. Más bien, es una \defn{vista} de \inl{a}, así que ahora si hacemos 137 | \begin{python} 138 | b[1] = 10 139 | \end{python} 140 | entonces la entrada correspondiente de \inl{a} \emph{ 5 271 | a[a > 5] = 0 272 | \end{python} 273 | 274 | Además existe una función \inl{where}, que es como una versión vectorizada de \inl{if}: 275 | \begin{python} 276 | b = r_[0:16].reshape(4,4) 277 | c = list(b.flatten()) 278 | c.reverse() 279 | c = array(c).reshape(4,4) 280 | 281 | a = where(b < 5, b, c) 282 | \end{python} 283 | Este comando pone cada entrada de \inl{a} igual a la entrada correspondiente de \inl{b} si ésta es menor que $5$, o a la de \inl{c} si no. 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | \section{Números aleatorios} 292 | 293 | La biblioteca \inl{numpy} incluye un módulo amplio para manipular números aleatorios, llamado \inl{random}. 294 | Como siempre, las funciones se llaman, por ejemplo, \inl{random.random()}. Para facilitarnos la vida, podemos importar todas estas funciones al espacio de nombres con 295 | \begin{python} 296 | from numpy import * 297 | random? # informacion sobre el modulo 298 | from random import * # 'random' esta 299 | \end{python} 300 | o 301 | \begin{python} 302 | from numpy.random import * 303 | \end{python} 304 | Nótese que hay otro módulo \inl{random} que existe afuera de \inl{numpy}, con distinta funcionalidad. 305 | 306 | La funcionalidad básica del módulo es la de generar números aleatorios distribuidos de manera uniforme en el intervalo $[0,1)$: 307 | \begin{python} 308 | random() 309 | for i in xrange(10): 310 | random() 311 | \end{python} 312 | Al poner \inl{random(N)}, nos regresa un vector de números aleatorios de longitud \inl{N}. 313 | 314 | Para generar una matriz aleatoria, podemos utilizar 315 | \begin{python} 316 | rand(10, 20) 317 | \end{python} 318 | Para números en un cierto rango $[a, b)$, podemos utilizar 319 | \begin{python} 320 | uniform(-5, 5, 10) 321 | \end{python} 322 | 323 | 324 | También hay diversas funciones para generar números aleatorios con distribuciones no-uniformes, por ejemplo \inl{exponential(10)} y \inl{randn(10, 5, 10)} para una distribución normal, o \inl{binomial(10, 3, 100)}. 325 | 326 | 327 | 328 | 329 | 330 | \ej Calcula la distribución de distancias entre valores propios consecutivos de una matriz aleatoria real y simétrica. 331 | 332 | 333 | \section{Transformadas de Fourier} 334 | Otro submódulo útil de \inl{numpy} es \inl{fft}, que provee transformadas rápidas de Fourier: 335 | \begin{python} 336 | from numpy import * 337 | 338 | x = arange(1024) 339 | f = fft.fft(x) 340 | y = fft.ifft(f) 341 | linalg.norm( x - y ) 342 | \end{python} 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | -------------------------------------------------------------------------------- /matplotlib.tex: -------------------------------------------------------------------------------- 1 | \chapter{Gráficas con \texttt{matplotlib}} 2 | 3 | En este capítulo, veremos cómo podemos crear gráficas dentro de Python, usando el paquete \inl{matplotlib} y su entorno \inl{pylab}. 4 | 5 | \section{Entorno \inl{pylab}} 6 | El paquete \inl{matplotlib} dibuja las gráficas. Para integrar mejor este módulo con el uso interactivo, y en particular con \inl{ipython}, incluye un módulo \inl{pylab}, que provee muchos comandos de utilidad para manejar \inl{matplotlib}. 7 | 8 | La manera más efectiva de cargar la biblioteca \inl{pylab} es al mero momento de \emph{correr} \inl{ipython}: se da la opción \inl{-pylab} en la línea de comandos\footnote{Yo encuentro conveniente declarar un nuevo comando \texttt{pylab} agregando la línea \\ \texttt{alias pylab='ipython -pylab'} en el archivo \texttt{.bashrc} en mi directorio hogar.). Entonces se puede correr simplemente a poner \inl{pylab} en la línea de comandos.}: 9 | \begin{python} 10 | > ipython -pylab 11 | \end{python} 12 | Si todo funciona correctamente, deberías recibir el mensaje 13 | ``Welcome to pylab, a matplotlib-based Python environment.'' En este caso, ya se habrá cargado el entorno \inl{pylab}, que incluye 14 | el módulo \inl{matplotlib} para llevar a cabo gráficas, y también carga automáticamente \inl{numpy}, por lo cual no es necesario volver a cargar estos módulos para uso interactivo. [Sí es necesario cargarlos explícitamente en cualquier script que ocupe gráficas.] 15 | 16 | \section{Gráficas básicas} 17 | El comando principal de \inl{matplotlib} / \inl{pylab} es \inl{plot}. Acepta uno o dos listas o vectores de \inl{numpy}, que corresponden a las coordenadas $y$ (si hay un solo vector) o $x$ y $y$ de una gráfica 2D. 18 | Por ejemplo, si queremos graficar los cuadrados de los números de $1$ a $10$, podemos hacer 19 | \begin{python} 20 | x = arange(10) 21 | y = x * x 22 | plot(x, y) 23 | \end{python} 24 | Si queremos puntos en lugar de líneas, hacemos 25 | \begin{python} 26 | plot(x, y, 'o') 27 | \end{python} 28 | al estilo de MATLAB. (De hecho, \inl{pylab} se creó basándose en el comportamiento de MATLAB.) 29 | 30 | Nótese que por defecto las gráficas se \emph{acumulan}. Este comportamiento se puede modficar con \inl{hold(False)}, que reemplaza las gráficas con las nuevas, y \inl{hold(True)}, que regresa a la funcionalidad por defecto. También se puede utilizar \inl{clf()} para limpiar la figura. 31 | 32 | 33 | 34 | 35 | La ventana que cree \inl{matplotlib} incluye botones para poder hacer acercamientos y moverse a través de la gráfica. 36 | También incluye un botón para exportar la figura a un archivo en distintos formatos. Los formatos de principal interés son PDF, que es un formato ``vectorial'' (que incluye las instrucciones para dibujar la figura), que da la calidad necesaria para las publicaciones, y PNG, que da una imagen de la figura, y es adecuada para páginas web. 37 | 38 | \section{Cambiando el formato} 39 | 40 | Hay distintos tipos de líneas y puntos disponibles, y se puede modificar el tamaño de ambos. Todas las opciones están disponible a través de la documentación de \inl{plot}, a través de \inl{plot?}. Además, los colores se pueden especificar explícitamente: 41 | \begin{python} 42 | x = arange(10) 43 | plot(x, x**2, 'ro', x, 2*x, 'gx') 44 | plot(x, 3*x, 'bo-', linewidth=3, markersize=5, markerfacecolor='red', markeredgecolor='green', markeredgewidth=2) 45 | \end{python} 46 | Se pueden dar cualquier número de gráficas que dibujar en un solo comando. Si el formato no se da explícitamente, entonces \inl{matplotlib} escoge el siguiente de una secuencia razonable de estilos. 47 | 48 | \section{Etiquetas} 49 | 50 | Se puede proporcionar un título de la gráfica con \inl{title} 51 | \begin{python} 52 | title("Algunas funciones sencillas") 53 | \end{python} 54 | 55 | 56 | Los ejes se pueden etiquetar con 57 | \begin{python} 58 | xlabel("x") 59 | ylabel("f(x)") 60 | \end{python} 61 | Una bondad de \inl{matplotlib} es que las etiquetas se pueden expresar en formato \LaTeX\ y se interpretará automáticamente de la forma adecuada: 62 | \begin{python} 63 | xlabel("$x$") 64 | ylabel("$x^2, 2x, \exp(x)$", fontsize=16) # cambia tamano de fuente 65 | \end{python} 66 | 67 | También se pueden colocar etiquetas arbitrarias con 68 | \begin{python} 69 | text(4.6, 35, "Punto de\ninteres") 70 | \end{python} 71 | Si se le asigna a una variable, entonces se puede volver a remover con 72 | \begin{python} 73 | etiq = text(4.6, 35, "Punto de\ninteres") 74 | etiq.remove() 75 | draw() 76 | \end{python} 77 | Es necesario llamar a \inl{draw()} para volver a dibujar la figura. 78 | 79 | \section{Figuras desde scripts} 80 | Una vez que una figura se vuelve complicada, es necesario recurrir a un script que contenga las instrucciones para dibujarla. Eso es \emph{sumamente importante} en particular para preparar figuras para un documento, donde se ajustará varias veces una sola figura hasta que quede bien. 81 | 82 | Para utilizar \inl{matplotlib} desde un script, es necesario incluir la biblioteca \inl{pylab}. Luego se puede utilizar \inl{plot}. Para ver la imagen, a veces es necesario poner el comando \inl{show()}: 83 | \begin{python} 84 | from pylab import * 85 | x = arange(10) 86 | plot(x, x**2) 87 | show() 88 | \end{python} 89 | 90 | 91 | Eso también es necesario al utilizar \inl{pylab} desde \inl{ipython} sin poner \inl{ipython -pylab}, pero en este caso, es necesario cerrar la gráfica para poder volver a utilizar el \inl{ipython}. 92 | 93 | \section{Escalas logarítmicas} 94 | Para utilizar ejes con escalas logarítimicas, hay tres funciones: \inl{loglog}, \inl{semilogy} y \inl{semilogx}. 95 | Se utilizan en lugar de \inl{plot}: 96 | \begin{python} 97 | t = arange(1000) 98 | p = t**(-0.5) 99 | loglog(t, p, 'o') 100 | \end{python} 101 | 102 | 103 | \section{Múltiples dibujos} 104 | Está fácil hacer múltiples dibujos alineados con \inl{subplot}. Su sintaxis es 105 | \begin{python} 106 | subplot(num_renglones, num_columnas, num_dibujo) 107 | \end{python} 108 | Es decir, se especifican el número de renglones y columnas que uno quiere, y el último número especifica cuál dibujo es los \inl{num_renglones} $\times$ \inl{num_columnas} es. Aquí está un ejemplo adaptado de la documentación de \inl{matplotlib}: 109 | \begin{python} 110 | def f(t): 111 | """Oscilacion amortiguada""" 112 | c = cos(2*pi*t) 113 | e = exp(-t) 114 | return c*e 115 | 116 | t1 = arange(0.0, 5.0, 0.1) 117 | t2 = arange(0.0, 5.0, 0.02) 118 | t3 = arange(0.0, 2.0, 0.01) 119 | 120 | subplot(211) 121 | l = plot(t1, f(t1), 'bo', t2, f(t2), 'k--', markerfacecolor='green') 122 | grid(True) 123 | title('Amortiguacion de oscilaciones') 124 | ylabel('Amortiguada') 125 | 126 | subplot(212) 127 | plot(t3, cos(2*pi*t3), 'r.') 128 | grid(True) 129 | xlabel('tiempo $t$ (s)') 130 | ylabel('No amortiguada') 131 | show() 132 | \end{python} 133 | 134 | \section{Animaciones} 135 | Las gráficas hechas en \inl{matplotlib} se pueden animar. La manera más fácil es simplemente redibujar la gráfica completa cada vez que se cambian los datos. Sin embargo, eso no es eficiente, ya que se tiene que recalcular cada vez las etiquetas etc. 136 | 137 | Una mejor solución es que cada vez se cambie simplemente el contenido de datos de la gráfica. Primero es necesario asignarle a la gráfica un nombre: 138 | \begin{python} 139 | from pylab import * 140 | x = arange(10) 141 | y = x*x 142 | ion() 143 | p, = plot(x, y) 144 | 145 | for a in arange(0, 10, 0.1): 146 | x = arange(10) + a 147 | p.set_xdata(x) 148 | draw() 149 | \end{python} 150 | Nótese el comando \inl{ion()} (``interactividad prendida"). 151 | El comando \inl{p, = plot(x,y)} es necesario ya que el comando \inl{plot} regresa una lista de todos los objetos en el plot. Se utiliza esta asignación de tuplas para extraer realmente el primer elemento; sería equivalente (pero menos natural) poner \inl{p = plot(x,y)[0]}. 152 | 153 | 154 | \section{Otros tipos de gráficas} 155 | Aparte del tipo básico de gráficas que hemos visto hasta ahora, que permiten llevar a cabo gráficas de datos como puntos y/o líneas, existe en \inl{matplotlib} una gran variedad de otros tipos de gráficas posibles; se refiere a la página principal \url{http://matplotlib.sourceforge.net} y a la página 156 | \url{http://www.scipy.org/Cookbook/Matplotlib} que contiene muchos ejemplos. 157 | 158 | Por ejemplo, podemos visualizar matrices 2D como ``heat-maps'' (mapas en los cuales el color corresponde al valor de la matriz) con \inl{pcolor} y \inl{imshow}. Nótese que para crear una figura cuadrada, se puede utilizar 159 | \begin{python} 160 | f = figure( figsize=(8,8) ) 161 | \end{python} 162 | 163 | Otro tipo de gráfica disponible es un histograma. \inl{pylab} puede calcular y dibujar la gráfica en un solo comando: 164 | \begin{python} 165 | from pylab import randn, hist 166 | x = randn(10000) 167 | hist(x, 100, normed=True) 168 | \end{python} 169 | Hay una función \inl{histogram} en \inl{numpy} que calcula histogramas sin dibujarlos. 170 | 171 | Aquí va una versión tomada de la documentación: 172 | \begin{python} 173 | import numpy as np 174 | import matplotlib.mlab as mlab 175 | import matplotlib.pyplot as plt 176 | 177 | mu, sigma = 100, 15 178 | x = mu + sigma*np.random.randn(10000) 179 | 180 | # the histogram of the data 181 | n, bins, patches = plt.hist(x, 50, normed=1, facecolor='green', alpha=0.75) 182 | 183 | # add a 'best fit' line 184 | y = mlab.normpdf( bins, mu, sigma) 185 | l = plt.plot(bins, y, 'r--', linewidth=1) 186 | 187 | plt.xlabel('Smarts') 188 | plt.ylabel('Probability') 189 | plt.title(r'$\mathrm{Histogram\ of\ IQ:}\ \mu=100,\ \sigma=15$') 190 | plt.axis([40, 160, 0, 0.03]) 191 | plt.grid(True) 192 | 193 | plt.show() 194 | \end{python} 195 | 196 | 197 | 198 | \section{Uso avanzado de \inl{matplotlib}} 199 | Para usos más avanzados de \inl{matplotlib}, es necesario entender mejor la estructura interna del paquete, que es justamente lo que esconde \inl{pylab}. Por ejemplo, para colocar una flecha en un dibujo, utilizamos ``patches'' (``parches''): 200 | \begin{python} 201 | from pylab import * 202 | 203 | x = arange(10) 204 | y = x 205 | 206 | plot(x, y) 207 | arr = Arrow(2, 2, 1, 1, edgecolor='white') 208 | ax = gca() # obtener el objeto tipo "eje" ("axis") 209 | ax.add_patch(arr) 210 | arr.set_facecolor('g') 211 | show() 212 | \end{python} 213 | 214 | 215 | \section{Mallas con \texttt{meshgrid}} 216 | 217 | 218 | 219 | Por lo tanto, es necesario primero construir la malla donde se calculará el campo vectorial. Esto se hace con \inl{meshgrid}, que acepta dos vectores 1D que dan las coordenadas $x$ y $y$ de los puntos de la malla. \inl{meshgrid} construye una malla cuyos vértices son los puntos en el producto cartesiano de los dos conjuntos de puntos. Regresa una tupla de dos matrices, que dan las coordenadas $x$ y $y$ respectivamente de los puntos de la malla: 220 | \begin{python} 221 | x = r_[-5:5:11j] 222 | y = r_[-5:5:11j] 223 | 224 | X, Y = meshgrid(x, y) 225 | print X, Y 226 | \end{python} 227 | Así que \inl{meshgrid} en algún sentido provee un mapa de las entradas de la matriz a sus coordenadas en el espacio real 2D. 228 | 229 | El punto de esta construcción es que ahora las funciones se pueden evaluar en \emph{cada punto de la red al mismo tiempo}. Por ejemplo, para tener una matriz que representa la suma de las componentes $x$ y $y$ en cada punto de la malla, hacemos 230 | \begin{python} 231 | Z = X + Y 232 | \end{python} 233 | Para tener la distancia de la origen en cada punto, hacemos 234 | \begin{python} 235 | R = sqrt(X*X + Y*Y) 236 | \end{python} 237 | 238 | Una abreviación del comando \inl{meshgrid}, usando una notación indicial parecida a la que ocupa \inl{r_}, es 239 | \begin{python} 240 | X, Y = mgrid[-5:5:11j, -5:5:11j] 241 | \end{python} 242 | 243 | 244 | 245 | \section{Campos vectoriales} 246 | Los campos vectoriales se pueden dibujar con la función \inl{quiver}\footnote{Eso es una broma nerd: ``quiver'' quiere decir ``carcaj'' (un objeto donde se guardan las flechas).}. Esta función acepta 4 matrices, $X$ y $Y$ que dan las coordenadas $X$ y $Y$ de los puntos de la malla donde se especifica el campo, y $U$ y $V$, que son las componentes de los vectores que dibujar en cada punto. 247 | 248 | Por ejemplo, podemos dibujar un campo radial al poner 249 | \begin{python} 250 | X, Y = mgrid[-5:5:11j, -5:5:11j] 251 | quiver(X, Y, X, Y) 252 | \end{python} 253 | ya que en el punto $(x,y)$ de la malla ponemos el vector $(x,y)$. 254 | Lo podemos colorear según el valor de la distancia del origen con 255 | \begin{python} 256 | X, Y = mgrid[-5:5:11j, -5:5:11j] 257 | R = sqrt(X*X + Y*Y) 258 | quiver(X, Y, X, Y, R) 259 | \end{python} 260 | 261 | 262 | Algunos campos más interesantes son 263 | \begin{python} 264 | quiver(X, Y, Y, X) 265 | quiver(X, Y, Y, -X) 266 | \end{python} 267 | Resulta que se ven un poco ``deformados'', ya que cada flecha se dibuja empezando en el punto dado de la malla. 268 | Se ve más ordenado al colocar el punto medio de la flecha en el punto de la malla: 269 | \begin{python} 270 | quiver(X, Y, Y, X, R, pivot='middle') 271 | \end{python} 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | \section{Gráficas en 3D} 283 | En versiones recientes de \inl{matplotlib}, hay soporte limitado para gráficas en 3D. 284 | El módulo relevante es \inl{mplot3d}. 285 | Un ejempo tomado de la documentación: 286 | \begin{python} 287 | from mpl_toolkits.mplot3d import Axes3D 288 | from matplotlib import cm 289 | import matplotlib.pyplot as plt 290 | import numpy as np 291 | 292 | fig = plt.figure() 293 | ax = Axes3D(fig) 294 | X = np.arange(-5, 5, 0.25) 295 | Y = np.arange(-5, 5, 0.25) 296 | X, Y = np.meshgrid(X, Y) 297 | R = np.sqrt(X**2 + Y**2) 298 | Z = np.sin(R) 299 | ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet) 300 | 301 | plt.show() 302 | \end{python} 303 | 304 | \section{Interacción con el mouse y el teclado} 305 | Se puede interactuar con el mouse y con el teclado de una manera relativamente sencilla. 306 | 307 | Para interactuar con el mouse, creamos una función que se llamará cuando \inl{pylab} note que hay un evento que involucre el mouse. 308 | Esta función toma un solo argumento, que suele llamarse \inl{event}. \inl{pylab} manda a la función un objeto que representa el evento, incluyendo cuál botón se 309 | presionó y en que posición de la gráfica. La función se registra ante \inl{pylab} con la función \inl{connect}. 310 | 311 | Lo mismo tiene para el teclado. Así que el código más sencillo es el siguiente. Nótese que es necesario que haya una gráfica pre-existente antes de poder interactuar con ella. 312 | \begin{python} 313 | from pylab import * 314 | 315 | def teclado(event): 316 | print "Se tecleo %s en la posicion (%g, %g)" % event.key, event.xdata, event.ydata 317 | 318 | def mouse(event): 319 | if event.button != 1: 320 | return 321 | x,y = event.xdata, event.ydata 322 | print "Se oprimio el boton izquierdo en (%g, %g)" % (x, y) 323 | 324 | x = arange(10) 325 | y = x*x 326 | p, = plot(x, y) 327 | 328 | show() 329 | 330 | connect('button_press_event', mouse) 331 | connect('key_press_event', teclado) 332 | \end{python} --------------------------------------------------------------------------------