Anda di halaman 1dari 343

Matemticas

y
programacin
con Python
N. Aguilera
Agosto de 2013
Contenidos
. Preliminares
.. Organizacin y convenciones que usamos . . . . . . .
.. Por qu Python? . . . . . . . . . . . . . . . . . . . . .
... Censura, censura, censura . . . . . . . . . . . . .
.. La versin . . . . . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
.. Agradecimientos . . . . . . . . . . . . . . . . . . . . . .
Parte I : Elemenros
. El primer contacto
.. Funcionamiento de la computadora . . . . . . . . . . .
.. Bits y bytes . . . . . . . . . . . . . . . . . . . . . . . . .
.. Programas y lenguajes de programacin . . . . . . . .
.. Python y IDLE . . . . . . . . . . . . . . . . . . . . . . .
. Python como calculadora
.. Operaciones con nmeros . . . . . . . . . . . . . . . .
.. El mdulo math . . . . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
Pg. Conrendos
. Tipos de datos bsicos
.. Por qu hay distintos tipos de datos? . . . . . . . . . .
.. Tipo lgico . . . . . . . . . . . . . . . . . . . . . . . . .
.. Cadenas de caracteres . . . . . . . . . . . . . . . . . . .
.. print (imprimir) . . . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
. Variables y asignaciones
.. Asignaciones en Python . . . . . . . . . . . . . . . . . .
.. None . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
. Mdulos
.. Mdulos propios . . . . . . . . . . . . . . . . . . . . . .
.. Ingreso interactivo . . . . . . . . . . . . . . . . . . . . .
.. Documentacin y comentarios en el cdigo . . . . . .
.. Usando import . . . . . . . . . . . . . . . . . . . . . . .
. Funciones
.. Ejemplos simples . . . . . . . . . . . . . . . . . . . . . .
.. Funciones numricas . . . . . . . . . . . . . . . . . . .
.. Python y variables lgicas . . . . . . . . . . . . . . . . .
.. Variables globales y locales . . . . . . . . . . . . . . . .
. Tomando control
.. if (si) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.. while (mientras) . . . . . . . . . . . . . . . . . . . . . .
.. El algoritmo de Euclides . . . . . . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
. Sucesiones
.. ndices y secciones . . . . . . . . . . . . . . . . . . . . .
.. tuple (tupla) . . . . . . . . . . . . . . . . . . . . . . . .
.. list (lista) . . . . . . . . . . . . . . . . . . . . . . . . .
Conrendos Pg.
.. range (rango) . . . . . . . . . . . . . . . . . . . . . . .
.. Operaciones comunes . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
. Recorriendo sucesiones
.. for (para) . . . . . . . . . . . . . . . . . . . . . . . . . .
.. Listas por comprensin . . . . . . . . . . . . . . . . . .
.. Filtros . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
. Cuatro variaciones sobre un tema
.. Reloj... no marques las horas . . . . . . . . . . . . . . .
.. Algo de matemtica fnanciera . . . . . . . . . . . . . .
.. Polinomios . . . . . . . . . . . . . . . . . . . . . . . . .
.. Escritura en base entera . . . . . . . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
. Formatos y archivos de texto
.. Formatos . . . . . . . . . . . . . . . . . . . . . . . . . .
.. Archivos de texto . . . . . . . . . . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
Parte II : Popurr|
. Nmeros aleatorios
.. Funciones de nmeros aleatorios en Python . . . . . .
.. Qu son los nmeros aleatorios? . . . . . . . . . . . .
.. Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . .
.. Mtodos de Monte Carlo . . . . . . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
Pg. v Conrendos
. Clasifcacin y bsqueda
.. Clasifcacin . . . . . . . . . . . . . . . . . . . . . . . .
.. Listas como conjuntos . . . . . . . . . . . . . . . . . . .
.. Bsqueda binaria . . . . . . . . . . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
. El mdulo gracar y funciones numricas
. Clculo numrico elemental
.. La codifcacin de decimales . . . . . . . . . . . . . . .
.. Errores numricos . . . . . . . . . . . . . . . . . . . . .
.. Mtodos iterativos: puntos fjos . . . . . . . . . . . . .
.. El mtodo de Newton . . . . . . . . . . . . . . . . . . .
.. El mtodo de la biseccin . . . . . . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
. Nmeros enteros
.. Ecuaciones diofnticas y la tcnica de barrido . . . . .
.. Cribas . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.. Divisibilidad y nmeros primos . . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
. Grafos
.. Ensalada de defniciones . . . . . . . . . . . . . . . . .
.. Representacin de grafos . . . . . . . . . . . . . . . . .
.. Recorriendo un grafo . . . . . . . . . . . . . . . . . . .
.. Ejercicios Adicionales . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
Conrendos Pg. v
. Recursin
.. Introduccin . . . . . . . . . . . . . . . . . . . . . . . .
.. Funciones defnidas recursivamente . . . . . . . . . . .
.. Nmeros de Fibonacci . . . . . . . . . . . . . . . . . .
.. Ventajas y desventajas de la recursin . . . . . . . . . .
.. Los Grandes Clsicos de la Recursin . . . . . . . . . .
.. Contando objetos combinatorios . . . . . . . . . . . .
.. Las grandes listas . . . . . . . . . . . . . . . . . . . . . .
.. yield . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.. Generando objetos combinatorios . . . . . . . . . . . .
.. Ejercicios adicionales . . . . . . . . . . . . . . . . . . .
.. Comentarios . . . . . . . . . . . . . . . . . . . . . . . .
Parte III : Apndces
Apndice A. Mdulos y archivos mencionados
dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
dearchivoaconsola . . . . . . . . . . . . . . . . . . . . . . . .
decimales . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
eratostenes . . . . . . . . . . . . . . . . . . . . . . . . . . . .
euclides2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
fargumento . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ocal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
gr1sobrex . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
grafos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
grbiseccion . . . . . . . . . . . . . . . . . . . . . . . . . . . .
grexplog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
grgrsimple . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
grnewton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
grpuntojo . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
grseno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
holamundo . . . . . . . . . . . . . . . . . . . . . . . . . . . .
holapepe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Pg. v Conrendos
ifwhile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
numerico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
recursion1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
recursion2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
santosvega.txt . . . . . . . . . . . . . . . . . . . . . . . . . .
sumardos . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
tablaseno . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Apndice B. Notaciones y smbolos
B.. Lgica . . . . . . . . . . . . . . . . . . . . . . . . . . . .
B.. Conjuntos . . . . . . . . . . . . . . . . . . . . . . . . . .
B.. Nmeros: conjuntos, relaciones, funciones . . . . . . .
B.. Nmeros importantes en programacin . . . . . . . .
B.. En los apuntes . . . . . . . . . . . . . . . . . . . . . . .
B.. Generales . . . . . . . . . . . . . . . . . . . . . . . . . .
Parte IV : lndces
Comandos de Python que usamos
ndice de fguras y cuadros
Autores mencionados
Bibliografa
ndice alfabtico
Captulo
Preliminares
Estos son apuntes de un curso introductorio a la resolucin de
problemas matemticos usando la computadora y el lenguaje de pro-
gramacin Python.
La primera parte es el ncleo del curso y la mayora de sus conteni-
dos son comunes a otros cursos iniciales de programacin. Comenza-
mos viendo tipos de datos, funciones y estructuras de control, pasamos
luego al manejo de secuencias, terminando con el manejo elemental
de archivos de texto.
En la segunda parte vemos algunos temas ms directamente relacio-
nados con matemticas: nmeros aleatorios y simulacin, clasifcacin
y bsqueda, resolucin iterativa de ecuaciones de una variable, nme-
ros enteros, grafos, terminando con recursin.
A diferencia de los cursos tradicionales de programacin, veremos
muy poco de aplicaciones informticas como bases de datos, inter-
faces grfcas o internet: el nfasis es en matemticas y algoritmos,
intentando ir ms all de apretar botones.
Trataremos de no apartarnos demasiado de las estructuras disponi-
bles en lenguajes procedimentales, aunque ser inevitable mencionar
algunas particularidades de Python.
En este sentido, es conveniente tener siempre presente que:
Pg. z Cap|rulo t. Prelmnares
Este es un curso de resolucion de problemas
matematicos con la computadora y no de Python.
Por otra parte hay muy poca teora, que se habr visto o se ver en
otros cursos: lo esencial aqu son los ejercicios.
En casi todos los temas habr algunos ejercicios rutinarios y otros
que no lo son tanto. Algunos pensarn que el material presentado es
excesivo, y habr otros que querrn resolver ms ejercicios o ejercicios
ms avanzados, y para ellos en algunos captulos se incluye una seccin
de ejercicios adicionales.
.. Organizacin y convenciones que usamos
En los distintos captulos se presentan los temas y ejercicios, agru-
pados en secciones y a veces subsecciones. Secciones y ejercicios estn
numerados comenzando con en cada captulo, de modo que la sec-
cin . se refere a la seccin del captulo , y el ejercicio . se
refere al ejercicio del captulo .
La versin electrnica del libro est diseada para que pueda ser
leda sin muchos inconvenientes en tabletas, y ofrece la ventaja de
vnculos (links) remarcados en azul.
Lo que escribiremos en la computadora y sus respuestas se indican
con otro tipo de letra y color, y fragmentos ms extensos se
ponen en prrafos con una raya vertical a la izquierda:
como ste
A veces incluimos los smbolos >>> para destacar la diferencia
entre lo que escribimos y lo que responde la computadora. En este
caso, escribimos en el rengln donde est >>> y la respuesta de la
computadora aparece sin esos smbolos.
Muchas veces usaremos indistintamente la notacin de Python
como 12 o f(x), y la notacin matemtica como o f (x), esperando
que no de lugar a confusin.
t.z. Por qu Pyrhon? Pg.
Siguiendo la tradicin norteamericana, la computadora expresa
los nmeros poniendo un punto decimal en vez de la coma, y
para no confundirnos seguimos esa prctica. As, . es un nmero
entre y , mientras que es un nmero entero, mayor que mil. A
veces dejamos pequeos espacios entre las cifras para leer mejor los
nmeros, como en ..
En el apndice Aestn varios mdulos o funciones que son propios
de estos apuntes y no estn incluidos en la distribucin de Python.
En el apndice B hay una sntesis de notaciones, convenciones o
abreviaturas. En la seccin B. se explican los garabatos como e, ,
k... y varios ms!
Al fnal se incluyen ndices que tal vez no sean necesarios en la
versin electrnica, pero esperamos que sean tiles en la impresa.
.. Por qu Python?
Por muchos aos usamos Pascal como lenguaje para los apuntes.
Pascal fue ideado por N. Wirth hacia para la enseanza de la
programacin y fue un lenguaje popular por varias dcadas, pero ha
cado en desuso en los ltimos aos, y es difcil conseguir versiones
recientes para las distintas plataformas. De cualquier forma, tiene dos
inconvenientes mayores: no tiene un generador nativo de nmeros
aleatorios, y carece de elementos grfcos, casi impensado en estos das.
Actualmente no hay lenguajes destinados a la enseanza de la
programacin desde un enfoque matemtico, que sean gratuitos y de
amplia difusin.
Entre los lenguajes ms populares hoy,
()
hemos elegido Python
(pronunciado paizon), http://www.python.org, creado por G. van
Rossum hacia .
La eleccin de Python se debe a varios motivos, entre ellos:
Es fcil hacer los primeros programas, y se puede comenzar con
()
Ver http://www.tiobe.com/index.php/content/paperinfo/tpci/.
Pg. { Cap|rulo t. Prelmnares
un modo prcticamente interactivo escribiendo en una venta-
na tipo terminal, caracterstica compartida por sistemas como
Mathematica, Matlab o Maple.
Los algoritmos se pueden implementar rpidamente usando fun-
ciones predefnidas, y en especial listas con fltros, caracterstica
compartida tambin con, por ejemplo, Mathematica.
Las funciones pueden ser argumentos de otras funciones.
No tiene lmite para el tamao de enteros.
Es gratis y est disponible para las principales plataformas (Li-
nux, MS-Windows, Mac OS y otras), y las nuevas versiones son
lanzadas simultneamente.
Tiene un entorno integrado para el desarrollo (IDLE).
La distribucin incluye al mdulo tkinter con el que se puede
acceder a las facilidades grfcas de Tcl/Tk, permitiendo un en-
torno grfco independiente de la plataforma. Estas facilidades
son usadas por IDLE, de modo que la integracin es estrecha y
seguida muy de cerca.
La distribucin ofcial incluye una amplia variedad de extensio-
nes (mdulos), entre los que nos interesan los de matemticas
(math y random).
Pero tambin tiene sus desventajas para la enseanza:
No tiene un conjunto pequeo de instrucciones.
Es posible hacer una misma cosa de varias formas distintas, lo
que confunde a los principiantes.
La sintaxis no es consistente.
Por ejemplo:
print es una funcin, pero return no lo es,
sort y reverse modifcan una lista pero sorted da una
lista y reversed da un iterador.
El resultado de int(str(1)) es como uno esperara, pero
bool(str(False)) da True.
t.z. Por qu Pyrhon? Pg. y
Expresiones que no tienen sentido en matemticas son vlidas
en Python, como 3 + False < 5 and True.
Admitiremos algunas expresiones comunes a otros lenguajes
de programacin como los cortocircuitos lgicos.
Esto hace que, a diferencia del curso con Pascal, dediquemos una
buena parte del tiempo a estudiar el lenguaje, tratando de entender su
idiosincrasia.
... Censura, censura, censura
Para organizarnos mejor y no enloquecernos ponemos algunas
restricciones para el uso de Python. Por ejemplo:
De los mas de oo modulos que trae la
distribucion, solo permitiremos el uso explcito de
math y random.
Varios mdulos se usanimplcitamente al iniciar IDLEy al trabajar
con grfcos.
Esto nos trae a que hay muchas cosas de programacin en general
y de Python en particular que no veremos. Entre otras:
No estudiaremos diccionarios (dict) o conjuntos (set).
Usaremos diccionarios sin mayores explicaciones (apretaremos
botones) en los mdulos grfcos.
No veremos cmo defnir clases, ni programacin orientada a
objetos en general, ni claro construcciones asociadas como
decoradores.
Usaremos algunos mtodos ya existentes de Python, por ejem-
plo para listas.
Pg. o Cap|rulo t. Prelmnares
No veremos manejo de errores o excepciones y sentencias rela-
cionadas (try, assert, debug, with, etc.).
No veremos cmo defnir argumentos opcionales en funciones,
aunque los usaremos en las funciones predefnidas como print
o sort.
Veremos muy poco de generadores (slo funciones defnidas
usando yield en el captulo ).
No veremos construcciones de programacin funcional como
filter, map, y zip, an cuando son comunes a otros lenguajes.
En la pgina hay un resumen de los comandos de Python que
vemos, sealando la primera pgina donde aparecen. Es posible que
falten algunos, pero en general son los nicos admitidos y no deben
usarse otros.
Si decimos que no veremos alguna instruccion o
modulo de Python en el curso, esta prohibido
usarla en la resolucion de los ejercicios.
Terminamos destacando una convencin muy importante.
Un prrafo con el smbolo contiene construcciones de Python
que, aunque tal vez vlidas, hay que evitar a toda costa. Son construc-
ciones confusas, o absurdas en matemticas, o inefcientes computacio-
nalmente, o no se usan en otros lenguajes, etc.:
Las construcciones sealadas con no deben
usarse en este curso.
t.. La versn zot Pg. ,
.. La versin
Estas notas se van modifcando en base a la experiencia que se
gana en el dictado del curso, de modo que en el transcurso de los aos
hay temas que cambian, otros se eliminan, otros se agregan, y otros...
reaparecen!
Esta versin no es diferente. Entre los cambios ms destacados:
Las notas se dividieron en dos partes: una ms bsica, comn a
casi cualquier primer curso de programacin, y otra de tpicos
ms cercanos a matemticas.
El captulo intenta unifcar conceptos dispersos en versiones
anteriores, tratando de llamar la atencin de los alumnos. Uno
de los hilos conductores es la regla de Horner, que antes estaba
en el captulo de clculo numrico.
Dejamos el estudio de grafos con pesos, pues son tcnicas difci-
les de aplicar directamente a otros problemas.
Desaparecieron muchas instrucciones de Python (del, remove,
join, extend y otras), tratando de reducir la cantidad de instruc-
ciones disponibles y reforzar el aprendizaje del uso de ndices.
En cambio, apareci yield (y next) en la generacin de objetos
combinatorios.
.. Comentarios
Los temas y formas de abordarlos estn inspirados en Wirth
(), Kernighan y Ritchie (), y los tres primeros volmenes
de Knuth (a; b; ) en lo referente a programacin,
y de Gentile () y Engel () en cuanto a basar el curso en
resolucin de problemas (y varios de los temas considerados).
Los primeros captulos siguen ideas de las presentaciones de los
libros de Mathematica (Wolfram, , y siguientes ediciones), y
el mismo tutorial de Python.
Pg. 8 Cap|rulo t. Prelmnares
El libro de Litvin y Litvin () trabaja con Python con una
flosofa similar a la nuestra, pero a nivel de secundaria y est en
ingls.
Otro libro con una flosofa parecida es el de Sedgewick y
Wayne (). Es algo ms avanzado y toca temas que no vemos
(y al revs). Tambin est en ingls y trabaja con Java.
A los que quieran aprender ms les sugerimos los libros ya men-
cionados de Wirth () y Sedgewick y Wayne () y, para un
estudio ms profundo, los de Knuth (a; b; ).
Hemos tratado de incluir referencias bibliogrfcas sobre temas
y problemas particulares, pero muchos pertenecen al folklore
y es difcil determinar el origen.
La mayora de las referencias histricas estn tomadas de MacTu-
tor History of Mathematics, Wolfram MathWorld y WikipediA.
A quienes les haya picado el bichito les sugerimos tomar pro-
blemas o participar en las competencias estudiantiles de la ACM
(Association for Computing Machinery) en las que estudiantes
de nuestro pas participan exitosamente desde hace varios aos.
.. Agradecimientos
Agradezco a los muchos docentes y alumnos que infuyeron en los
cambios y la deteccin de errores (tipogrfcos o conceptuales).
Especialmente quiero agradecer a Luis Bianculli, Jorge DEla, Ma-
ra Fernanda Golobitsky, Egle Haye, Alberto Marchi, Martn Marques
y Marcela Morvidone, con quienes he tenido el placer de trabajar.

Parte I
Elemenros
Captulo
El primer contacto
En este captulo damos breves descripciones del funcionamiento
de la computadora, de los programas y los lenguajes de programacin,
para terminar con nuestro primer encuentro directo con Python.
.. Un poco (muy poco) sobre cmo funciona la
computadora
La computadora es una mquina que toma datos de entrada, los
procesa y devuelve resultados, tambin llamados datos de salida, como
esquematizamos en la fgura .. Los datos, ya sean de entrada o salida,
pueden ser simples como nmeros o letras, o mucho ms complicados
como una matriz, una base de datos o una pelcula.
En el modelo de computacin que usaremos, el procesamiento lo
realiza una unidad central de procesamiento o CPU (Central Processing
Unit), que recibe y enva datos a un lugar llamado memoria de la
Entrada Procesamiento Salida
Figura .: Esquema de entrada, procesamiento y salida.
z.t. Punconamenro de la compuradora Pg. tt
teclado
ratn
pantalla
discos
impresora
otros
memoria CPU
Figura .: Esquema de transferencia de datos en la computadora.
computadora.
As, imaginamos que lo que escribimos en el teclado no es procesa-
do directamente por la CPU, sino que es traducido adecuadamente y
alojado en la memoria previamente. Tenemos entonces un esquema
como el de la fgura .. Los elementos a la izquierda permiten que
la computadora intercambie datos con el exterior (como el teclado
o la pantalla) o los conserve para uso posterior (como el disco), y la
verdadera accin est entre la memoria y la CPU.
Aunque las computadoras modernas suelen tener ms de una CPU,
en nuestro modelo consideraremos que hay una sola. Del mismo modo,
consideraremos que la CPU lee y escribe los datos de la memoria
secuencialmente uno a la vez a pesar de que las computadoras
actuales pueden ir leyendo y escribiendo simultneamente varios datos.
Finalmente, las instrucciones que sigue la CPU forman parte de
los datos en la memoria que se procesarn. Es decir, la CPU lee ins-
trucciones en la memoria que le dicen qu otros datos (que pueden ser
ms instrucciones) tomar de la memoria y qu hacer con ellos.
Resumiendo, y muy informalmente, nuestro modelo tiene las si-
guientes caractersticas:
Hay una nica CPU,
que slo intercambia datos con la memoria,
Pg. tz Cap|rulo z. El prmer conracro
1 0 1 0 1 0 0 1
bits
byte
Figura .: Un byte de bits.
este intercambio es secuencial, y
las instrucciones que recibe la CPU forman parte de los datos
en la memoria.
k El modelo, con pocos cambios, se debe a john von ^eumann (:o
:,,), quien se intereso inicialmente en logica, teora de conjuntos,
de la medida, y mecanica cuantica, tocando luego temas de analisis
funcional, teora ergodica, siendo fundador de la teora de juegos.
En sus ultimos aos tambien tuvo infuencia decisiva en ecua-
ciones en derivadas parciales y en teora de automatas, en la que
sintetizo sus conocimientos e ideas de logica y grandes computadoras
electronicas.
.. Bits y bytes
Podemos pensar que la memoria, en donde se almacenan los datos,
est constituida por muchas cajitas llamadas bits (binary digit o dgito
binario), en cada una de las cuales slo se puede guardar un o un .
Puesto que esta caja es demasiado pequea para guardar informacin
ms complicada que s/no o blanco/negro, los bits se agrupan en
cajas un poco ms grandes llamadas bytes, generalmente de bits, en
los que pensamos que los bits estn alineados y ordenados, puesto que
queremos que sea distinto de . Ver el esquema en la
fgura ..
Ejercicio .. Suponiendo que un byte tenga bits:
z.. Programas y lenguajes de programacn Pg. t
a) Cuntas ristras distintas de y puede tener?
Sugerencia: hacer la cuenta primero para un byte de bit,
luego para un byte de bits, luego para un byte de bits,...
b) Si no importara el orden de los bits que forman el byte, y enton-
ces , , fueran indistinguibles entre s,
cuntos elementos distintos podra contener un byte?
Sugerencia: si el byte tiene bits puede ser que haya ceros
y ningn uno, o ceros y uno, o... e
Para las computadoras ms recientes, estas unidades de bits re-
sultan demasiado pequeas para alimentar a la CPU, por lo que los
bits se agrupan en cajas de, por ejemplo, , o bits (usualmente
potencias de ), siempre conceptualmente alineados y ordenados.
.. Programas y lenguajes de programacin
Un programa es un conjunto de instrucciones para que la compu-
tadora realice determinada tarea. En particular, el sistema operativo
de la computadora es un programa que alimenta constantemente a la
CPU y le indica qu hacer en cada momento. Entre otras cosas le va a
indicar que ejecute o corra nuestro programa, leyendo y ejecutando las
instrucciones que contiene.
Los lenguajes de programacin son abstracciones que nos permi-
ten escribir las instrucciones de un programa de modo que sean ms
sencillas de entender que ristras de ceros y unos. Las instrucciones
para la mquina se escriben como sentencias de acuerdo a las reglas
del lenguaje que luego sern traducidas a algo que la CPU pueda
entender, es decir, las famosas ristras de ceros y unos. Las sentencias
que escribimos (en lenguaje humano) forman el programa fuente o
codigo fuente o smplemente codigo, para distinguirlo del programa
ejecutable o aplicacion que es el que tiene los ceros y unos que entiende
la computadora.
Cuando trabajamos con el lenguaje Python, el programa llamado
Pg. t{ Cap|rulo z. El prmer conracro
editar
probar
terminar
corregir
xito
error
Figura .: Esquema del desarrollo de un programa.
(casualmente) python hace la traduccin de humano a binario e indica
a la CPU que realice la tarea. Esto se hace a travs de otro programa
llamado terminal en sistemas Unix: all escribimos las instrucciones y
luego le pedimos al programa python que las ejecute.
En la mayora de los casos an para gente experimentada
habr problemas, por ejemplo, por errores de sintaxis (no seguimos las
reglas del lenguaje), o porque al ejecutar el programa los resultados no
son los esperados. Esto da lugar a un ciclo de trabajo esquematizado
en la fgura .: editamos, es decir, escribimos las instrucciones del
programa, probamos si funciona, y si hay errores como ser la
mayora de las veces habr que corregirlos y volver a escribir las
instrucciones.
Amedida que los programas se van haciendo ms largos (ponemos
mayor cantidad de instrucciones) es conveniente tener un mecanismo
que nos ahorre volver a escribir una y otra vez lo mismo. En todos
los lenguajes de programacin est la posibilidad de que el programa
traductor (en nuestro caso Python) tome las instrucciones de un archi-
vo que sea fcil de modifcar. Generalmente, este archivo se escribe y
modifca con la ayuda de un programa que se llama editor de textos.
Para los que estn haciendo las primeras incursiones en progra-
macin es ms sencillo tener un entorno que integre el editor de texto
y la terminal. Afortunadamente, la distribucin de Python incluye
uno de estos entornos llamado IDLE (pronunciado aidl), y en el curso
trabajaremos exclusivamente con ste. As, salvo indicacin contraria,
cuando hablemos de la terminal nos estaremos refriendo a la terminal
z.{. Pyrhon y IDLE Pg. ty
de IDLE, y no la de Unix (aunque todo lo que hacemos con IDLE lo
podemos hacer desde la terminal de Unix).
En resumen, en el curso no vamos a trabajar con Python directa-
mente, sino a travs de IDLE.
.. Python y IDLE
Usaremos la ltima versin estable de Python (. al escribir
estas notas), que puede obtenerse del sitio ofcial de Python, donde
hay instalaciones disponibles para los principales sistemas operativos.
Algunas observaciones:
La versin que usaremos no es compatible con versiones ante-
riores como la ., y hay que tener cuidado cuando se hacen
instalaciones o se consulta documentacin (ejemplos, apuntes,
libros, etc.) de internet.
Muchos sistemas Unix tienen Python preinstalado, pero posible-
mente se trate de una versin anterior. Para verifcar si la versin
. est instalada, puede ponerse en la terminal de Unix:
which python3
y si no aparece la ubicacin, debe instalarse.
En algunos casos, IDLE se ofrece como instalacin separada (que
debe instalarse). Adems, IDLE usa el programa Tcl de ActiveState, y
habr que tener instaladas versiones de Python, IDLE y Tcl compatibles.
La forma de iniciar IDLE depende del sistema operativo y la ins-
talacin, pero fnalmente debe aparecer la terminal de IDLE con un
cartel similar a
Python 3.3.2 (v3.3.2:d047928ae3f6, May 13 2013, 13:52:24)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>>
Pg. to Cap|rulo z. El prmer conracro
Es importante verifcar que aparezca anunciado
Python 3.3 en alguna parte. versiones menores
seguramente nos daran dolores de cabeza.

Los signos >>> en la terminal indican que Python est a la espera de


que ingresemos alguna orden. Por ejemplo, ponemos 2 + 2, quedando
>>> 2 + 2
y ahora apretamos la tecla retorno (o intro o return o enter o
con un dibujo parecido a , dependiendo del teclado) para obtener
4
>>>
quedando IDLE a la espera de que ingresemos nuevos comandos. En
un rapto de audacia, ingresamos 2 + 3 para ver qu sucede, y seguimos
de este modo ingresando operaciones como en una calculadora.
Si queremos repetir o modifcar alguna entrada anterior, podemos
movernos con alt-p (previous o previo) o alt-n (next o siguiente)
donde alt indica la tecla modifcadora alterna marcada con alt,
o bien dependiendo del sistema y la instalacin con ctrl-p y
ctrl-n, donde ctrl es la tecla modifcadora control. En todo caso se
pueden mirar las preferencias de IDLE para ver qu otros atajos hay o
modifcarlos a gusto.
Con ctrl-d (fn de datos) cerramos la ventana de la terminal, o
bien podemos salir de IDLE usando el men correspondiente.
A partir de este momento, suponemos que
sabemos como iniciar y salir de IDLE e ingresar
comandos en su terminal.

Captulo
Python como calculadora
En este captulo usamos Python como una calculadora sencilla,
observamos que nmeros enteros y decimales son muy diferentes para
Python, y terminamos ampliando la calculadora bsica a una cientfca
mediante el mdulo math.
.. Operaciones con nmeros
Ejercicio .. En la terminal de IDLE ingresar 123 + 45, y comprobar
que el resultado es entero (no tiene punto decimal).
Repetir en cada uno de los siguientes, reemplazando + (adicin)
por el operador indicado y ver el tipo de resultado que se obtiene (si
tiene o no coma decimal).
a) - (resta, es decir, calcular 123 - 45),
b)
*
(multiplicacin, en matemticas ),
c)
**
(exponenciacin, en matemticas

)
d) / (divisin),
e) // (divisin con cociente entero),
f ) % (resto de la divisin con cociente entero, no confundir con
porcentaje!).
Pg. t8 Cap|rulo . Pyrhon como calculadora
La gua de estilos de Python sugiere dejar un espacio en blanco
alrededor de los operadores, como en 1 + 2. No es estrictamente
necesario seguir esta regla, y a veces pondremos 1+2 sin espacios
alrededor del operador. Lo que defnitivamente no es estticamen-
te agradable es poner 1 +2, dejando un espacio de un lado pero
no del otro.
Observar que, excepto el caso de la divisin 123 / 45, todos los
resultados son enteros (no tienen coma decimal). e
Ejercicio.. Repetir los apartados del ejercicio anterior considerando
. y . (en vez de, respectivamente, y ), y ver si los resultados
tienen o no coma decimal.
Observar que el resultado de 12.3 // 4.5 es 2.0 y no 2. e
Ejercicio .. Qu pasa si ponemos cualquiera de las siguientes?
a) 12 / 0 b) 34.5 / 0 c) 67 // 0 e
Ejercicio .. Cunto es

(cero a la cero) segn las matemticas?


Y segn Python? e
Ejercicio .. Si tenemos ms de una operacin, podemos agrupar
con parntesis como hacemos en matemticas. Ejecutar las siguientes
instrucciones, comprobando que los resultados son los esperados.
a) 4 - (3 + 2) b) (4 - 3) + 2 c) 4 - 3 + 2 e
Cuando no usamos parntesis, tenemos que tener cuidado con la
precedencia (cul se aplica primero) de los operadores. Por ejemplo, si
en matemticas ponemos + , sabemos que tenemos que calcular
primero y a eso agregarle , o sea, tiene mayor precedencia
que +. Si en cambio tenemos + , evaluamos de izquierda a
derecha. La cosa se complica si consideramos : en matemticas
no queda claro si nos referimos a () o a ( ).
Python sigue reglas similares, aunque evala 3 / 4
*
5 de izquier-
da a derecha, como en el caso de sumas y restas. En el curso trataremos
de evitar este tipo de construcciones agregando parntesis aunque sean
redundantes.
.t. Operacones con nmeros Pg. t
Volvemos sobre el tema en el ejercicio ..
Ejercicio .. Adems de las operaciones entre nmeros, podemos
usar algunas funciones como el valor absoluto de x, x, que se escribe
abs(x) en Python, o el redondeo de decimal a entero, round(x), que
nos da el entero ms prximo a x.
a) Ver qu hace abs poniendo help(abs) y luego repetir para
round.
Cuando escribimos comandos como help o round en IDLE,
es posible poner unas pocas letras y completar el comando
o al menos obtener una lista de posibilidadesintroduciendo
una tabulacin (tecla tab o similar).
b) Conjeturar y evaluar el resultado:
i) abs(12) ii) round(12.3)
iii) round(-5.67) iv) abs(-3.21)
c) Evaluar:
i) abs ii) round
y observar que al poner una funcin (como abs) sin argumento,
Python responde diciendo que es una funcin (en este caso,
propia).
d) Python diferencia entre maysculas y minsculas. Probar con
los siguientes, viendo que da error:
i) Abs(2) ii) ABS(2) e
Ejercicio .. Cuando x es un nmero, type(x) nos dice si x es entero
(int) o decimal (float) segn Python.
Ver los resultados de las siguientes instrucciones:
a) type(12) b) type(12.3)
c) round(12.3) d) type(round(12.3))
e) 98 // 76 f ) type(98 // 76)
g) 98.0 // 76.0 h) type(98.0 // 76.0)
Pg. zo Cap|rulo . Pyrhon como calculadora
k int viene de integer, o entero. float viene de foating point (punto
fotante), el nombre de la codifcacion para numeros decimales
(estudiaremos esta codifcacion en el captulo :o). e
Es posible pasar de uno a otro tipo de nmero usando int (para
pasar de float a int) o float (para pasar de int a float). Claro que
al pasar de decimal a entero perdemos los decimales despus de la
coma.
Ejercicio .. Analizar los resultados de:
a) int(12.3) b) type(int(12.3))
c) float(-45) d) type(float(-45)) e
Ejercicio .. Explorar la diferencia entre int y round cuando aplica-
dos a nmeros decimales. Por ejemplo, evaluar estas funciones en .,
., ., ., ., ..
Tambin poner help(round) (que ya vimos) y help(int). e
Ejercicio .. Python puede trabajar con enteros de cualquier tama-
o, pero los tamaos de los decimales es limitado.
a) Poner 123
**
456 viendo que obtenemos un nmero muy
grande.
b) Poner 123.0
**
456.0 viendo que obtenemos un error (el
mensaje de error indica Result too large o resultado dema-
siado grande.)
c) Qu pasar si ponemos float(123)
**
float(456)?
d) Probar tambin con 123.0
**
456 y 123
**
456.0.
Mientras que cualquier nmero entero puede representarse en
Python (sujeto a la capacidad de la memoria), el mximo nmero
decimal que se puede representar es aproximadamente .

es demasiado grande y no puede


representarse como nmero decimal.
Ms adelante estudiaremos con ms cuidado estos temas. e
.z. El mdulo math Pg. zt
Matemticas: e

x sen cos tan log
Python: pi e sqrt(x) sin cos tan log
Cuadro .: Traducciones entre matemticas y el mdulo math.
.. El mdulo math
Python tiene un conjunto relativamente pequeo de operaciones y
funciones matemticas predeterminadas. Para agregar nuevas posibili-
dades de matemticas y de muchas otras cosas Python cuenta con
el mecanismo de modulos, cuyos nombres indicaremos conestasletras.
As, para agregar funciones y constantes matemticas apelamos al
mdulo math, que agrega las funciones trigonomtricas como seno,
coseno y tangente, la exponencial y su inversa el logaritmo, y las cons-
tantes relacionadas = . . . . y e = . . . .
Para usar math ponemos
import math
A partir de ese momento podemos emplear las nuevas posibilida-
des usando las traducciones de matemtica a Python indicadas en el
cuadro ., recordando que en las instrucciones de Python hay que
anteponer math. . Por ejemplo, se escribe math.pi en Python.
Hay otras formas de importar mdulos o parte de sus contenidos,
pero:
nosotros solo usaremos la forma
import nombre
_
del
_
mdulo
importando siempre todo el contenido del modulo.
Ejercicio .. Poner import math en la terminal, y luego realizar los
siguientes apartados:
a) Poner help(math), para ver las nuevas funciones disponibles.
Pg. zz Cap|rulo . Pyrhon como calculadora
b) Evaluar math.sqrt(2). Qu pasa si ponemos slo sqrt(2)
(sin math)?
c) Desde las matemticas, es

entero?, y

? De qu tipo
son math.sqrt(3) y math.sqrt(4)? e
Ejercicio .. Usando el mdulo math:
a) Ver qu hace math.trunc usando help(math.trunc).
b) Cul es la diferencia entre round y math.trunc? Encontrar
valores del argumento donde se aprecie esta diferencia.
c) Cul es la diferencia entre int(x) y math.trunc(x) cuando
x es un nmero decimal? e
Ejercicio . (funciones trigonomtricas). Como en matemticas
avanzadas, en Python las funciones trigonomtricas toman los argu-
mentos en radianes. En todo caso podemos pasar de grados a radianes
multiplicando por . As,

= (radianes).
Python tiene las funciones math.radians y math.degrees que
no usaremos.
Poniendo import math en la terminal de IDLE, realizar los siguien-
tes apartados:
a) Evaluar math.pi.
b) Sin usar calculadora o compu, cules son los valores de cos
y sen? Comparar con la respuesta de Python a math.cos(0)
y math.sin(0).
c) Calcular sen usando Python.
d) Calcular tan

usando math.tan con argumento .


e) Calcular seno, coseno y tangente de

usando Python (las


respuestas, por supuesto, deberan ser aproximadamente ,

y

).
f ) Cunto es tan

?, y segn Python?
Python no puede evaluar tan

exactamente: tanto math.pi


.z. El mdulo math Pg. z
como math.tan son slo aproximaciones a y tan (respecti-
vamente). e
Con log
a
b denotamos el logaritmo en base a de b, recordando
que log
a
b = c a
c
= b (suponiendo que a y b son nmeros reales
positivos). Es usual poner ln x = log
e
x, aunque siguiendo la notacin
de Python ac entenderemos que log x (sin base explcita) es log
e
x =
ln x.
Ejercicio . (exponenciales y logaritmos). En la terminal de IDLE,
poner import math y realizar los siguientes apartados:
a) Calcular math.e.
b) Usando help, averiguar qu hace la funcin math.log y calcu-
lar math.log(math.e). Es razonable el valor obtenido?
c) Para encontrar el logaritmo en base de un nmero, podemos
usar math.log(nmero, 10) pero tambin podemos poner di-
rectamente math.log10(nmero): ver qu hace math.log10
usando help, y calcular log

de las dos formas. Hay dife-


rencias?, debera haberlas?
d) Calcular a = log

aproximadamente, y verifcar el resultado


calculando
a
(cunto debera ser?).
e) Ver qu hace math.exp. Desde la teora, que diferencia hay
entre math.exp(x) y (math.e)
**
x?
Calcular ambas funciones y su diferencia con Python para
distintos valores de x (e. g., , , ). e
Ejercicio .. Recordemos que para x R, la funcin piso se defne
como
x = m ax n Z n x,
y la funcin techo se defne como
[x = mnn Z n x.
Pg. z{ Cap|rulo . Pyrhon como calculadora
En el mdulo math, estas funciones se representan respectivamente
como math.floor (piso) y math.ceil (techo). Ver el funcionamiento
de estas funciones calculando el piso y el techo de , . y ..
Comparar con los resultados de int y round en esos valores. e
Ejercicio . (cifras I). La cantidad de cifras (en base ) para n N
puede encontrarse usando log

(el logaritmo en base ), ya que n tiene


k cifras si y slo si
k
n <
k
, es decir, si y slo si k log

n < k,
o sea si y slo si k = + log

n.
a) Usar estas ideas para encontrar la cantidad de cifras (en base
) de

.
Recordar el ejercicio . y la nota al fnal de ste.
b) Encontrar la cantidad de cifras en base de

y de . e
.. Comentarios
La presentacin como calculadora es tpica en sistemas interac-
tivos como Matlab o Mathematica. En particular, aparece en el
tutorial de Python.
Ms adelante en el captulo veremos cmo hacer para
que Python se comporte como una calculadora grfca tambin.

Captulo
Tipos de datos bsicos
En este captulo vemos que no slo podemos trabajar con nme-
ros enteros o decimales, sino que tambin podemos hacer preguntas
esperando respuestas de verdadero o falso, y que podemos poner
carteles en las respuestas.
.. Por qu hay distintos tipos de datos?
Uno se pregunta por qu distinguir entre entero y decimal. Des-
pus de todo, las calculadoras comnmente no hacen esta distincin,
trabajando exclusivamente con decimales, y en matemticas y .
son distintas representaciones de un mismo entero.
Parte de la respuesta es que todos los objetos se guardan como
ristras de ceros y unos en la memoria, y ante algo como
la computadora debe saber si es un nmero, o parte de l, o una le-
tra o alguna otra cosa, para poder trabajar. Una calculadora sencilla,
en cambio, siempre trabaja con el mismo tipo de objetos: nmeros
decimales.
La variedad de objetos con los que trabaja la compu se ve refejada
en los lenguajes de programacin. Por ejemplo, los lenguajes Pascal y C
trabajan con enteros, decimales, caracteres y otros objetos construidos
Pg. zo Cap|rulo {. Tpos de daros bscos
a partir de ellos. De modo similar, entre los tipos bsicos de Python
tenemos los dos que hemos visto, int o entero (como 123) y float o
decimal (como 45.67) y ahora veremos dos ms:
bool o logico, siendo los nicos valores posibles True (verdade-
ro) y False (falso).
Poniendo help(bool) vemos que, a diferencia de otros lengua-
jes, para Python bool es una subclase de int, lo que tiene sus
ventajas pero trae aparejada muchas inconsistencias.
k bool es una abreviacion de Boolean, que podemos traducir como
booleanos y pronunciar buleanos. Los valores logicos reciben
tambien ese nombre en honor a G. Boole (:8:,:8o).
str o cadena de caracteres, como Mateo Adolfo.
k str es una abreviacion del ingles string, literalmente cuerda, que
traducimos como cadena, en este caso de caracteres (character
string).
.. Tipo lgico
Repasemos un poco las operaciones lgicas, recordando que en
matemticas representamos con a la conjuncin y, con a la
disyuncin o y con a la negacin no.
Ejercicio .. En cada caso, decidir si la expresin matemtica es ver-
dadera o falsa:
a) = b) > c) d)
e)

<

f ) < < g) < < h) ( < ) ( < ) e


En Python tambin tenemos expresiones que dan valores True
(verdadero), o False (falso). Por ejemplo:
>>> 4 < 5
True
>>> 4 > 5
False
{.z. Tpo lgco Pg. z,
Matemticas: = > < (y) (o) (no)
Python: == != > >= < <= and or not
Cuadro .: Traducciones entre matemticas y Python.
En el cuadro . vemos cmo convertir algunas expresiones entre
matemtica y Python, recordando que and, or y not son los
trminos en ingls para y, o y no, respectivamente.
As, para preguntar si = ponemos 4 == 5, y para preguntar si
ponemos 4 != 5:
>>> 4 == 5
False
>>> 4 != 5
True
En Python el signifcado de = no es el mismo
que en matematicas, lo que da lugar a numerosos
errores.
la igualdad = en matematicas se representa
con == en Python,
la instruccion = en Python es la asignacion
que veremos en el captulo ,.

Ejercicio .. Traducir a Python las expresiones del ejercicio ., ob-


servando que en Python (como en matemticas) la expresin a < b <
c es equivalente a (a < b) and (b < c). e
Ejercicio .. Conjeturar y verifcar en Python:
a) not True b) True and False
c) True or False d) False and (not True) e
Pg. z8 Cap|rulo {. Tpos de daros bscos
Ejercicio .. Usando type(algo), ver que las expresiones
a) 4 < 5 b) 4 != 5 c) 4 == 5
son de tipo bool. e
Ejercicio .. Cul es el resultado de 1 > 2 + 3?, cul es la prece-
dencia entre > y + ? Y entre > y otras operaciones aritmticas (como
*
,
/,
**
)? e
Ejercicio .. Python considera que 1 y 1.0 son de distinto tipo, pero
que sus valores son iguales. Evaluar:
a) type(1) == type(1.0) b) 1 == 1.0 e
Ejercicio . (errores numricos). Usando ==, <= y <, comparar
a) 123 con 123.0,
b) 123 con 123 + 1.0e-10,
1.0e-10 es la versin de Python de lo que en matemtica es
.

, y no est relacionado directamente con el nmero


e = . . . ..
c) 123 con 123 + 1.0e-20.
Alguna sorpresa?
Estudiaremos problemas de este tipo con ms profundidad en el
captulo . e
En general, los lenguajes de programacin tienen reglas un tanto
distintas a las usadas en matemticas para las evaluaciones lgicas. Por
ejemplo, muchas veces la evaluacin de expresiones en las que aparecen
conjunciones ( y ) o disyunciones ( o ) se hace de izquierda a dere-
cha y dejando la evaluacin en cuanto se obtiene una expresin falsa
al usar y o una expresin verdadera al usar o . Esto hace que, a
diferencia de matemticas, and y or no sean operadores conmutativos.
Estamos considerando que slo aparece y o slo aparece o .
Cuando aparecen ambos entremezclados, hay que tener en cuenta
la precedencia de or y and que estudiamos en el ejercicio ..
{.z. Tpo lgco Pg. z
Python tambin usa esta convencin:
Ejercicio . (cortocircuitos en lgica). Evaluar y comparar:
a) 1 < 1/0
b) False and (1 < 1/0)
c) (1 < 1/0) and False
d) True or (1 < 1/0)
Aunque incorrectas desde las matematicas (pues las opera-
ciones logicas de conjuncion y disyuncion son conmutativas),
aceptaremos el uso de cortocircuitos porque su uso esta
muy difundido en programacion. e
Ejercicio . (precedencias).
a) Evaluar 3 / 4
*
5 y decidir si corresponde a (3 / 4)
*
5 o
a 3 / (4
*
5).
b) La expresin de Python - 3
**
- 4, es equivalente en mate-
mticas a ()

o a

?
c) Conjeturar el valor de True or False and False, luego eva-
luar la expresin en Python y decidir si corresponde a (True
or False) and False o a True or (False and False).
Decidir si en Python hay precedencias entre and y or o si se
evalan de izquierda a derecha (como 3 / 4
*
5).
En matemticas no hay precedencias entre la conjuncin y la
disyuncin: siempre deben ponerse parntesis al mezclarse.
En todos los ejemplos anteriores hay que poner parentesis.
Mas vale poner algunos parentesis redundantes antes que
dejar algo de signifcado dudoso. e
Otra diferencia importante con las matemticas es que a los efectos
de evaluaciones lgicas, Python considera que todo objeto tiene un
valor verdadero o falso. Recprocamente, para operaciones aritmticas
False y True tienen valores numricos ( y respectivamente).
Pg. o Cap|rulo {. Tpos de daros bscos
Esto es muy confuso y no sucede en otros lenguajes de programa-
cin:
En el curso estan prohibidas las construcciones
que mezclan valores u operaciones numericas con
logicas como.
1 and 2 or 3,
False + True,
-1 < False,
validas en Python pero carentes de sentido en
matematicas.

.. Cadenas de caracteres
Los caracteres son las letras, signos de puntuacin, dgitos, y otros
smbolos que usamos para la escritura. Las cadenas de caracteres son
sucesiones de estos caracteres que en Python van encerradas entre
comillas, ya sean sencillas, , como en Ana Luisa, o dobles, ", como
en "Ana Luisa".
A diferencia de los tipos que acabamos de ver (entero, decimal y l-
gico), las cadenas de caracteres son objetos compuestos, constituidos
por objetos ms sencillos (los caracteres).
Python no tiene el tipo carcter y esta descripcin no es completa-
mente cierta. Para representar uncarcter enPython, simplemente
consideramos una cadena de un elemento. Por ejemplo, la letra
a se puede poner como la cadena a.
Ejercicio .. Ingresar en la terminal Ana Luisa y averiguar su
tipo poniendo type(Ana Luisa). e
Ejercicio .. Ver que para Python Ana Luisa y "Ana Luisa" son
lo mismo usando ==. e
{.. Cadenas de caracreres Pg. t
Ejercicio .. Las comillas simples no se pueden intercambiar con
las dobles ", pero se pueden combinar. Ver los resultados de:
a) mi" b) mi" mama" c) "mi mama" d) mi" "mama e
Ejercicio .. Como vimos en el caso de int y float (ejercicio .),
podemos cambiar el tipo de un objeto, aunque cuando no se trata de
nmeros pueden surgir difcultades.
a) Cuando pasamos un objeto de tipo int, float o bool a str,
bsicamente obtenemos lo que se imprimira en la terminal,
slo que entre comillas. Evaluar:
i) str(1) ii) str(1.) iii) str(False)
b) Hay cosas que no tienen sentido:
i) int(pepe) ii) float(pepe) iii) bool(pepe)
c) A veces, pero no siempre, podemos volver al objeto original:
i) int(str(1)) ii) float(str(1.2))
Recordar el ejercicio ..
d) A veces el resultado puede llevar a error:
bool(str(False))
Esto es particularmente fastidioso cuando se est leyendo de
un archivo de texto. e
Ejercicio . (longitud de cadena). Con len podemos encontrar la
longitud, es decir, la cantidad de caracteres de una cadena. Por ejemplo,
mama tiene cuatro caracteres (contamos las repeticiones), y por lo
tanto len(mama) da 4.
Conjeturar el valor y luego verifcarlo con Python en los siguientes
casos:
a) len(me mima) b) len(mi mama me mima) e
Ejercicio . (concatenacin). Concatenar es poner una cadena a
continuacin de otra, para lo cual Python usa + , el mismo smbolo
que para la suma de nmeros.
Pg. z Cap|rulo {. Tpos de daros bscos
a) Evaluar:
i) mi + mama ii) mi + + mama
Para evitar confusiones, a veces ponemos para indicar un
espacio en blanco.
b) A pesar del signo + , la concatenacin no es conmutativa
(como s lo es la suma de nmeros). Ver el resultado de
1 + 2 == 2 + 1
pa + ta == ta + pa
c) Evaluar mi mama + me mima.
Cmo podra modifcarse la segunda cadena para que el
resultado de la suma sea mi mama me mima?
d) Conjeturar los valores de
i) len(mi mama) + len(me mima),
ii) len(mi mama me mima)
y luego verifcar la validez de las conjeturas. e
Ejercicio . (cadena vaca). La cadena vaca es la cadena , o la
equivalente "", sin caracteres y tiene longitud . Es similar a la nocin
de conjunto vaco en el contexto de conjuntos o el cero en nmeros.
a) No hay que confundir (comilla-comilla) con (comilla-
espacio-comilla). Conjeturar el resultado y luego evaluar:
i) len() ii) len( )
b) Cul ser el resultado de + mi mama? Verifcarlo con
Python. e
Ejercicio ..
a) + puede usarse tanto para sumar nmeros como para conca-
tenar cadenas de caracteres, pero no podemos mezclar nmeros
con cadenas: ver qu resultado da 2 + mi.
b) Podra usarse - con cadenas como en mi - mama?
c) Cambiando ahora + por
*
, verifcar si los siguientes son
vlidos en Python, y en caso afrmativo cul es el efecto:
{.{. print (mprmr) Pg.
i) 2
*
ma ii) 2
*
ma iii) ma
*
2 e
Ejercicio.(isinstance I). Para cerrar el tema de los tipos de datos,
en este ejercicio vemos la funcin isinstance, que de alguna manera
es la inversa de type.
a) Usando help(isinstance), ver qu hace esta funcin.
b) Evaluar
i) isinstance(1, int)
ii) isinstance(1.0, int)
iii) isinstance(mama, float)
iv) isinstance(True, int) e
Con help(str) podemos ver las muchas operaciones que tiene
Python para cadenas. Nosotros veremos slo unas pocas en el curso: las
que ya vimos, algunas ms dentro del contexto general de sucesiones
en el captulo , y cuando trabajemos con formatos y archivos de texto
en el captulo .
.. print (imprimir)
print nos permite imprimir enla terminal expresiones que pueden
involucrar elementos de distinto tipo.
Ejercicio ..
a) Al ingresarlos en la terminal, cul es la diferencia entre 123,
print(123), 123 y print(123)?
b) print puede no tener argumentos explcitos. Evaluar y obser-
var las diferencias entre:
i) print ii) print()
iii) print() iv) print( )
c) Tambin puede tener ms de un argumento, no necesariamente
del mismo tipo, en cuyo caso se separan con un espacio al
imprimir. Evaluar
Pg. { Cap|rulo {. Tpos de daros bscos
print(Segn Mara,, 1.23,
lo que dice Pepe es, 1 > 2)
d) Evaluar y observar las diferencias entre:
i) print(123456) y print(123, 456).
ii) print(Hola mundo) y print(Hola, mundo). e
Ejercicio .. Aunque matemticamente no tiene mucho sentido, la
multiplicacin de un entero por una cadena que vimos en el ejerci-
cio . es til para imprimir.
Evaluar:
a) print(70
*
-)
b) print(2
*
- + 3
*
+ 4
*

*
) e
Ejercicio .. Observar las diferencias entre los resultados de los
siguientes apartados, y determinar el efecto de agregar \n:
a) print(mi, mama, me, mima)
b) print(mi\n, mama, me\n\n, mima)
c) print(mi, \n, mama, me, \n\n, mima) e
Ejercicio.. Cuando la cadena es muy larga y no cabe en un rengln,
podemos usar \ (barra invertida) para dividirla. Por ejemplo, evaluar:
print(Este texto es muy largo, no entra en \
un rengln y tengo que ponerlo en ms de uno.)
Cmo podra usarse + (concatenacin) para obtener resultados
similares?
Ayuda: + puede ponerse al principio o fnal de un rengln, siempre
que est dentro de un parntesis.
Aunque se puede agrandar la ventana de IDLE, es sumamente
recomendable no escribir renglones con ms de caracteres. e
Como vimos, \ se usa para indicar que el rengln contina, o,
en la forma \n, para indicar que debe comenzarse un nuevo rengln.
{.y. Comenraros Pg. y
Si queremos que se imprima \, tenemos que poner \\ dentro del
argumento de print.
Ejercicio ..
a) Comparar print(\) con print(\\).
b) Conjeturar y luego verifcar los resultado de print(/\) y de
print(//\\).
c) Imprimir una casita usando print:
/\
/
__
\
| |
|
__
| e
.. Comentarios
El ejercicio . est tomado de Litvin y Litvin ().

Captulo
Variables y asignaciones
Frecuentemente queremos usar un mismo valor varias veces en los
clculos, o guardar un valor intermedio para usarlo ms adelante, o
simplemente ponerle un nombre sencillo a una expresin complicada
para referirnos a ella en adelante. A estos efectos, muchas calculadoras
tienen memorias para conservar nmeros, y no es demasiada sorpresa
que los lenguajes de programacin tengan previsto un mecanismo
similar: la asignacion.
.. Asignaciones en Python
Cuando escribimos alguna expresin como 123 o -5.67 o mi
mama, Python guarda estos valores como objetos en la memoria, lo
que esquematizamos en la fgura ..a).
En Python podemos hacer referencia posterior a estos objetos,
poniendo un nombre, llamado identifcador, y luego una asignacin,
indicada por = , que relaciona el identifcador con el objeto. As, el
conjunto de instrucciones
a = 123
suma = -5.67
y.t. Asgnacones en Pyrhon Pg. ,
memoria
123 5.67 mi mama
a) Objetos en la memoria.
memoria
123 5.67 mi mama
suma texto a
b) Asignaciones.
Figura .: Objetos en la memoria.
texto = mi mama
hace que se relacionen los identifcadores a la izquierda (a, suma y
texto) con los objetos a la derecha (123, -5.67 y mi mama), como
esquematizamos en la fgura ..b).
Recordemos que los datos, incluyendo instrucciones, se guardan
en la memoria de la computadora como ristras de ceros y unos.
En la fgura . ponemos los valores humanos para entender de
qu estamos hablando.
Tambin recordemos que la igualdad en matemtica, = , se
indica por == en Python.
A fn de conservar una nomenclatura parecida a la de otros len-
guajes de programacin, decimos que a, suma y texto son variables,
aunque en realidad el concepto es distinto en Python, ya que son una
referencia, similar al vnculo (link) en una pgina de internet.
Ejercicio ..
a) Poner a = 123, y comprobar que el valor de a no se muestra.
Al hacer la asignacin, a es una variable con identifcador a
y valor .
b) Poner simplemente a y verifcar que aparece su valor ().
c) Poner type(a).
Pg. 8 Cap|rulo y. Varables y asgnacones
El tipo de una variable es el tipo del objeto al cual hace
referencia.
d) Poner b (al cual no se le ha asignado valor) y ver qu pasa.
En Python, el valor de una variable y la misma variable,
no existen si no se ha hecho una asignacion a ella. e
Python trabaja con objetos, cada uno de los cuales tiene una iden-
tidad, un tipo y un valor.
La identidad es el lugar (direccin) de memoria que ocupa el obje-
to. No todos los lenguajes de programacin permiten encontrarla,
pero s Python. Nosotros no estudiaremos esa propiedad.
Podemos pensar que la asignacin a = algo consiste en:
Evaluar el miembro derecho algo, realizando las operaciones
indicadas si las hubiera. Si algo involucra variables, las operacio-
nes se hacen con los valores correspondientes. El valor obtenido
se guarda en algn lugar de la memoria.
Recordar que si algo es slo el identifcador de una variable
(sin otras operaciones), el valor es el del objeto al cual referencia
la variable.
En a se guarda (esencialmente) la direccin en la memoria del
valor obtenido.
Por ejemplo:
a = 1 a es una referencia a (fgura ., izquierda)
b = a b tambin es una referencia a (fgura ., centro)
a = 2 ahora a es una referencia a (fgura ., derecha)
a el valor de a es
b b sigue siendo una referencia a
Ejercicio .. En cada caso, predecir el resultado del grupo de instruc-
ciones y luego verifcarlo en la terminal de Python, recordando que
primero se evala el miembro derecho y luego se hace la asignacin:
y.t. Asgnacones en Pyrhon Pg.
1
a
1
a
b
1 2
a
b

Figura .: Ilustracin de asignaciones.


a) a = 1
a
b) a = 1
a = a + 1
a
c) a = 1
a = a + a
a
d) a = 3
b = 2
c = a + b
d = a - b
e = d / c
e
e) a = 3
b = 2
c = a + b
d = a - b
e = c / d
e
f ) a = 3
b = 2
a = a + b
b = a - b
a
b e
Los identifcadores pueden tener cualquier longitud (cantidad de
caracteres), pero no se pueden usar todos los caracteres. Por ejemplo,
no pueden tener espacios, ni signos de puntuacin como , o . ,
ni signos como + o - para no confundir con operaciones, y no
deben empezar con un nmero. No veremos las reglas precisas, que
son un tanto complicadas y estn en el manual de referencia.
Aunque se permiten, es conveniente que los identifcadores no
empiecen con guin bajo _ , dejando esta posibilidad para identif-
cadores de Python. Tambin es conveniente no poner tildes, como en
, o .
Finalmente, observamos que identifcadores con maysculas y
minsculas son diferentes (recordar el ejercicio .).
Ejercicio ..
Pg. {o Cap|rulo y. Varables y asgnacones
a) Decidir cules de los siguientes son identifcadores vlidos en
Python, y comprobarlo haciendo una asignacin:
i) PepeGrillo ii) Pepe Grillo iii) Pepe
_
Grillo
iv) Pepe-Grillo v) Pepe\Grillo vi) Pepe/Grillo
vii) Grillo,Pepe viii) Pepe12 ix) 34Pepe
b) Cmo podra detectarse que PepeGrillo y pepegrillo son
identifcadores distintos?
Sugerencia: asignarlos a valores distintos y comprobar que
son diferentes. e
Ejercicio . (palabras reservadas). Python tiene algunas palabras
reservadas que no pueden usarse como identifcadores.
a) Para encontrarlas, ponemos en la terminal help() y a conti-
nuacin keywords (keyword = palabra clave).
b) Esto quiere decir que no podemos poner and = 5: verifcarlo.
c) Por otro lado, podemos usar por ejemplo float como
identifcador, a costa de que despus no podamos usar la fun-
cin correspondiente. Para verifcarlo, en la terminal poner
sucesivamente:
float
float(123)
float = 456
float
float(123)
type(7.8)
Es mejor no usar nombres de expresiones de Python como
identifcadores.
No es necesario memorizar las palabras reservadas. El propsito
del ejercicio es destacar que hay expresiones que no pueden usarse
como identifcadores.
IDLE pone con colores distintos las palabras claves como and y
otras instrucciones como float. e
y.t. Asgnacones en Pyrhon Pg. {t
Ejercicio .. Dados los enteros a y b, b > , el algoritmo de la division
encuentra enteros q y r, r < b tales que a = qb + r, an cuando a
no sea positivo, y esto se traduce en Python poniendo
q = a // b y r = a % b. (.)
Ms adelante veremos la funcin divmod que hace una tarea simi-
lar con una nica instruccin.
Para ver el comportamiento de Python en estas operaciones, eva-
luamos q y r para distintos valores de a y b: positivos, negativos, enteros
o decimales.
a) Qu pasa si b es ?, y si a y b son ambos ?
b) Qu hace Python cuando b es entero pero negativo? (o sea:
qu valores de q y r se obtienen?).
c) Si b es positivo pero decimal, al realizar las operaciones en (.),
Python pone q decimal y r decimal, pero esencialmente q es
entero pues q == int(q).
Verifcar esto tomando distintos valores decimales de a y b
(b positivo).
d) Si a es decimal y b = 1, determinar si el valor de q coincide
con int(a) o round(a) o ninguno de los dos.
e) Dar ejemplos de la vida real donde tenga sentido considerar:
i) a decimal y b entero positivo,
ii) b decimal y positivo.
Ayuda: hay varias posibilidades, por ejemplo pensar en horas,
en radianes y b = , y en general en cosas cclicas.
f ) Qu hace Python cuando b es negativo y decimal? e
Ejercicio . (cifras II). En el ejercicio . vimos una forma de deter-
minar la cantidad de cifras de un entero n (cuando escrito en base )
usando log

. Como Python puede escribir el nmero, otra posibilidad


es usar esa representacin.
Pg. {z Cap|rulo y. Varables y asgnacones
a) Ejecutar:
a = 123
b = str(a)
len(b)
b) En el apartado anterior, qu relacin hay entre len(b) y la
cantidad de cifras en a?
Proponer un mtodo para encontrar la cantidad de cifras
(en base ) de un entero positivo basado en esta relacin.
c) Usando el mtodo propuesto en el apartado anterior, encontrar
la cantidad de cifras (en base ) de

y comparar con el
resultado del ejercicio .. e
.. None
As como en matemticas es til tener el nmero o el conjunto
vaco, en programacin es til tener un objeto que tenga valor nulo,
o que sea el dato vaco. En Python este valor se llama None (nada o
ninguno).
En otros lenguajes se lo denomina Null (nulo) en vez de None.
Como el nmero o el conjunto vaco, el concepto no es fcil de
entender. Por ejemplo, el manual de la biblioteca dice sobre None:
Es el nico valor del tipo NoneType y es usado frecuen-
temente para indicar la ausencia de valor ...
lo que es bastante confuso.
None es una constante como lo son 123 o mi mama me mima, en
realidad ms anloga a 0 o . Es una de las palabras claves que vimos
en el ejercicio . y no podemos usarla como identifcador, del mismo
modo que no podemos poner 0 = 123.
Aunque no se crea, ya hemos visto None en accin: es el valor
retornado por print. Exploramos el tema en el siguiente ejercicio,
pero antes de hacerlo no estara de ms repasar el ejercicio ..
y.z. None Pg. {
Ejercicio . (None).
a) Poniendo en la terminal:
abs(-4)
y luego
a = abs(-4)
vemos que una diferencia entre estos dos grupos de instruccio-
nes es que en el primer caso se imprime el valor de abs(-4) (y
no existe la variable a), mientras que en el segundo el valor de
abs(-4) se guarda en la variable a, y no se imprime nada.
Verifcar el valor y tipo de a.
b) Cambiando abs por print, pongamos:
print(-4)
y luego
a = print(-4)
Cmo se comparan los resultados de estos dos grupos con
los del apartado anterior? En particular, cul es el valor de a?,
y su tipo?
c) Siempre con a = print(-4), poner a == None para ver que,
efectivamente, el valor de a es None.
d) Poner None en la terminal y ver que no se imprime resultado
alguno. Comparar con los apartados anteriores. e
La discusin sobre None nos alerta sobre la diferencia entre los
resultados de una accin y los valores retornados por esa accin.
Por ejemplo, print tiene como resultado que se imprima una
cadena de caracteres, pero el valor retornado es None.
Como hemos visto numerosas veces, la asignacin a = 4 tiene
como resultado que se relacione la variable a con el nmero , y
uno sospechara que el valor retornado por esta accin es None,
pero esto no es as.
En Python hay una oscura diferencia entre expresiones y sen-
tencias. 1 + 2 y print(mi mama) son expresiones y retornan
Pg. {{ Cap|rulo y. Varables y asgnacones
valores, mientras que a = 3 es una sentencia y no retorna valor
alguno.
Una forma de distinguirlas es justamente haciendo una asig-
nacin al resultado. Como hicimos en el ejercicio ..b), no hay
problemas en hacer la asignacin a = print(Ana), pero a =
(b = 1) da error.
No nos meteremos en esas profundidades.
.. Comentarios
Es posible averiguar las variables defnidas usando globals, ob-
teniendo un diccionario. Como tantas otras cosas, no veremos
ni globals ni la estructura de diccionario.

Captulo
Mdulos
La asignacin nos permite referir a algo complejo con un nombre
sencillo. Del mismo modo, a medida que vamos haciendo acciones
ms complejas, el uso de la terminal se hace incmodo y es conveniente
ir agrupando las instrucciones, guardndolas en algn archivo para no
tener que escribirlas nuevamente, como mencionamos en la seccin ..
Prcticamente todos los lenguajes de programacin tienen algn
mecanismo que nos permite guardar grupos de instrucciones. En Py-
thon estos archivos se llaman modulos, y para distinguirlos en estas
notas indicamos sus nombres conestasletras, en general omitiendo la
extensin (que pueden no tener).
Los mdulos de Python vienen bsicamente en dos sabores:
Los mdulos estandares, que forman parte de la distribucin de
Python y que amplan las posibilidades del lenguaje. Nosotros
vamos a usar explcitamente muy pocos de stos, slo math y
random.
Varios mdulos se instalan automticamente al iniciar IDLE.
Los mdulos que construimos nosotros, ya sea porque Python
no tiene un mdulo estndar que haga lo que queremos (o no
sabemos que lo tiene), o, como en este curso, porque queremos
Pg. {o Cap|rulo o. Mdulos
hacer las cosas nosotros mismos.
Estos mdulos son archivos de texto, en donde guardamos
varias instrucciones, eventualmente agrupadas en una o ms
funciones (tema que veremos en el captulo ).
Por otro lado, los mdulos se pueden usar de dos formas distintas:
Si el mdulo se llama pepe, usando la instruccin
import pepe
(sin incluir extensin) ya sea en la terminal o desde otro mdulo.
Si el mdulo est en un archivo de texto y se puede abrir en una
ventana de IDLE, con el men Run Module de IDLE.
En la prctica, este segundo mtodo es equivalente a escri-
bir todas las sentencias del mdulo en la terminal de IDLE y
ejecutarlas.
Estas dos formas dan resultados distintos, y nos detendremos a
explorar estas diferencias en la seccin .. En la mayora de los casos,
usaremos el primer mtodo con los mdulos estndares como math y
el segundo con los mdulos que construimos.
Para resaltar esta diferencia, a veces los archivos que se usan de la
segunda manera (abrindolos con IDLE) se llaman scripts (guion)
en vez de mdulos. Nosotros no haremos esta distincin: como
los que construyamos se pueden usar de cualquiera de las dos
formas, para simplifcar llamaremos mdulos a todos.
Veamos algunos ejemplos.
.. Mdulos propios
En esta seccin construiremos nuestros propios mdulos, esto es,
archivos de texto con extensin .py donde se guardan instrucciones de
Python.
Los archivos deben estar codifcados en utf-, lo que IDLE hace
automticamente.
o.t. Mdulos propos Pg. {,
Ejercicio . (Hola Mundo).
a) Abrir una ventana nueva en IDLE distinta de la terminal (men
File ^ew Vindow), escribir en ella print(Hola Mundo)
en un nico rengln, y guardar en un archivo con nombre
elprimero.py, prestando atencin al directorio en donde se
guarda.
Python es muy quisquilloso con las sangras: el rengln no
debe tener espacios (ni tabulaciones) antes de print.
Para evitar problemas, guardaremos todos nuestros mdulos
en el mismo directorio (veremos ms adelante por qu).
Por prolijidad es mejor que el directorio no sea el directorio
principal. Por ejemplo, podran ponerse en un directorio Pyt-
hon dentro del directorio Documentos (o similar) del usuario.
b) Buscando el men correspondiente en IDLE (Run Run Mo-
dule), ejecutar los contenidos de la ventana y verifcar que en
la terminal de IDLE se imprime Hola Mundo.
c) holamundo es una versin donde se agregaron renglones al
principio, que constituyen la documentacion que explica qu
hace el mdulo. Incluir estos renglones (donde el texto com-
pleto empieza y termina con """), y ejecutar nuevamente el
mdulo, verifcando que el comportamiento no vara.
Es una sana costumbre (lase: exmenes) documentar los
mdulos. En este caso es un poco redundante, pues son pocos
renglones y se puede entender qu hace leyndolos: mas vale
que sobre y no que falte, lo que abunda no daa,...
El uso de """ es similar al de las comillas simples y dobles "
para encerrar cadenas de caracteres, con algunas diferencias.
Por ejemplo, no es necesaria la barra invertida \ al fnal de
un rengln para indicar que el texto contina en el siguiente.
Recordar de no poner ms de caracteres por rengln.
La gua de estilos de Python sugiere que la documentacin sea
un rengln corto, seguido eventualmente de otros separados
por renglones en blanco. Si hay ms de un rengln, se sugiere
Pg. {8 Cap|rulo o. Mdulos
dejar un rengln en blanco antes del """ fnal.
Ms detalles pueden encontrarse en la gua mencionada.
d) Poniendo ahora print(
__
doc
__
), aparecer el texto que agre-
gamos al principio de holamundo.
e) Sin embargo, poniendo help(holamundo) da error.
Porque no hemos usado import.
Usando os.getcwd() se puede determinar el directorio de
trabajo. Nosotros no veremos el mdulo estndar os. e
.. Ingreso interactivo de datos
Cuando trabajamos slo con la terminal de IDLE, podemos asig-
nar o cambiar valores sin mucho problema. La situacin cambia si se
ejecuta o importa un mdulo y queremos ingresar datos a medida que
se requieren.
Ejercicio .. holapepe es una variante de holamundo, donde el usua-
rio ingresa su nombre, y la computadora responde con ese nombre. La
funcin input se encarga de leer el dato requerido.
a) Ejecutar el mdulo, comprobando su comportamiento, y usan-
do tambin print(
__
doc
__
) para leer la documentacin.
b) pepe es una variable donde se guarda el nombre ingresado. El
nombre ingresado puede no ser pepe, y puede tener espa-
cios como en Mateo Adolfo. Verifcar el nombre ingresado
poniendo pepe en la terminal de IDLE.
c) Al ingresar el nombre no es necesario poner comillas: Python
toma cualquier entrada como cadena de caracteres.
Probar con las siguientes entradas, ejecutando cada vez el
mdulo y verifcando cada una de ellas poniendo pepe antes
de ejecutar la siguiente.
i) queseo ii) 123 123" iii) agu"ero
o.z. Ingreso nreracrvo Pg. {
d) Cmo podramos modifcar el rengln fnal para que se agre-
gue una coma , inmediatamente despus del nombre? Por
ejemplo, si el nombre ingresado es Mateo, debera imprimirse
algo como Hola Mateo, encantada de conocerte.
Sugerencia: usar concatenacin (ejercicio .).
e) Los renglones que se escriben en la ventana del mdulo holape-
pe no deben tener sangras, aunque pueden haber renglones en
blanco (pero sin espacios ni tabulaciones): agregar un rengln
sin caracteres (con retorno o similar) entre el rengln con el
primer print y el rengln que empieza con pepe, y comprobar
que el comportamiento no vara. e
Ejercicio .. sumardos es un mdulo donde el usuario ingresa dos
objetos, y se imprime la suma de ambos. Adems, al comienzo se
imprime la documentacin del mdulo.
a) Sin ejecutar el mdulo, qu resultado esperaras si las entradas
fueran mi y mama (sin comillas)?
Ejecutar el mdulo, viendo si se obtiene el resultado espera-
do.
b) Qu resultado esperaras si las entradas fueran 2 y 3?
Ejecutar el mdulo, viendo si se obtiene el resultado espera-
do.
Python siempre toma las entradas de input como cade-
nas de caracteres.
c) Si queremos que las entradas se tomen como nmeros enteros,
debemos pasar de cadenas de caracteres a enteros, por ejemplo
cambiando
a = input(Ingresar algo: )
por
a = int(input(Ingresar un entero: ))
y de modo similar para b.
Pg. yo Cap|rulo o. Mdulos
Hacer estos cambios, cambiar tambin la documentacin y
guardar los cambios en el mdulo sumardosenteros.
Probar el nuevo mdulo (ejecutndolo cada vez) con las
entradas:
i) 2 y 3 ii) 4.5 y 6 iii) mi y mama
d) Cmo modifcaras el mdulo para que Python interprete las
entradas como dos nmeros decimales? e
.. Documentacin y comentarios en el cdigo
Sobre todo cuando escribimos muchas instrucciones es bueno ir
agregando documentacin para que cuando volvamos a leerlas des-
pus de un tiempo entendamos qu quisimos hacer. Una forma de
documentar es incluir un texto entre triple comillas """, que como
veremos cuando va al principio es la respuesta a help. Otra forma
es usar el smbolo # : Python ignora este smbolo y todo lo que le
sigue en ese rengln. Esta accin se llama comentar el texto.
Ejercicio .. Veamos el efecto en el mdulo holapepe:
a) Agregar # al principio del primer rengln que empieza con
print, ejecutar el mdulo y ver el efecto producido.
b) Manteniendo el cambio anterior, en el rengln siguiente cam-
biar input() por input(Cmo te llams?). Cul es el
efecto?
c) El nombre ingresado queda demasiado junto a la pregunta en
input. Cmo se podra agregar un espacio a la pregunta para
que aparezcan separados?
d) Descomentar el rengln con print o sea, sacar el # y cam-
biar la instruccin por print(Hola, soy la compu) vien-
do el efecto. e
Cuando se programa profesionalmente, es muy importante que
el programa funcione an cuando los datos ingresados sean errneos,
o.{. Usando import Pg. yt
por ejemplo si se ingresa una letra en vez de un nmero, o el nmero
como divisor de un cociente. Posiblemente se dedique ms tiempo a
esta fase, y a la interfaz entre la computadora y el usuario, que a hacer
un programa que funcione cuando las entradas son correctas.
Nosotros supondremos que siempre se ingresan datos apropiados,
y no haremos (salvo excepcionalmente) deteccin de errores. Tampoco
nos preocuparemos por ofrecer una interfaz estticamente agradable.
En cambio:
Siempre trataremos de dejar claro mediante la
documentacion y comentarios que hace el
programa y preguntando que datos han de
ingresarse en cada momento.
.. Usando import
Al poner import mdulo, Python no busca el mdulo en toda la
computadora (lo que llevara tiempo) sino en una lista de directorios,
en la que siempre estn los mdulos estndares como math.
Cuando ejecutamos un mdulo en IDLE (como hicimos con ho-
lamundo), el directorio donde est el archivo correspondiente pasa a
formar parte de la lista. De all la recomendacin de poner todos los
mdulos construidos por nosotros en un mismo directorio, de modo
de poder acceder a nuestros mdulos rpidamente.
Es posible usando instrucciones que no veremos encontrar
la lista completa de directorios y tambin cambiar la lista, por
ejemplo, agregando otros directorios.
Ejercicio ..
a) En la terminal poner a = 5 y verifcar el valor poniendo a.
b) Poner import math y luego calcular math.log(3).
Pg. yz Cap|rulo o. Mdulos
c) Reiniciar la terminal de IDLE (con el men Shell Restart
Shell), y preguntar el valor de a (sin asignar valor a a), viendo
que da error.
Poner nuevamente math.log(3) (sin import math) viendo
que tambin da error.
Al reiniciar IDLE se pierden las asignaciones anteriores. e
Ejercicio .. Resolver los siguientes apartados en una nueva sesin
de IDLE.
()
a) poner import sumardos y ver que da error.
Para importar un modulo no estandar, tenemos que
agregar el directorio donde se encuentra a la lista de
directorios donde busca Python.
b) Abrir el mdulo holamundo (y no sumardos) en IDLE y ejecu-
tarlo (Run Run Module), viendo que se imprime Hola Mundo
(y no hay error).
c) Volver a poner import sumardos en la terminal, viendo que
ahora no da error.
Al ejecutar un modulo propio, el directorio donde esta se
incorpora a la lista de directorios donde Python busca
los modulos.
d) Al poner help(sumardos) (y no holamundo), la documenta-
cin de sumardos aparece al principio de la respuesta.
Cuando hacemos import mdulo podemos acceder a
su documentacion con help(mdulo).
Comparar con el ejercicio ..e).
e) Poner import holapepe y luego help(holapepe).
Se puede importar cualquier cantidad de modulos, pero
()
Restart Shell puede no ser sufciente, dependiendo del sistema operativo.
o.{. Usando import Pg. y
marco o espacio global
variables
globales
math
holapepe
Mara Jos 3.14. . .
pepe pi pepe
Figura .: Marco global y marcos de mdulos en el ejercicio ..
ejecutar solo uno con Run Module en IDLE.
f ) Qu pasa si ponemos help(holamundo)?
Recordar el ejercicio ..e). e
Al importar (con import) un mdulo, se agregan instrucciones (y
variables) a las que ya hay, pero para acceder a los objetos del mdulo
importado y distinguirlos de los que hayamos defnido antes, debemos
agregar el nombre del mdulo al identifcador del objeto, como en
math.pi o math.cos.
Decimos que los objetos creados por el mdulo estn en el espacio
(o contexto o marco) determinado por el mdulo, y que son locales a l.
Este espacio tiene el mismo nombre del mdulo (como math), y por
eso se denomina espacio de nombre o nombrado. Los objetos creados
fuera de estos espacios se dicen globales.
Veamos cmo es esto, ayudndonos con la fgura ..
Ejercicio . (espacios de nombres).
a) Poner import math y luego math.pi, viendo que obtenemos
un valor ms o menos familiar, pero que si ponemos slo pi
(sin math.) nos da error.
Pg. y{ Cap|rulo o. Mdulos
math.pi es una variable en el espacio math, mientras
que pi no existe como variable (global) pues no se le ha
asignado valor alguno.
b) Abrir el mdulo holapepe, ejecutarlo con el men Run Run
Module de IDLE, ingresar el nombre Mara, y verifcar lo ingre-
sado poniendo pepe.
pepe es una variable global, con valor Mara.
c) Sin cerrar la terminal de IDLE, poner import holapepe. Nos
volver a preguntar el nombre y ahora pondremos Jos.
Preguntando por pepe volvemos a obtener Mara, pero si
ahora ponemos holapepe.pepe, obtendremos Jos.
holapepe.pepe es una variable dentro del espacio deter-
minado por holapepe, y su valor es Jos. En cambio,
pepe es una variable global y su valor es Mara. e

Captulo
Funciones
Es tedioso escribir las mismas instrucciones varias veces o an eje-
cutar un mdulo cada vez que queremos probar con distintas entradas.
Una solucin es juntar las instrucciones en una funcion. Como en el
caso de asignaciones y mdulos, la idea es no repetir acciones. Aunque
la ventaja de su uso ir quedando ms clara a lo largo del curso, en
general podemos decir que las funciones son convenientes para:
poner en un nico lugar clculos idnticos que se realizan en
distintas oportunidades,
o poner por separado alguna accin permitiendo su fcil reem-
plazo (y con menor posibilidad de error),
y no menos importante, haciendo el programa ms fcil de en-
tender, dejando una visin ms global y no tan detallada en cada
parte.
Para defnir una funcin en Python usamos el esquema:
def funcin(argumento/s):
instrucciones
El primer rengln no debe tener sangras (espacios entre el margen
izquierdo y la primer letra) y debe terminar con : , y el segundo
debe tener una sangra de exactamente espacios.
Pg. yo Cap|rulo ,. Puncones
El grupo de instrucciones que comienza al aumentar el sangrado
se llama bloque, y termina cuando la sangra disminuye.
Un bloque de instrucciones puede contener sub-bloques, cuyos
sangrados son mayores que el que los contiene.
A medida que vayamos usando los sangrados quedar ms
claro el efecto.
En la jerga de programacin, cuando ponemos y = f(x) decimos
que hacemos una llamada a f, que x se pasa a o es un argumento
de f, y que f(x) retorna o devuelve y.
Sin embargo, a diferencia de matemticas, en programacin las
funciones pueden no tener argumentos. En Python siempre retornan
algn valor, que puede ser no visible como None (ver seccin .).
.. Ejemplos simples
Ejercicio .. Siguiendo las ideas del ejercicio ., vamos a defnir
una funcin hola1 que dado un argumento, imprime Hola seguido
del argumento. Por ejemplo, queremos que hola1(Mateo) imprima
Hola Mateo.
a) En una nueva ventana de IDLE (no la terminal) empezamos a
construir un mdulo poniendo la documentacin general:
"""Ejemplos de funciones con y sin argumentos."""
Guardar los cambios poniendo el nombre holas al mdulo.
b) Dejando al menos un rengln en blanco despus de la docu-
mentacin, agregar la defnicin de la siguiente funcin en el
mdulo holas:
def hola1(nombre):
"""Imprime Hola seguido del argumento."""
print(Hola, nombre)
IDLE pone la sangra automticamente cuando el rengln
anterior termina en : .
Observar el uso de dentro de las """ en la documentacin.
,.t. Ejemplos smples Pg. y,
c) Guardar los cambios y ejecutar el mdulo (Run Run Module).
d) En la terminal poner help(hola1) para leer la documentacin.
e) En la terminal poner hola1(, terminando con ( sin otros
caracteres ni retorno, viendo que aparece un cartel con el
argumento a poner y la documentacin.
La documentacion de una funcion debe comenzar con
un resumen de un unico renglon corto, con no mas de
oo caracteres, ya que es lo que aparecera al hacer el
procedimiento anterior (poner el nombre de la funcion
seguido de ( y nada mas).
f ) Probar la funcin con las siguientes entradas:
i) hola1(Mateo) ii) hola1(123)
iii) hola1(123) iv) hola1(1 + 2)
v) hola1(2 > 5)
Como en matemticas, primero se evala el argumento y
luego la funcin (en este caso hola1).
g) Qu pasa si ponemos hola1 (sin parntesis ni argumentos)
en la terminal? Ver que la respuesta es similar a poner, por
ejemplo, abs (sin parntesis ni argumentos).
h) Qu pasa si ponemos nombre en la terminal?
La variable nombre es local a la funcion hola1 y no se
conoce afuera, siguiendo un mecanismo de contextos
como en los modulos (ejercicio o.,).
El tema se explica con ms detalle en la seccin .. e
La funcin hola1 que acabamos de defnir toma el argumento que
hemos llamado nombre, pero podemos defnir funciones sin argumen-
tos.
Ejercicio .. Dejando al menos un rengln en blanco despus de la
defnicin de la funcin hola1, agregar la defnicin de la siguiente
funcin en el mdulo holas:
Pg. y8 Cap|rulo ,. Puncones
def hola2():
"""Ejemplo de funcin sin argumento.
Imprime el dato ingresado.
"""
print(Hola, soy la compu)
nombre = input(Cul es tu nombre? )
print(Encantada de conocerte, nombre)
hola2 no tiene argumentos, pero tenemos que poner los parnte-
sis tanto al defnirla como al invocarla.
Atencin a las sangras!
a) Guardar los cambios, ejecutar el mdulo, y verifcar su docu-
mentacin poniendo help(hola2) y luego hola2(.
Al poner hola2( en la terminal (terminando en (
sin otros caracteres ni retorno) solo aparece el primer
renglon de la documentacion.
Al poner help(hola2) aparecen todos los renglones de
la documentacion y no solo el primero.
Por eso es de suma importancia que la documentacion
de una funcion tenga el primer renglon corto con un
resumen de lo que hace, separado por un renglon en
blanco del resto de la documentacion (si la hubiera).
b) Verifcar el comportamiento de hola2, poniendo hola2().
c) nombre es una variable local a la funcin hola2: poner nombre
en terminal y ver que da error.
A diferencia de las variables locales a mdulos, no es fcil
acceder a las variables locales dentro de una funcin: ver que
hola2.nombre y hola2().nombre dan error. e
Ejercicio.. Habiendo ejecutado el mdulo holas, hacer la asignacin
,.t. Ejemplos smples Pg. y
a = hola1(Mateo) y verifcar que a es None al terminar.
Repetir con a = hola2(). e
Los ejercicios anteriores nos muestran varias cosas. Por un lado,
que en un mismo mdulo se pueden defnir varias funciones. Por otro,
las funciones del mdulo holas realizan la accin de imprimir pero el
valor que retornan es None, como la funcin print (ver el ejercicio .).
Ejercicio . (return). Basados en el ejercicio ., ahora defnimos
una funcin que toma dos argumentos y que retorna un valor que
podemos usar, para lo cual usamos return.
a) En una ventana nueva de IDLE, poner
def sumar2(a, b):
"""Suma los argumentos."""
return a + b # resultado de la funcin
Guardar en un archivo adecuado, y ejecutar el mdulo.
b) Conjeturar y verifcar el resultado de los siguientes (viendo que
no es None):
i) sumar2(2, 3.4) ii) sumar2(pi, pa)
iii) sumar2(1) iv) sumar2(1, 2, 3)
c) Poniendo en la terminal:
a = sumar2(1, 2)
a
vemos que el efecto es el mismo que haber puesto a = 1 +
2. e
Ejercicio ..
a) En cada una de las funciones hola1 y hola2 de los ejercicios .
y . incluir al fnal la instruccin return None, y hacer las
asignaciones a = hola1(toto) y a = hola2(), viendo que
en ambos casos el resultado es efectivamente None.
b) Cambiando el return None anterior por slo return, y ver el
efecto.
Pg. oo Cap|rulo ,. Puncones
Si la ultima instruccion en la defnicion de una funcion es
return o return None, el efecto es el mismo que no poner
nada, y el valor retornado es None. e
Ejercicio .. Las funciones que defnimos pueden usar funciones
defnidas por nosotros. Poner:
def f(x):
"""Multiplicar por 2."""
return 2
*
x
def g(x):
"""Multiplicar por 4."""
return f(f(x))
y evaluar f y g en , y . e
.. Funciones numricas
En esta seccin miramos funciones cuyos argumentos son uno o
ms nmeros, y el resultado es un nmero.
Ejercicio .. Si f indica la temperatura en grados Fahrenheit, el valor
en grados centgrados (o Celsius) est dado por c = (f ).
a) Expresar en Python la ecuacin que relaciona c y f .
b) En la terminal de IDLE, usar la expresin anterior para encon-
trar c cuando f es 0, 10, 98.
c) Recprocamente, encontrar f cuando c es -15, 10, 36.7.
d) Para qu valores de f el valor de c (segn Python) es entero?
Y matemticamente?
e) En qu casos coinciden los valores en grados Fahrenheit y
centgrados?
f ) Defnir una funcin acelsius en Python tal que si f es el valor
de la temperatura en grados Fahrenheit, acelsius(f) da el
,.. Pyrhon y varables lgcas Pg. ot
valor en grados centgrados, y verifcar el comportamiento
repitiendo los valores obtenidos en b).
g) Recprocamente, defnir la funcin afahrenheit que dado el
valor en grados centgrados retorne el valor en grados Fahren-
heit, y verifcarlo con los valores obtenidos en c). e
Ejercicio .. Construir una funcin gmsar(g, m, s) que ingresan-
do la medida de un ngulo en grados (g), minutos (m) y segundos (s),
retorne la medida en radianes.
Por ejemplo,

son . . . . radianes. e
Ejercicio .. Defnir una funcin que retorne la cantidad de cifras de
un nmero en base de dos formas:
a) Usando las ideas del ejercicio ..
b) Usando las ideas del ejercicio .. e
.. Python y variables lgicas
En esta seccin tratamos de deshacer los entuertos de Python con
las variables lgicas, apoyndonos en la funcin isinstance (ejerci-
cio .).
Ejercicio ..
a) Defnir una funcin esbool que determine si el argumento
ingresado es una variable lgica o no desde las matematicas (no
de Python), retornando verdadero o falso. Por ejemplo:
argumento mi mama 1 1.2 1.0 True
debe dar False False False False True
b) Defnir una funcin esnumero que determine si el argumento
ingresado es un nmero. Por ejemplo:
argumento mi mama 1 1.2 1.0 True
debe dar False True True True False
Pg. oz Cap|rulo ,. Puncones
Ayuda: usar el apartado anterior y operadores lgicos como
and y not.
c) Defnir una funcin esentero que determine si el argumento
ingresado es un nmero entero. Por ejemplo:
argumento mi mama 1 1.2 1.0 True
debe dar False True False True False
Atencion: ver el resultado de int(True) == True.
d) Defnir una funcin esnatural que determine si el argumento
ingresado es un nmero entero y positivo. e
.. Variables globales y locales
Las funciones tambin son objetos, y cuando defnimos una fun-
cin se fabrica un objeto de tipo function (funcion), con su propio
espacio o marco, y se construye una variable que tiene por identifcador
el de la funcin y hace referencia a ella.
As como para los mdulos, en el marco de una funcin hay objetos
como instrucciones y variables, que son locales a la funcin.
Los argumentos (si los hubiera) en la defnicin de una funcin se
llaman parametros formales y los que se especifcan en cada llamada se
llaman parametros reales. Al hacer la llamada a la funcin, se realiza
un mecanismo similar al de asignacin, asignando cada uno de los
parmetros formales a sus correspondientes parmetros reales.
De este modo, si f est defnida por
def f(a, b):
...
a y b son variables locales a la funcin, y cuando hacemos la llamada
f(x, y) se hacen las asignaciones a = x y b = y antes de continuar
con las otras instrucciones en f.
En lneas generales cuando dentro del cuerpo de una funcion en-
contramos una variable, entonces:
,.{. Varables globales y locales Pg. o
si la variable es un argumento formal, es local a la funcin.
si la variable nunca est en el miembro izquierdo de una asig-
nacin (siempre est a la derecha), la variable es global y tendr
que ser asignada antes de llamar a la funcin,
si la variable est en el miembro izquierdo de una asignacin, la
variable es local a la funcin y se desconoce afuera (como en los
espacios defnidos por mdulos),...
... salvo que se declare como global con global, y en este caso
ser... global!
Ejercicio .. En una nueva sesin de IDLE, realizar los siguientes
apartados.
a) Poner en la terminal:
def f(x):
a = 3
return x + a
La variable a en la defnicin es local a la funcin, y puede
existir una variable a fuera de la funcin que sea global.
b) Poner sucesivamente:
f(2)
f
type(f)
y estudiar los resultados.
c) Poner
g = f
g(2)
g
type(g)
y comprobar que los tres ltimos resultados son idnticos al
anterior.
d) Poner
Pg. o{ Cap|rulo ,. Puncones
marco o espacio global
marco de la funcin
instrucciones
de la funcin
instrucciones
globales
variables locales
variables globales
1 3
a
f
g
x a
Figura .: Variables globales y locales.
a = 2
f(a)
a
y observar que el valor de la variable global a no ha cambiado. e
Podemos pensar que los distintos elementos que intervienen en el
ejercicio . estn dispuestos como se muestra en la fgura .:
La funcin tiene instrucciones, datos y variables locales, que
ocupan un lugar propio en memoria, formando un objeto que
puede referenciarse como cualquier otro objeto.
En este caso, f y g referencian a la misma funcin.
La variable global a referencia a 2, mientras que la variable a
local a la funcin referencia a 3.
,.{. Varables globales y locales Pg. oy
La instruccin f(a) hace que se produzca la asignacin x = a,
pero x es local a la funcin mientras que a es global.
Como vemos, el tema se complica cuando los identifcadores (los
nombres) de los parmetros formales en la defnicin de la funcin
coinciden con los de otros fuera de ella, o aparecen nuevas variables en
la defnicin de la funcin con los mismos nombres que otras defnidas
fuera de ella.
El siguiente ejercicio muestra varias alternativas ms, y alentamos
a pensar otras.
Ejercicio ..
a) En la terminal de IDLE poner
def f(x):
"""Retorna su argumento."""
print(el argumento ingresado fue:, x)
return x
y explicar los resultados de los siguientes:
i) a = f(1234)
a == 1234
x
ii) a = 1234
b = f(a)
a == b
iii) x = 12
y = f(34)
x == y
b) Reiniciar la terminal (Shell Restart Shell), de modo que ni a
ni x estn defnidas, poner
def f(x):
"""Usa una variable global a."""
return x + a # a es global, no asignada en f
y explicar los resultados de los siguientes:
i) f(1) ii) a = 1
f(2)
iii) a = 1
f(a)
Si a no tiene valor defnido, la llamada a f(a) no tiene
sentido.
Debemos tener presente que cuando defnimos f mediante
Pg. oo Cap|rulo ,. Puncones
def f(a):
...
a es local a la estructura, y puede o no haber otra variable con
el mismo identifcador a fuera de f.
Ver tambin el ejercicio . y el apartado h).
c) Reiniciar la terminal, poner
def f(x):
"""Trata de cambiar la variable a."""
a = 5 # a es local porque se asigna
return x + a
y explicar los resultados de los siguientes:
i) f(1) ii) a = 2
f(1)
a
d) Reiniciar la terminal, poner
def f(x):
"""Usa una variable global a."""
b = a # b es local y a es global
return x + a + b
y volver a resolver las preguntas del apartado anterior.
e) Repetir el apartado c) con
def f():
"""Variable local a con problemas."""
b = a # b es local y a es global
a = 1 # a es local porque se asigna
# y entonces estamos en problemas
# porque la usamos antes de asignar
return a + b
Cambiar el orden de los renglones poniendo primero a = 1
y luego b = a, y repetir.
f ) Cul ser el resultado de poner
,.{. Varables globales y locales Pg. o,
x = 1
def f():
"""x es local o global?"""
print(x)
x = 2
print(x) ?
Por qu?
g) Reiniciar la terminal, poner
def f(x):
"""Trata de cambiar la variable global a."""
global a
a = 5 # a es... global!
return x + a
y explicar los resultados de las siguientes:
i) f(1)
a
ii) a = 2
f(1)
a
h) Poner
def f(x):
"""Trata de cambiar el argumento con global."""
global x # el argumento no puede ser global
x = 2
return x
y ver que da error: una variable no puede ser a la vez argumento
formal y global. e
Ejercicio .. En otra tnica, podemos usar una variable local con el
mismo identifcador que la funcin como en
def f(x):
"""Ejemplo retorcido."""
f = x + 1 # x y f son locales
return f
Pg. o8 Cap|rulo ,. Puncones
y ejecutar el bloque
f
f(1)
f
Desde ya que este uso da lugar a confusiones. e
Ejercicio .. Las funciones pueden considerarse como objetos de la
misma categora que las variables, y podemos tener funciones locales
a una funcin como en el mdulo ocal.
a) Ejecutar ese mdulo y explicar el resultado del bloque:
x = 1
fexterna()
x
b) Cul es el resultado de ejecutar finterna()?, por qu? e
Ejercicio .. Siendo como variables, las funciones tambin pueden
pasarse como argumentos a otras funciones, como se ilustra en el
mdulo fargumento.
Predecir los resultados de las siguientes y luego verifcarlos:
a) aplicar(f, 1)
b) aplicar(g, 1)
c) aplicar(f, aplicar(f, 1))
d) aplicar(g, aplicar(f, 1))
e) aplicar(g, aplicar(g, 1)) e

Captulo
Tomando control
Las cosas empiezan a ponerse interesantes cuando disponemos de
estructuras de control de fujo, esto es, instrucciones que nos permiten
tomar decisiones sobre si realizar o no determinadas instrucciones o
realizarlas repetidas veces. Al disponer de estas estructuras, podremos
verdaderamente comenzar a describir algoritmos, instrucciones (no
necesariamente en un lenguaje de programacin) que nos permiten
llegar a determinado resultado, y apuntar hacia el principal objetivo de
este curso: pensar en los algoritmos y cmo traducirlos a un lenguaje
de programacin.
Prcticamente todos los lenguajes de programacintienendistintas
estructuras de control similares o equivalentes a las de if y while que
estudiamos en este captulo.
k La palabra algoritmo esta relacionada con el nombre de Abu jafar
Muhammad ibn Musa al-Khwarizmi (,8o8,o). A su vez, la
palabra lgebra esta relacionada con su obra.
.. if (si)
Supongamos que al cocinar decidimos bajar el fuego si el agua
hierve, es decir, realizar cierta accin si se cumplen ciertos requisitos.
Pg. ,o Cap|rulo 8. Tomando conrrol
Podramos esquematizar esta decisin con la sentencia:
si el agua hierve entonces bajo el fuego.
A veces queremos realizar una accin si se cumplen ciertos requisi-
tos, pero realizar una accin alternativa si no se cumplen. Por ejemplo,
si para ir al trabajo podemos tomar el colectivo o un taxi que es ms
rpido pero ms caro que el colectivo dependiendo del tiempo que
tengamos decidiramos tomar uno u otro, que podramos esquematizar
como:
si es temprano entonces tomo el colectivo en otro caso tomo el taxi.
En Python podemos tomar este tipo de decisiones, usando if (si
en ingls) para el esquema si... entonces..., y el bloque se escribe como
otros que ya hemos visto:
if condicin: # si el agua hierve entonces
hacer algo # bajo el fuego
usando : en vez de entonces.
Para la variante si... entonces... en otro caso... usamos if junto
con else (en otro caso en ingls), escribindose como:
if condicin: # si es temprano entonces
hacer algo # tomo el colectivo
else: # en otro caso
hacer otra cosa # tomo el taxi
Por supuesto, inmediatamente despus de if tenemos que poner
una condicin (una expresin lgica) que pueda evaluarse como ver-
dadera o falsa.
En fn, cuando hay varias posibilidades, como en
. si est Mateo entonces lo visito,
. en otro caso si est Ana entonces la visito,
. si ninguna de las anteriores es cierta entonces me
quedo en casa.
8.t. if (s) Pg. ,t
en vez de poner algo como else if para en otro caso si, en Python se
pone elif:
if condicin: # si est Mateo
hacer algo # entonces lo visito
elif otra condicin: # en otro caso si est Ana
hacer otra cosa # entonces la visito
else: # si ninguna de las anteriores entonces
hacer una tercer cosa # me quedo en casa
Observemos que estamos dando prioridades: en el ejemplo, si
Mateo est lo voy a visitar, y no importa si Ana est o no. En otras
palabras, si tanto Ana como Mateo estn, visito a Mateo y no a Ana.
Veamos algunos ejemplos concretos sencillos.
Ejercicio .. En este ejercicio usamos la estructura if... else...,
donde se espera que el argumento sea un nmero (entero o decimal).
a) La funcin espositivo (en el mdulo ifwhile) imprime si el
argumento es positivo o no.
Estudiar la construccin y probar la funcin con distintos
argumentos, numricos y no numricos.
b) Cambiar la defnicin de la funcin de modo que retorne verda-
dero o falso en vez de imprimir, cambiando print por return
adecuadamente.
c) Al usar return en una funcin se termina su ejecucin y no se
realizan las instrucciones siguientes. Ver si el bloque interno
de la funcin del apartado anterior es equivalente a:
if x > 0:
return True
return False e
Ejercicio . (piso y techo). Recordando las defniciones de piso y
techo (en el ejercicio .), la funcin piso del mdulo ifwhile imprime
los valores correspondientes al piso de un nmero real usando una
estructura if... elif... else.
Pg. ,z Cap|rulo 8. Tomando conrrol
a) Estudiar las instrucciones de la funcin y comparar los resulta-
dos de la funcin piso con los de la funcin math.floor para
, . y ..
b) Cambiando print por return (en lugares apropiados), modif-
car piso de modo de retornar el valor del piso del argumento.
c) Construir una funcin techo para retornar el techo de un n-
mero real. e
Ejercicio . (signo de un nmero real). La funcin signo R R
se defne como:
signo x =
:

'
si x > ,
si x < ,
si x = .
Defnir una funcin correspondiente en Python usando la estruc-
tura if... elif... else, y probarla con los argumentos , .,
. y .
Observar que x = x signo x para todo x R, y un poco arbi-
trariamente defnimos signo = .
En este y otros ejercicios similares, si no se explicita retornar
o imprimir, puede usarse cualquiera de las dos alternativas (o
ambas). e
Ejercicio . (aos bisiestos). Desarrollar una funcin para decidir
si un ao dado es o no bisiesto.
Segn el calendario gregoriano que usamos, los aos bisiestos son
aquellos divisibles por excepto si divisibles por pero no por
. As, el ao no es bisiesto pero s lo son y .
Este criterio fue establecido por el Papa Gregorio XIII en ,
pero no todos los pases lo adoptaron inmediatamente. En el
ejercicio adoptamos este criterio para cualquier ao, anterior o
posterior a .
A veces con un pequeo esfuerzo podemos hacer el clculo ms
efciente. Un esquema para resolver el problema anterior, si anio
es el ao ingresado, es
8.t. if (s) Pg. ,
if anio % 400 == 0:
print(anio, es bisiesto)
elif anio % 100 == 0:
print(anio, no es bisiesto)
elif anio % 4 == 0:
print(anio, es bisiesto)
else:
print(anio, no es bisiesto)
Sin embargo, el esquema
if anio % 4 != 0:
print(anio, no es bisiesto)
elif anio % 100 != 0:
print(anio, es bisiesto)
elif anio % 400 != 0:
print(anio, no es bisiesto)
else:
print(anio, es bisiesto)
es ms efciente, pues siendo que la mayora de los nmeros no
son mltiplos de , en la mayora de los casos haremos slo una
pregunta con el segundo esquema pero tres con el primero. e
Ejercicio .. El Gobierno ha decidido establecer impuestos a las
ganancias en forma escalonada: los ciudadanos con ingresos hasta
no pagarn impuestos; aqullos con ingresos superiores a
pero que no sobrepasen , debern pagar de im-
puestos; aqullos cuyos ingresos sobrepasen pero no sean
superiores a debern pagar de impuestos, y los que ten-
gan ingresos superiores a debern pagar de impuestos.
a) Defnir una funcin para calcular el impuesto dado el monto
de la ganancia.
b) Modifcarla para determinar tambin la ganancia neta (una vez
deducidos los impuestos).
c) Modifcar las funciones de modo que el impuesto y la ganancia
neta se calculen hasta el centavo (y no ms).
Pg. ,{ Cap|rulo 8. Tomando conrrol
Sugerencia: hay varias posibilidades. Una es usando round
(ver help(round)). e
.. while (mientras)
La estructura while permite realizar una misma tarea varias veces.
Junto confor que veremos ms adelanterecibenel nombre comn
de lazos o bucles, y son estructuras de repeticion.
Supongamos que voy al supermercado con cierto dinero para com-
prar la mayor cantidad posible de botellas de cerveza. Podra ir calcu-
lando el dinero que me va quedando a medida que pongo botellas en
el carrito: cuando no alcance para ms botellas, ir a la caja. Una forma
de poner esquemticamente esta accin es
mientras alcanza el dinero, poner botellas en el carrito.
En Python este esquema se realiza con la construccin
while condicin: # mientras alcanza el dinero,
hacer algo # poner botellas en el carrito
donde, como en el caso de if, la condicin debe ser una expresin
lgica que se evala en verdadero o falso.
Observamos desde ya que:
Si la condicin no es cierta al comienzo, nunca se realiza la
accin: si el dinero inicial no me alcanza, no pongo ninguna
botella en el carrito.
En cambio, si la condicin es cierta al principio, debe modifcarse
con alguna accin posterior, ya que en otro caso llegamos a un
lazo infnito, que nunca termina.
Por ejemplo, si tomamos un nmero positivo y le sumamos
, al resultado le sumamos , y as sucesivamente mientras los
resultados sean positivos. O si tomamos un nmero positivo y lo
dividimos por , luego otra vez por , etc. mientras el resultado
sea positivo.
8.z. while (menrras) Pg. ,y
Paso accin a b r
(antes de empezar) 10 3 sin valor
r = a 10
r >= b: verdadero
r = r - b 7
r >= b: verdadero
r = r - b 4
r >= b: verdadero
r = r - b 1
r >= b: falso
imprimir r
Cuadro .: Prueba de escritorio para el ejercicio ..
Al menos en teora. Como veremos ms adelante, la mquina
tiene un comportamiento propio.
Por cierto, en el ejemplo de las botellas en el supermercado podra-
mos realizar directamente el cociente entre el dinero disponible y el
precio de cada botella, en vez de realizar el lazo mientras. Es lo que
vemos en el prximo ejercicio.
Ejercicio .. La funcin resto (en el mdulo ifwhile) calcula el resto
de la divisin de a N por b N mediante restas sucesivas.
a) Estudiar las instrucciones de la funcin (sin ejecutarla).
b) Todava sin ejecutar la funcin, hacemos una prueba de escrito-
rio. Por ejemplo, si ingresamos a = y b = , podramos hacer
como se indica en el cuadro ., donde indicamos los pasos
sucesivos que se van realizando y los valores de las variables a,
b y r. Podemos comprobar entonces que los valores de a y b al
terminar son los valores originales, mientras que r se modifca
varias veces.
Pods hacer la prueba de escritorio como te parezca ms clara.
Pg. ,o Cap|rulo 8. Tomando conrrol
La presentada es slo una posibilidad.
Las pruebas de escritorio sirven para entender el comporta-
miento de un conjunto de instrucciones y detectar algunos
errores (pero no todos) cuando la lgica no es ni demasiado
sencilla, como los que hemos visto hasta ahora, ni demasiado
complicada como varios de los que veremos ms adelante.
Otra forma algo ms primitiva de entender el com-
portamiento y eventualmente encontrar errores, es probarlo
con distintas entradas, como hemos hecho hasta ahora.
c) Hacer una prueba de escritorio con otros valores de a y b, por
ejemplo con < a < b (en cuyo caso la instruccin dentro del
lazo while no se realiza).
d) Ejecutar la funcin, verifcando que coinciden los resultados
de la funcin y de las pruebas de escritorio.
e) Observar que es importante que a y b sean positivos: dar ejem-
plos de a y b donde el lazo while no termina nunca (sin eje-
cutar la funcin!).
f ) Modifcar la funcin para comparar el valor obtenido con el
resultado de la operacin a % b.
g) Vamos a modifcar la funcin de modo de contar el nmero
de veces que se realiza el lazo while. Para ello agregamos un
contador k que antes del lazo while se inicializa a poniendo k
= 0 y dentro del lazo se incrementa en con k = k + 1. Hacer
estas modifcaciones imprimiendo el valor fnal de k antes de
fnalizar la funcin.
h) Modifcar la funcin para calcular tambin el cociente de a
por b, digamos c, mediante c = a // b. Qu diferencia hay
entre el cociente y el valor fnal de k obtenido en el apartado g)?,
podras explicar por qu? e
Ejercicio . (algoritmo de la divisin). Como ya mencionamos en
el ejercicio ., cuando a y b son enteros, b > , el algoritmo de la
division encuentra enteros q y r, r < b, tales que a = q b + r.
8.z. while (menrras) Pg. ,,
a) Defnir una funcin algodiv para encontrar e imprimir q y r
dados a y b, a y b > , usando slo restas sucesivas.
Sugerencia:
q = 0
r = a
while r >= b:
q = q + 1
r = r - b
Si se usa la sugerencia, observar que encada paso mantenemos
el invariante a = qb + r pues a = b + a = b + (a b) =
b) Extender la funcin anterior para considerar tambin el caso
en que a sea negativo (siempre con b > y usando slo sumas
y restas).
Sugerencia:
if a >= 0:
while r >= b:
...
else: # a < 0
while r < 0:
...
e
Ejercicio . (cifras III). En los ejercicios . y . (y .) vimos
distintas posibilidades para encontrar las cifras de un nmero entero
positivo. Una tercer posibilidad es ir dividiendo sucesivamente por
hasta llegar a (que suponemos tiene cifra), contando las divisiones
hechas, imitando lo hecho en el ejercicio . slo que dividimos en vez
de restar.
Informalmente pondramos:
c
repetir:
c c +
n n
hasta que n =
Pg. ,8 Cap|rulo 8. Tomando conrrol
El esquema anterior est escrito en seudo codigo: una manera
informal para escribir algoritmos. Las operaciones se denotan
como en matemticas (y no como Python), de modo que =
es la igualdad mientras que es la asignacin, aunque nos
tomamos la libertad de indicar con la divisin entera y poner
comentarios como en Python.
Python no tiene la estructura repetir... hasta que..., pero
podemos imitarla usando break en un lazo infnito:
c = 0
while True: # repetir...
c = c + 1
n = n // 10
if n == 0: # ... hasta que n es 0
break
Es decir: con break (o return si estamos en una funcin) podemos
interrumpir un lazo.
Hay que tener cuidado cuando break esta contenido dentro
de lazos anidados (unos dentro de otros), pues solo sale del
lazo mas interno que lo contiene (si hay un unico lazo que
lo contiene no hay problemas).
La funcin cifras (en el mdulo ifwhile) usa esta estructura para
calcular la cantidad de cifras en base de un nmero entero, sin tener
en cuenta el signo, pero considerando que tiene una cifra.
a) Estudiar las instrucciones de la funcin, y probarla con distintas
entradas enteras (positivas, negativas o nulas).
b) Qu pasa si se elimina el rengln n = abs(n)?
c) Habra alguna diferencia si se cambia el lazo principal por
while n > 0:
c = c + 1
n = n // 10 ?
8.. El algorrmo de Eucldes Pg. ,
d) Ver que los resultados de los ejercicios . y . coinciden con
el obtenido al usar cifras.
e) Con return salimos inmediatamente de la funcin: ver que
cambiando break por return c (y comentando la aparicin
fnal de return c), el comportamiento de la funcin no vara.
break tiene como compaero a continue, que en vez de salir del
lazo inmediatamente, saltea lo que resta y vuelve nuevamente al
comienzo del lazo.
Posiblemente no tengamos oportunidad de usar continue en
el curso, pero su uso est permitido (as como el de break). e
.. El algoritmo de Euclides
En esta seccin vemos uno de los resultados ms antiguos que lleva
el nombre de algoritmo.
Dados a, b N, el maximo comun divisor entre a y b, indicado
con mcd(a, b), se defne
()
como el mximo elemento del conjunto de
divisores comunes de a y b:
mcd(a, b) = m ax d Z d a y d b.
Para a y b enteros, la notacin a b signifca a divide a b, es decir,
existe c Z tal que b = c a.
d Z d a y d b no es vaco (pues contiene a ) y est acotado
superiormente (por mna, b), por lo que mcd(a, b) est bien
defnido.
La denominacin maximo comun divisor es la de uso tradicional
en matemticas. Ms recientemente en las escuelas de nuestro
pas se la ha cambiado a divisor comun maximo: me reservo mi
opinin al respecto.
()
Como su nombre lo indica!
Pg. 8o Cap|rulo 8. Tomando conrrol
Para completar la defnicin para cualesquiera a, b Z, defnimos
mcd(a, b) = mcd(a, b),
mcd(, z) = mcd(z, ) = z para todo z Z.
No tiene mucho sentido mcd(, ), y ms que nada por comodi-
dad, defnimos mcd(, ) = , de modo que la relacin anterior sigue
valiendo an para z = .
Cuando mcd(a, b) = es usual decir que los enteros a y b son
primos entre s o coprimos (pero a o b pueden no ser primos: y son
coprimos pero ninguno es primo).
Para nosotros, un nmero p es primo si p N, p > , y los nicos
divisores de p son y p. Los primeros primos son , , , y .
Algunos autores consideran que , , etc. tambin son pri-
mos, pero nosotros los consideraremos siempre mayores que .
En el libro VII de los Elementos, Euclides enuncia una forma de
encontrar el mximo comn divisor, lo que hoy llamamos algoritmo
de Euclides y que en el lenguaje moderno puede leerse como:
Para encontrar el maximo comun divisor (lo que Euclides
llama maxima medida comun) de dos numeros enteros
positivos, debemos restar el menor del mayor hasta que los
dos sean iguales.
k En su obra Los elementos, Euclides de Alejandra (alrededor de :,
:o, a. C.) considera a los numeros como longitudes de segmentos
(no exista el ni los numeros negativos), y de all que tratara
dentro de la geometra cuestiones que hoy consideraramos como
de teora de numeros.
En la escuela elemental a veces se ensea a calcular el mximo co-
mn divisor efectuando primeramente la descomposicin como
producto de primos. Sin embargo, la factorizacin en primos es
computacionalmente difcil, y en general bastante menos efciente
que el algoritmo de Euclides, que an despus de aos es
el ms indicado (con pocas variantes) para calcular el mximo
comn divisor.
8.. El algorrmo de Eucldes Pg. 8t
Un poco antes de Euclides con Pitgoras y el descubrimiento de la
irracionalidad de

, surgi el problema de la conmensurabilidad
de segmentos, es decir, si dados dos segmentos de longitudes a y
b existe otro de longitud c tal que a y b son mltiplos enteros de
c. En otras palabras, c es una medida comn. Si a es irracional
(como

) y b = , entonces no existe c, y el algoritmo de Euclides


no termina nunca.
Ejercicio . (algoritmo de Euclides I). La versin original del algo-
ritmo de Euclides para encontrar mcd(a, b) cuando a y b son enteros
positivos podra ponerse como
mientras a b:
si a > b:
a a b
en otro caso: ac es b > a
b b a
ac es a = b
retornar a
(.)
a) Construir una funcin mcd traduciendo a Python el esquema
anterior (slo para enteros positivos). Probarla con entradas
positivas, e. g., mcd(612, 456) da como resultado 12.
b) Ver que si algn argumento es nulo o negativo el algoritmo no
termina (sin ejecutar la funcin!).
c) Agregar instrucciones al principio para eliminar el caso en que
alguno de los argumentos sea , y tambin para eliminar el caso
en que algn argumento sea negativo.
d) Modifcar la funcin de modo que a la salida escriba tambin
los valores originales de a y b, por ejemplo si las entradas son
a = y b = que imprima
El mximo comn divisor entre 12 y 8 es 4 e
Ejercicio . (algoritmo de Euclides II). Invirtiendo el proceso que
hicimos el ejercicio ., en la versin original del esquema (.) pode-
Pg. 8z Cap|rulo 8. Tomando conrrol
mos cambiar las restas sucesivas por divisiones enteras y restos, como
hacemos en la funcin mcd2 en el mdulo ifwhile.
a) Verifcar el funcionamiento tomando distintas entradas (positi-
vas, negativas o nulas).
b) En vista de que el algoritmo original puede no terminar depen-
diendo de los argumentos, ver que mcd2 termina en un nmero
fnito de pasos, por ejemplo en no ms de b pasos.
Ayuda: en cada paso, el resto es menor que el divisor.
c) Modifcar la funcin de modo que imprima la cantidad de veces
que realiz el lazo while.
d) Qu pasa si se cambia la instruccin while b != 0 por while
b > 0? e
Ejercicio .. Una de las primeras aplicaciones de mcd es simplif-
car nmeros racionales, por ejemplo, escribir como . Defnir
una funcin que dados los enteros p y q, con q , encuentre m Z y
n N de modo que
p
q
=
m
n
y mcd(m, n) = .
Atencin con los signos de p y q! e
Ejercicio .. El mnimo comun multiplo de a, b N, mcm(a, b), se
defne en forma anloga al mximo comn divisor: es el menor entero
del conjunto k N a k y b k.
a) En la escuela nos ensean que si a, b N entonces
mcm(a, b) mcd(a, b) = a b.
Defnir una funcin para calcular mcm(a, b) para a, b N,
usando esta relacin.
b) Cmo podra extenderse la defnicin de mcm(a, b) para
a, b Z? Cul sera el valor de mcm(, z)? e
Ejercicio . (Pablito y su pap I). Pablito y su pap caminan juntos
tomados de la mano. Pablito camina metros en exactamente pasos,
mientras que su padre lo hace en exactamente pasos.
8.{. Ejerccos adconales Pg. 8
0 1 2 3 4 5
Pablito
pap
Figura .: Pasos de Pablito y su pap.
a) Resolver con lpiz y papel: si empiezan a caminar juntos, cun-
tos metros recorrern hasta marcar nuevamente el paso juntos?,
y si el padre caminara

metros en pasos?
Aclaracion: se pregunta si habiendo en algn momento apo-
yado simultneamente los pies izquierdos, cuntos metros des-
pus volvern a apoyarlos simultneamente (ver fgura .).
Respuesta: y metros respectivamente.
b) Qu relacin hay entre el mximo comn divisor o el mnimo
comn mltiplo con el problema de Pablito y su pap?
Recordando el tema de la conmensurabilidad mencionado al in-
troducir el algoritmo de Euclides, no siempre el problema tiene
solucin. Por ejemplo, si Pablito hace metro cada pasos y el
pap

metros cada pasos.
Como para la computadora todos los nmeros son racionales,
el problema siempre tiene solucin computacional.
El ejercicio no requiere programacin, lo que postergamos para
el ejercicio adicional .. e
.. Ejercicios adicionales
Ejercicio . (Pablito y su pap II). Defnir una funcin para resol-
ver en general el problema de Pablito y su pap (ejercicio .), donde
las entradas son el nmero de pasos y la cantidad de metros recorridos
tanto para Pablito como para su pap.
Concretamente, los argumentos de la funcin son los enteros posi-
tivos p
b
, n
b
, d
b
, p
p
, n
p
y d
p
, donde:
Pg. 8{ Cap|rulo 8. Tomando conrrol
p
b
nmero de pasos de Pablito
n
b
d
b
metros recorridos por Pablito en p
b
pasos
p
p
nmero de pasos del pap
n
p
d
p
metros recorridos por el pap en p
p
pasos
Ayuda: pongamos m
b
= n
b
d
b
y m
p
= n
p
d
p
para simplifcar. Si
Pablito hace h
b
pasos, la cantidad de metros recorridos ser
h
b

m
b
p
b
,
y de modo similar para su pap. Como ambos deben realizar un n-
mero par de pasos y recorrer la misma cantidad de metros, ponemos
h
b
= k
b
, h
p
= k
p
y buscamos los valores positivos ms chicos posi-
bles de modo que
k
b

m
b
p
b
= k
p

m
p
p
p
. (.)
Como m
b
= n
b
d
b
, m
p
= n
p
d
p
, simplifcando llegamos a
k
b
n
b
d
p
p
p
= k
p
n
p
d
b
p
b
(.)
donde las incgnitas son k
b
y k
p
que deben ser enteros positivos lo ms
chicos posibles, y por lo tanto las cantidades en (.) deben coincidir
con
mcm(n
b
d
p
p
p
, n
p
d
b
p
b
),
a partir del cual se pueden encontrar k
b
y k
p
, y luego la cantidad de
metros recorridos usando la ecuacin (.). e

Captulo
Sucesiones (secuencias)
Muchas veces necesitamos trabajar con varios objetos a la vez, por
ejemplo cuando estamos estudiando una serie de datos. Una manera
de agrupar objetos es mediante las sucesiones que estudiamos en este
captulo.
Las sucesiones de Python tienen varias similitudes con los conjun-
tos (fnitos) de matemticas. As, podemos ver si cierto elemento est o
no, agruparlos (como en la unin de conjuntos), encontrar la cantidad
de elementos que tienen, e inclusive existe la nocin de sucesin vaca,
que no tiene elementos.
No obstante, las sucesiones no son exactamente como los conjun-
tos de matemticas, ya que pueden tener elementos repetidos (y que
cuentan para su longitud), y el orden es importante (nata no es lo
mismo que tana).
Justamente las cadenas de caracteres como nata que hemos
visto en el captulo son sucesiones.
Ac veremos tres nuevos tipos de sucesiones de Python: tuplas
(tuple), listas (list) y rangos (range).
Python tiene la estructura set (conjunto) que no estudiaremos.
En la seccin . veremos cmo interpretar listas como con-
juntos.
Pg. 8o Cap|rulo . Sucesones
Python tiene seis tipos de sucesiones: los cuatro ya mencionados
(str, list, tuple y range), y bytes y bytearray que no veremos.
.. ndices y secciones
Las sucesiones comparten una serie de operaciones en comn,
como el cardinal o longitud dado por len que ya vimos para
cadenas. Veamos otras dos: ndices y secciones.
Ejercicio . (ndices de sucesiones). Si la sucesin a tiene n elemen-
tos, stos pueden encontrarse individualmente con a[i], donde i es un
ndice, i = , . . . , n . ndices negativos cuentan desde el fnal hacia
adelante (i = , . . . , n), y poniendo i fuera del rango |n, n | da
error.
Resolver los siguientes apartados con a = Mateo Adolfo.
a) Encontrar
i) a[0] ii) a[1] iii) a[4] iv) a[10] v) a[-1]
Para los prximos apartados suponemos que n es la longitud de a,
i. e., que se ha hecho la asignacin n = len(a).
b) Ver que a[0] y a[n-1] dan la primera y la ltima letras de a.
c) Ver que a[-1] y a[-n] dan la ltima y la primera letras de a.
d) Ver que a[n] y a[-n-1] dan error.
e) Conjeturar el resultado de
i) a[1.5] ii) a[1.0] e
Ejercicio . (secciones de sucesiones). Adems de extraer un ele-
mento con un ndice, podemos extraer una parte o seccion (slice en
ingls, que tambin podra traducirse como rebanada) de una sucesin
correspondiente a un rango de ndices continuo.
Poniendo a = Ana Luisa y Mateo Adolfo en la terminal, ha-
cer los siguientes apartados.
.z. tuple (rupla) Pg. 8,
a) Ver qu hacen las siguientes instrucciones, verifcando en cada
caso que el valor de a no ha cambiado, y que el resultado es del
mismo tipo que la sucesin original (str en este caso):
i) a[0:3] ii) a[1:3] iii) a[3:3] iv) a[3:]
v) a[:3] vi) a[:] vii) a[-1:3] viii) a[3:-1]
b) En base al apartado anterior, podras predecir el resultado de
a == a[:4] + a[4:]? (Recordar el ejercicio .).
c) Es un error usar un nico ndice fuera de rango como vimos
en el ejercicio .. Sin embargo, al seccionar en general no hay
problemas, obteniendo eventualmente la cadena vaca :
i) a[2:100] ii) a[100:2]
iii) a[-100:2] iv) a[-100:100]
d) Qu ndices habr que poner para obtener Mateo?
e) Encontrar u, v, x y y de modo que el resultado de a[u:v] +
a[x:y] sea Ana y Mateo.
f ) Con algunas sucesiones podemos encontrar secciones exten-
didas con un tercer parmetro de paso o incremento. Ver qu
hacen las instrucciones:
i) a[0:10:2] ii) a[:10:2] iii) a[-10::2]
iv) a[::2] v) a[::-1] e
.. tuple (tupla)
Los elementos de las cadenas de caracteres son todos del mismo
tipo. En cambio, las tuplas son sucesiones cuyos elementos son obje-
tos arbitrarios. Se indican separando los elementos con comas ,, y
encerrando la tupla entre parntesis (no siempre necesarios) ( y ).
Ejercicio . (tuplas).
a) Poner
a = 123, mi mam, 456
en la terminal, y resolver los siguientes apartados.
Pg. 88 Cap|rulo . Sucesones
i) Encontrar el valor, el tipo (con type) y la longitud (con
len) de a.
ii) Cul te parece que sera el resultado de a[1]?, y de a[20]?
b) Construir una tupla con un nico elemento es un tanto peculiar.
i) Poner a = (5) y verifcar el valor y tipo de a.
No da una tupla para no confundir con los parntesis
usados al agrupar.
ii) Repetir para a = (5,).
c) Por el contrario, la tupla vaca (con longitud ) es () :
i) Poner a = () y encontrar su valor, tipo y longitud.
ii) Comparar los resultados de a = (,) y de a = , con los
del apartado b).
d) Una de las ventajas de las tuplas es que podemos hacer asigna-
ciones mltiples en un mismo rengln: verifcar los valores de
a y b despus de poner
a, b = 1, mi mam
Desde ya que la cantidad de identifcadores a la izquierda y
objetos en la tupla a la derecha debe ser la misma (o un nico
identifcador a la izquierda), obteniendo un error en otro caso.
e) Del mismo modo, podemos preguntar simultneamente por el
valor de varios objetos. Por ejemplo:
a = 1
b = 2
a, b e
Ejercicio . (intercambio). La asignacin mltiple en tuplas nos
permite hacer el intercambio de variables (swap en ingls), poniendo
en una el valor de la otra y recprocamente.
a) Poner
a = 1
b = 2
.z. tuple (rupla) Pg. 8
1 2
a
b
a, b = b, a
1 2
a
b

Figura .: Efecto del intercambio de variables.
y verifcar los valores de a y b.
b) Poner ahora
a, b = b, a
y verifcar nuevamente los valores de a y b.
El efecto del intercambio se ilustra en la fgura ..
c) Tambin podemos hacer operaciones en combinacin con el
intercambio, como en
a, b = 1, 2
a, b = a + b, a - b
a, b
d) En la funcin mcd2 (en el mdulo ifwhile) reemplazar los ren-
glones
r = a % b
a = b
b = r
por el nico rengln
a, b = b, a % b
Hay alguna diferencia en el comportamiento? e
Ejercicio .. Hay veces que es conveniente tener ms de un valor
como resultado.
Por ejemplo, en el algoritmo de la divisin (que ejercicios . y .)
a veces queremos conocer tanto el valor del cociente, q, como el del
resto, r.
Pg. o Cap|rulo . Sucesones
a) Averiguar qu hace la funcin divmod y usarla para distintos
valores.
b) Con los valores de q y r como en el ejercicio ., construir
una funcin que retorne la tupla (q, r) y luego comparar los
resultados con los de divmod para diferentes entradas (positivas
y negativas). e
.. list (lista)
Nosotros usaremos tuplas muy poco. Las usaremos algunas veces
para indicar coordenadas como en (, ), para el intercambio men-
cionado en el ejercicio ., para hacer asignaciones mltiples como en
el ejercicio ..d), y ocasionalmente como argumentos o resultados de
funciones como isinstance o divmod.
Usaremos mucho ms listas, similares a las tuplas, donde tambin
los elementos se separan por , pero se encierran entre corchetes
(ahora siempre) [ y ] . Como con las tuplas, los elementos de una
lista pueden ser objetos de cualquier tipo, como en [1, [2, 3]] o [1,
[mi, (4, 5)]].
Ejercicio . (listas).
a) Poniendo en la terminal
a = [123, mi mam, 456]
i) Repetir el ejercicio ..a).
ii) Cmo se puede obtener el elemento mi mam de a?, y
la i en mi mam?
Aclaracion: se piden expresiones en trminos de a e n-
dices.
b) Adiferencia de las tuplas, la construccin de listas con un nico
elemento o de la lista vaca son lo que uno esperara: verifcar
el valor, tipo y longitud de a cuando
i) a = [] ii) a = [5] iii) a = [5,]
.. list (lsra) Pg. t
[5,] y (5,) son secuencias de longitud , lo mismo que
[5], pero (5) no es una secuencia.
c) A veces podemos mezclar tuplas y listas. Ver los resultados de:
a, b = [1, 2]
[a, b] = 1, 2
d) Aunque hay que escribir un poco ms (porque con las tuplas
no tenemos que escribir parntesis), tambin podemos hacer
asignaciones mltiples e intercambios con listas como hicimos
con tuplas (en los ejercicios . y .).
i) En la terminal poner [a, b] = [1, 2] y verifcar los va-
lores de a y b.
ii) Poner [a, b] = [b, a] y volver a verifcar los valores de
a y b. e
Ejercicio . (mutables e inmutables). Una diferencia esencial entre
tuplas y listas es que podemos modifcar los elementos de una lista, y
no los de una tupla.
a) Poner en la terminal a = [1, 2, 3] y verifcar el valor de a.
b) Poner a[0] = 5 y volver a verifcar el valor de a.
c) Poner b = a y verifcar el valor de b.
d) Poner a[0] = 4 y verifcar los valores de a y b.
e) Poner a = [7, 8, 9] y verifcar los valores de a y b.
Cambios de partes de a se refejan en b, pero una nueva
asignacion a a no modifca b.
f ) Repetir los apartados anteriores cambiando a tuplas en vez de
listas, es decir, comenzando con
a = 1, 2, 3
y ver en qu casos da error. e
El ejercicio anterior muestra que podemos modifcar los elementos
de una lista (sin asignar la lista completa), y por eso decimos que las
Pg. z Cap|rulo . Sucesones
listas son mutables. En cambio, las tuplas son inmutables: sus valores no
pueden modifcarse y para cambiarlos hay que crear un nuevo objeto
y hacer una nueva asignacin.
Dentro de ciertos lmites, como vemos en el ejercicio ..
Ejercicio .. Los nmeros y cadenas tambin son inmutables. Com-
probar que
a = mi mam
a[0] = p
da error. e
Las listas permiten que se cambien individualmente sus elementos,
y tambin que se agreguen o quiten.
Ejercicio . (operaciones con listas). Pongamos
a = [a, b, r, a, c, a, d, a]
a) Sin usar Python: cuntos elementos tiene a?, cul es el valor
de a[3]?
b) En cada uno de los siguientes, despus de cada operacin veri-
fcar el valor resultante de a y su longitud con len(a).
i) a.append(b) ii) a.pop()
iii) a.pop(0) iv) a.insert(3, s)
v) a.insert(-1, x) vi) a.reverse()
Con help(list) obtenemos informacin sobre stas y otras
operaciones de listas. Para algn mtodo en particular pode-
mos poner, por ejemplo, help(list.pop). e
Operaciones como append, insert y pop se llaman metodos, en
este caso de la clase list, y se comportan como funciones (anteponien-
do el objeto de la clase correspondiente, como en a.pop()). Varios de
estos mtodos modifcan la lista sobre la cual actan, y a veces el valor
que retornan es None.
.. list (lsra) Pg.
En realidad, podemos modifcar parte de una lista sin necesidad de
usar pop, append o insert, sino slo asignaciones a secciones, como
ilustra el ejercicio siguiente.
Ejercicio .. Ejecutar:
a = [1, 2, 3, 4, 5]
a[2:4]
a[2:4] = [6, 7, 8, 9]
a
a[1:-3]
a[1:-3] = [3, 4]
a
a[1:-1]
a[1:-1] = []
a e
En particular, podemos decir que
lista.append(x) equivale a a[-1:] = [a[-1], x]
lista.insert(i, x) equivale a a[i:i+1] = [x, a[i]]
()
lista.pop(i) equivale a a[i:i+1] = []
aunque, como vimos, las asignaciones de secciones permiten operacio-
nes ms complejas ya que podemos cambiar ms de un elemento.
Ejercicio .. Si a es una lista (por ejemplo a = [1, 2, 3]), cules
son las diferencias entre a.reverse() y a[::-1]?
Ayuda: mirar el resultado de cada operacin (lo que Python escribe
en la terminal) y de a al fnal de cada una de ellas. e
Ejercicio .. La mutabilidad hace que debamos ser cuidadosos cuan-
do las listas son argumentos de funciones.
Por ejemplo, defnamos
()
Supuesto que a[i] exista.
Pg. { Cap|rulo . Sucesones
def f(a):
"""Agregar 1 a la lista a."""
a.append(1)
Poniendo
a = [2]
b = a
f(a)
b
vemos que b se ha modifcado, y ahora es [2, 1]. e
Ejercicio .. Si queremos trabajar con una copia de la lista a, pode-
mos poner b = a[:].
a) Evaluar
a = [1, 2, 3]
b = a
c = a[:]
a[0] = 4
y comprobar los valores de a, b y c.
b) Modifcar la funcin f(a) del ejercicio ., de modo de retor-
nar una copia de a a la que se le ha agregado , sin modifcar la
lista a. e
Ejercicio .. En realidad la cosa no es tan sencilla como sugiere el
ejercicio .. La asignacin a = b[:] se llama una copia playa o
plana (shallow), y est bien para listas que no contienen otras listas.
Pero en cuanto hay otra lista como elemento las cosas se complican
como en los ejercicios . y ..
a) Por ejemplo:
a = [1, [2, 3]]
b = a[:]
a[1][1] = 4
a
b
.. list (lsra) Pg. y
b) El problema no es slo cuando el contenedor ms grande es
una lista:
a = (1, [2, 3])
b = a
a[1][1] = 4 # modificamos una tupla!
b
El comportamiento en a) es particularmente fastidioso cuando
miramos a matrices como listas de listas, porque queremos una
copia de la matriz donde no cambien las entradas.
En la jerga de Python queremos una copia profunda (deep).
No vamos a necesitar este tipo de copias en lo que hacemos (o
podemos arreglarnos sin ellas), as que no vamos a insistir con el
tema. Los inquietos pueden ver la muy buena explicacin en el
manual de la biblioteca (Data Types copy). e
Dada la mutabilidad de las listas, debemos recordar:
Cuando pasamos una lista como argumento de
una funcion, hay que preguntarse siempre si al
terminar la funcion la lista original
debe,
puede, o
no debe
modifcarse.

El siguiente ejercicio muestra otro caso de mutablitis aguda.


Ejercicio . (problemas con asignaciones mltiples). Las asigna-
ciones mltiples e intercambios pueden ser convenientes (como en
los ejercicios . y .), pero debemos tener cuidado cuando hay listas
involucradas porque son mutables.
Conjeturar el valor de x despus de las instrucciones
Pg. o Cap|rulo . Sucesones
x = [0, 1]
i = 0
i, x[i] = 1, 2
y luego verifcar la conjetura con Python. e
.. range (rango)
La ltima sucesin de Python que veremos es range o rango, una
progresin aritmtica de enteros. A diferencia de las cadenas de carac-
teres, las tuplas y las listas, range es una enumeracin virtual, en el
sentido de que sus elementos no ocupan lugar en la secuencia. Como
las cadenas de caracteres y a diferencia de tuplas y listas, los elementos
de range son siempre del mismo tipo: enteros.
range tiene entre uno y tres argumentos, que deben ser enteros y
se usan en forma similar a las secciones en el ejercicio ..
Si hay tres argumentos el primero es donde comienza, el segundo
es el siguiente al valor fnal, y el ltimo se interpreta como el paso
o incremento de la progresin. El incremento puede ser positivo
o negativo, pero no nulo.
Si tiene dos argumentos, se interpreta que el paso (el tercero que
falta) es , y con un nico argumento se interpreta que el primer
elemento de la progresin es .
Si el valor del incremento es positivo y el valor inicial es mayor
o igual al fnal, el resultado (despus de tomar list) es la lista
vaca, [].
Anlogos resultados se obtienen cuando el incremento es
negativo y el valor inicial es menor o igual al fnal.
Ejercicio . (range).
a) Usando help, encontrar qu hace range.
b) Cul es el resultado de range(6)?
c) Encontrar el tipo de range(6) (con type).
.y. Operacones comunes Pg. ,
d) Ver los resultados de:
i) list(range(6)) ii) len(range(6))
iii) list(range(0, 6)) iv) list(range(6, 6))
e) Sin evaluar, conjeturar el valor y longitud de list(range(15,
6, -3)), y luego verifcar la conjetura en Python.
f ) Los rangos admiten operaciones comunes a las sucesiones, co-
mo ndices, secciones o longitudes. Evaluar:
i) list(range(7)) ii) range(7)[4]
iii) range(7)[1:5:2] iv) list(range(7)[1:5:2])
v) len(range(7)) vi) len(range(7)[1:5:2]) e
.. Operaciones comunes
Vimos que ndices y secciones son operaciones que se pueden
realizar en todas las sucesiones, y tambin que la longitud se puede
determinar con len en todos los casos. Veamos algunas ms.
Ejercicio . (in). Anlogamente a la nocin matemtica de perte-
nencia en conjuntos, la instruccin in (literalmente en) de Python nos
permite decidir si determinado elemento est en un contenedor.
a) a in mi mama b) b in mi mama
c) in mi mama d) in mi mama
e) a in f ) in
g) in h) 1 in [1, 2, 3]
i) 1 in [[1, 2], 3] j) 1 in range(5)
A diferencia del comportamiento en otras sucesiones, in en cade-
nas tambin nos permite decidir si una cadena es parte de otra,
es decir, si es una subcadena. Nosotros no veremos este uso en el
curso. e
Ejercicio .. La concatenacin que vimos en el ejercicio . con
+ , se extiende a tuplas y listas (los sumandos tienen que ser del
mismo tipo).
Ver el resultado de:
Pg. 8 Cap|rulo . Sucesones
a) [1, 2] + [3, 4]
b) (1, 2) + (3, 4)
c) [1, 2] + (3, 4) e
Ejercicio . (isinstance II). Con isinstance (ejercicio .) po-
demos determinar si un objeto es de cierto tipo. Si queremos deter-
minar si es de uno entre varios tipos posibles, ponemos el segundo
argumento de isinstance como tupla.
a) Si queremos determinar si x es un nmero (entero o real),
podramos poner
isinstance(x, (int, float))
Probar este esquema cuando x es:
i) 1 ii) 1.2 iii) mi mama iv) False
La ltima respuesta no es satisfactoria si queremos que los
valores lgicos no sean considerados como enteros (ver el
ejercicio .).
b) Defnir una funcin essecuencia que determine si su argu-
mento es o no una secuencia (cadena, tupla, lista o rango). e
Ejercicio . (cambiando el tipo de sucesin). Es posible cambiar
el tipo de una sucesin a otra, dentro de ciertas restricciones.
a) Determinar el tipo de a = [1, 2, 3] y encontrar:
i) str(a) ii) tuple(a) iii) list(a)
b) Si a = (1, 2, 3), ver que tuple(list(a)) es a.
c) De la misma forma, ver que cuando a = [1, 2, 3], entonces
list(tuple(a)) es a.
d) Determinar el tipo de a = Ana Luisa y encontrar:
i) str(a) ii) tuple(a) iii) list(a)
iv) Es cierto que str(list(a)) es a?
Si convertimos una cadena a lista (por ejemplo), podemos recu-
perar la cadena a partir de la lista de caracteres usando la funcin
.o. Comenraros Pg.
sumar que veremos en el ejercicio .. Python tiene el mtodo
join que no veremos en el curso. e
.. Comentarios
La mutabilidad de las listas es un arma de doble flo. Por un lado
al usarlas aumenta la rapidez de ejecucin, pero por otro nos
dan ms de una sorpresa desagradable, como se puede apreciar
con la aparicin de numerosos smbolos

en la seccin ..
El concepto de mutabilidad e inmutabilidad es propio de Python,
y no existe en lenguajes como C o Pascal. Estos lenguajes tienen
el concepto de pasar por valor o referencia, que tiene ciertas
similitudes.
La estructura de arreglo (listas con objetos del mismo tipo con-
secutivos en memoria) es de suma importancia para clculos
cientfcos de gran tamao. Esta estructura es distinta a la de
lista y no est implementada en Python.
En este curso ser sufciente emular arreglos usando listas
porque los ejemplos son de tamao muy reducido.
El mdulo no estndar numpy implementa arreglos en Python
efcientemente, pero no lo usaremos en el curso.
Varios de los ejercicios estn inspirados en los ejemplos del tuto-
rial y del manual de referencia de Python.

Captulo
Recorriendo sucesiones
Muchas veces tendremos que repetir una misma accin para ca-
da elemento de una sucesin. Por ejemplo, para contar la cantidad
de elementos en una lista la recorreramos sumando un por cada
elemento. Algunas de estas acciones son tan comunes que Python
tiene funciones predefnidas para esto, y para contar la cantidad de
elementos usaramos directamente len.
Sin embargo, a veces no hay funciones predefnidas o cuesta ms en-
contrarlas que hacerlas directamente. Para estos casos, Python cuenta
con la sentencia for (para) que estudiamos en este captulo.
.. for (para)
Si queremos recorrer los elementos de una sucesin, para contarlos
o para ver si alguno satisface cierta propiedad, intentaramos algo
como:
hacer algo con cada elemento de una sucesin.
Veremos un esquema similar cuando veamos listas por compren-
sin,
()
pero normalmente se tiene algo un poco al revs:
()
Concretamente, el esquema (.).
to.t. for (para) Pg. tot
para cada elemento de la sucesin hacer algo con l.
Esta ltima versin se hace en Python usando for, en la forma
for x in iterable: # para cada x en iterable
hacer
_
algo
_
con x
(.)
donde iterable puede ser una sucesin (cadena, tupla, lista o rango).
Recordar que las secuencias tienen un orden que se puede obtener
mirando los ndices, como hicimos al principio del captulo .
Las similitudes con el uso de in (ejercicio .) son intencionales.
Hay otros iterables (que no son sucesiones) en los que se pue-
de usar for, como los archivos de texto que estudiamos en el
captulo .
Miremos algunos ejemplos sencillos.
Ejercicio .. Consideremos a = [3, 5, 7].
a) Si queremos imprimir los elementos de a podemos poner
for x in a: # para cada elemento de a
print(x) # imprimirlo (con el orden en a)
for toma los elementos en el orden en que aparecen en
la secuencia.
b) Si queremos encontrar la cantidad de elementos, como en
len(a), imitando lo hecho en el ejercicio ..g), llamamos
long al contador y ponemos
long = 0
for x in a:
long = long + 1 # la accin no depende de x
long
c) Ver que las instrucciones en b) son equivalentes a:
long = 0
for i in range(len(a)):
Pg. toz Cap|rulo to. Recorrendo sucesones
long = long + 1 # la accin no depende de i
long e
La similitud de las construcciones
for x in a:
...
y
for i in range...:
...
hace que muchas veces se confundan los elementos de una
sucesion con los ndices correspondientes. en general, el ob-
jeto x = a[i] de la sucesion a es distinto del ndice i.
Ejercicio .. La variable que aparece inmediatamente despus de
for puede tener cualquier nombre (identifcador), pero hay que tener
cuidado porque la variable no es local a la construccin.
Comprobar que el valor de x cambia en cada una de las siguientes:
a) x = 5 # x no est en la lista
for x in [1, 2, 3]:
print(x)
x # x no es 5
b) x = 2 # x est en la lista
b = [1, x, 3]
for x in b:
print(x)
x # x no es 2 e
Ejercicio .. En el ejercicio . vimos que la construccin x in
a nos dice si el objeto x est en la secuencia a. Podemos imitar esta
accin recorriendo la sucesin a buscando el objeto x, terminando en
cuanto lo encontremos:
to.t. for (para) Pg. to
t = False
for y in a:
if y == x:
t = True
break
t
(.)
a) Comprobar la validez del esquema probndolo para los valores
de a y x del ejercicio ..
b) Dentro de una funcin podemos reemplazar break por return
en el esquema (.), eliminando la variable t:
for y in a:
if y == x:
return True
return False
(.)
Defnir una funcin estaen(a, x) que determina si x est
en la sucesin a usando esta variante (agregando encabezado y
documentacin), y compararlo con los resultados de x in a
para los valores de a y x del ejercicio .. e
Ejercicio .. En ocasiones no slo queremos saber si el objeto x est
en la secuencia a, sino tambin conocer las posiciones (ndices) que
ocupa.
Defnir una funcin posiciones(a, x) con el siguiente esquema
(agregando encabezado y documentacin):
p = []
for i in range(len(a)):
if x == a[i]:
p.append(i)
return p
(.)
a) Probar la funcin para distintos valores de a y x, por ejemplo.
Qu pasa si a es la secuencia vaca?, y si x no est en a?
Pg. to{ Cap|rulo to. Recorrendo sucesones
b) Cmo podra expresarse la instruccin x in a en trminos
de posiciones(a, x)? e
Ejercicio . (index y count). Adems de in, para saber si determi-
nado elemento est en la sucesin, podemos usar index para encontrar
la primera posicin o count para ver cuntas veces aparece.
a) Averiguar qu hacen estos mtodos poniendo, por ejemplo,
help(list.count)
help(list.index)
b) Poniendo a = mi mama me mima (sin tildes), hacer los si-
guientes:
i) Contar las veces que aparece la letra a en a manualmen-
te, y verifcar que a.count(a) da el mismo resultado.
ii) Encontrar la primera posicin de la letra a en a manual-
mente, y luego usar a.index(a).
iii) La letra p no est en a: ver los resultados de
p in a
a.index(p)
a.count(p)
c) Expresar index en trminos de la funcin posiciones del
ejercicio ., es decir, encontrar una expresin que involu-
cre posiciones(a, x) que sea equivalente a a.index(x).
Repetir para count (en vez de index).
d) Defnir una funcin sacar1(a, x) que elimina la primera
aparicin del objeto x en la lista a (modifcndola) si es que x
est en a usando slo if, count, index y pop. e
Ejercicio . (mximos y mnimos). A veces queremos encontrar
el mximo de una secuencia y su ubicacin en ella.
a) Defnir una funcin maxpos(a) para encontrar el mximo de
una secuencia a y la primera posicin que ocupa siguiendo el
esquema (agregar encabezado y documentacin):
to.t. for (para) Pg. toy
n = len(a)
if n == 0:
print(
***
secuencia vaca)
return # retorna None y termina
xmax, imax = a[0], 0
for i in range(1, n):
if a[i] > xmax:
xmax, imax = a[i], i
return xmax, imax
b) Ver los resultados de:
i) maxpos([1, 2, 3]) ii) maxpos((1, 2, 3))
iii) maxpos(1, 2, 3) iv) maxpos(mi mama)
v) maxpos([1, a]) vi) maxpos([])
c) Python tiene la funcin max. Averiguar qu hace, repetir el
apartado anterior (cambiando maxpos por max) y comparar los
comportamientos.
d) Anlogamente, considerar el caso del mnimo de una secuencia
y compararla con la funcin min de Python. e
Veamos cmo podemos copiar la idea del contador long en el ejer-
cicio ..b) para sumar los elementos de una secuencia. Por ejemplo,
para encontrar la suma de los elementos de
a = [1, 2.1, 3.5, -4.7]
con una calculadora, haramos las sumas sucesivas
+ . = ., . + . = ., . . = .. (.)
Para repetir este esquema en programacin es conveniente usar
una variable, a veces llamada acumulador (en vez de contador), en la
que se van guardando los resultados parciales, en este caso de la suma.
Llamando s al acumulador, haramos:
s = 0 # valor inicial de s
s = s + 1 # s -> 1
Pg. too Cap|rulo to. Recorrendo sucesones
s = s + 2.1 # s -> 3.1
s = s + 3.5 # s -> 6.6
s = s + (-4.7) # s -> 1.9
que es equivalente a la ecuacin (.) y puede escribirse con un lazo
for como:
s = 0 # acumulador, inicialmente en 0
for x in a: # s ser sucesivamente
s = s + x # 1, 3.1, 6.6 y 1.9
s
(.)
Ejercicio . (sumas y promedios). Usando el esquema (.), def-
nir una funcin suma(a) que dada la sucesin a encuentra su suma.
a) Evaluar suma([1, 2.1, 3.5, -4.7]) para comprobar el com-
portamiento.
b) Ver el resultado de suma([Mateo, Adolfo]).
Da error porque no se pueden sumar un numero (el valor
inicial del acumulador) y una cadena.
c) Cul es el resultado de suma([])?
Cuando la secuencia correspondiente es vaca, el lazo
for no se ejecuta.
d) Python tiene la funcin sum: averiguar qu hace esta funcin,
y usarla en los apartados anteriores.
e) Usando suma y len, defnir una funcin promedio que dada
una lista de nmeros construya su promedio. Por ejemplo,
promedio([1, 2.1, 3.5]) debera dar como resultado ..
Atencion: el promedio, an de nmeros enteros, en general
es un nmero decimal. Por ejemplo, el promedio de y es
.. e
Repasando lo que hicimos, en particular el esquema del ejerci-
cio ., vemos que podramos poner una nica funcin para sumar
to.t. for (para) Pg. to,
nmeros o cadenas de caracteres si ponemos el primer elemento de la
sucesin como valor inicial del acumulador.
Nos gustara defnir un valor conveniente para la suma de suce-
siones vacas como o [], y arbitrariamente decidimos que en esos
casos pondremos un cartel avisando de la situacin y retornaremos la
sucesin original.
Tendramos algo como:
if len(a) == 0: # nada para sumar
print(
***
Atencin: Sucesin vaca)
return a # nos vamos
s = a[0] # el primer elemento de a
for x in a[1:]: # para c/u de los restantes...
s = s + x
return s
Ejercicio .. Defnir una nueva funcin sumar en base a estas ideas
y comprobar su comportamiento en distintas sucesiones como:
a) [1, 2, 3] b) Mateo
c) [1, [2, 3], 4] d) [Mateo]
e) [[1, 2], [3, 4]] f ) [Mateo, Adolfo]
g) [] h) [M, a, t, e, o]
i) j) ()
k) range(6) l) range(6, 1)
m) range(1, 6, 2) e
Ejercicio . (factorial). Recordemos que para n N, el factorial se
defne por
n! = n. (.)
a) Defnir una funcin factorial(n) para calcular n! usando la
ecuacin (.), usando el esquema:
f = 1
for i in range(1:n+1):
f = f
*
i
(.)
Pg. to8 Cap|rulo to. Recorrendo sucesones
En realidad, tanto en la ecuacin (.) como en en el esque-
ma (.), podramos empezar multiplicando por en vez de
por . Se empieza desde como regla mnemotcnica.
Cuando queremos calcular la suma de varios terminos,
ponemos inicialmente el valor de la suma en .
En cambio, cuando queremos calcular el producto de
varios terminos, ponemos el valor inicial del producto
en .
b) La formula de Stirling establece que cuando n es bastante gran-
de,
n! n
n
e
n

n.
Construir una funcin stirling para calcular esta aproxima-
cin, y probarla para n = , y , comparando los resul-
tados con factorial. e
El teorema del binomio
()
expresa que
(x + y)
n
=
n

k=
_
n
k
_ x
k
y
nk
, (.)
donde
_
n
k
_ =
n!
k! (n k)!
=
n (n ) (n k + )
k!
(.)
son los coefcientes binomiales o numeros combinatorios ( k n).
Cuando x = y = , (.) se reduce
n
=

n
k=
{
n
k
), que tiene una
bonita interpretacin combinatoria: si el conjunto total tiene car-
dinal n, el miembro izquierdo es la cantidad total de subconjuntos
mientras que {
n
k
) es la cantidad de subconjuntos con exactamente
k elementos.
()
A veces llamado teorema del binomio de ^ewton.
to.t. for (para) Pg. to
Ejercicio.. Hacer el clculo de los tres factoriales (n!, k! y (nk)!)
en el segundo miembro de las igualdades en (.) es inefciente, y es
mejor hacer la divisin entera a la derecha de esas igualdades porque
involucra muchas menos multiplicaciones.
a) Volcar esta idea en una funcin para calcular el coefciente
binomial {
n
k
) donde los argumentos son n y k ( k n).
b) Como {
n
k
) = {
n
nk
), si k > n realizaremos menos multiplica-
ciones evaluando {
n
nk
) en vez de {
n
k
) usando el producto a la
derecha de (.).
Agregar un if a la funcin del apartado anterior para usar
las operaciones a la derecha de (.) slo cuando k n. e
Ejercicio . (sumas acumuladas). En muchas aplicaciones por
ejemplo de estadstica necesitamos calcular las sumas acumuladas
de una lista de nmeros. Esto es, si la lista es a = (a

, a

, . . . , a
n
), la
lista de acumuladas es la lista de sumas parciales,
s = (a

, a

+ a

, a

+ a

+ a

, . . . , a

+ + a
n
),
o, poniendo s = (s

, s

, . . . , s
n
), ms formalmente tenemos
s
k
=
k

i=
a
i
, k = , . . . , n. (.)
Ponemos las listas a y s como vectores para indicar que el orden
es importante.
Esto se parece mucho a las ecuaciones (.) y podemos combinar
los esquemas (.) y (.) para obtener el siguiente esquema, en el
que suponemos que la lista original es a:
suma = 0
acums = []
for x in a:
suma = suma + x
acums.append(suma)
acums
(.)
Pg. tto Cap|rulo to. Recorrendo sucesones
a) Defnir una funcin acumuladas siguiendo el esquema (.),
y aplicarla para calcular las acumuladas de los impares entre
y .
b) Una posibilidad es construir las sumas
[sum(a[:k]) for k in range(1, len(a))]
pero es terriblemente inefciente porque volvemos a empezar
cada vez.
c) A partir de (.), podemos poner
s

= a

, s
k
= s
k
+ a
k
para k > ,
y de aqu que
a

= s

, a
k
= s
k
s
k
para k > . (.)
Construir una funcin desacumular que dada la lista de
nmeros b, encuentre la lista a tal que acumuladas(a) sea b.
Atencion: los ndices en (.) y (.) empiezan con , pero
Python pone los ndices a partir de .
k Los que hayan estudiado derivadas e integrales podran reconocer
que acumular es como la integracion y desacumular es como
la derivacion. Tal vez pueda verse mejor esta relacion tomando
x = en (.) y (.)
As, en el marco de matematicas fnitas es muy natural que un
proceso sea el inverso del otro, lo que en matematicas del continuo
es el teorema fundamental del calculo. e
Vale la pena comparar el uso de acumuladores para la suma, el
producto y otras operaciones binarias similares cuando se aplican a
ms de dos valores.
Indicando por al operador, en todos estos casos usamos un es-
quema como:
s = valor
_
inicial # valor inicial del acumulador
for x in secuencia:
s = s x
s
to.t. for (para) Pg. ttt
Por ejemplo:
Para la suma ponemos inicialmente s = 0 y en cada paso s =
s + x.
Para el producto ponemos inicialmente p = 1 y en cada paso p
= p
*
x.
Para ver si todos los valores lgicos de una lista son verdaderos,
ponemos inicialmente t = True y en cada paso t = x and t.
En este caso, dado que una vez que t sea falso, siempre lo
seguir siendo, podemos poner (ver tambin el esquema (.)):
t = True
for x in a:
if not x:
t = False
break # salir del lazo
t
Consideraciones similares se aplican para ver si alguno de los
valores lgicos de una lista es verdadero.
Finalmente, como vimos en el ejercicio . para la suma (de
nmeros u otros objetos) y en el ejercicio . para el mximo,
cuando las secuencias a considerar son no vacas podemos poner
a secuencia[0] como valor inicial del acumulador.
Ac vienen preguntas flosfcas de cunto valen:
la suma de ningn nmero,
el producto de ningn nmero, o
el mximo de una lista vaca.
Ninguno tiene mucho sentido.
Es decir, ponemos el acumulador inicialmente en para la
suma o en para el producto slo por una cuestin de simplici-
dad, pensando en que la lista con la que estamos trabajando es
no vaca.
Ejercicio . (el ro y los caballos). Veamos algunos peligros que
pueden surgir al cambiar de caballo en la mitad del ro.
Pg. ttz Cap|rulo to. Recorrendo sucesones
*
/ \
* *
/ \ / \
* * *
/ \ / \ / \
* * * *
Figura .: Arbolito de Navidad con estrellas en la parte inferior.
a) Si cambiamos la secuencia sobre la que se itera dentro del lazo,
podemos tener un lazo infnito:
b = [1]
for x in b:
b.append(1)
b) Tratando de eliminar las apariciones de x en la lista a (modif-
cndola), ponemos
def sacar(a, x):
"""Eliminar x de la lista a."""
for i in range(len(a)):
if a[i] == x:
a.pop(i)
Probar la funcin cuando a = [1, 2, 3, 4] y
i) x = 5 ii) x = 3
Cul es el problema? Cmo se podra arreglar?
Sugerencia para arreglar la funcion: recorrer la lista desde
atrs hacia adelante.
Ver tambin los ejercicios ..d), . y .. e
Ejercicio .. Construir una funcin navidad(n) que imprima un
arbolito de Navidad como se muestra en la fgura . para n = . El
rbol debe tener una estrella en la punta y n estrellas en la parte de
abajo.
to.z. Lsras por comprensn Pg. tt
Ayuda: la cantidad de espacios en blanco iniciales disminuye a
medida que bajamos y recordar la casita en el ejercicio .. e
.. Listas por comprensin
Los conjuntos se pueden defnir por inclusion como en A = , , ,
o por comprension como en B = n

n A. En este ejemplo parti-


cular, tambin podemos poner en forma equivalente la defnicin por
inclusin B = , , .
De modo similar, las listas tambin pueden defnirse por inclusin,
poniendo explcitamente los elementos como en
a = [1, 2, 3]
como hemos hecho hasta ahora, o por comprension como en
b = [n
**
2 for n in a]
y en este caso el valor de b resulta [1, 4, 9]: para cada elemento de
a, en el orden dado en a, se ejecuta la operacin indicada (aqu elevar
al cuadrado).
Este mecanismo de Python se llama de listas por comprension, y
tiene la estructura general:
[f(x) for x in iterable] (.)
donde f es una funcin defnida para los elementos de iterable, y es
equivalente al lazo for:
lista = [] # acumulador
for x in iterable:
lista.append(f(x))
lista
(.)
Comparndolas, la construccin (.) no ahorra mucho en es-
critura respecto de (.), pero tal vez s en claridad: en un rengln
entendemos qu estamos haciendo.
Otras observaciones:
Pg. tt{ Cap|rulo to. Recorrendo sucesones
Recordemos que, a diferencia de los conjuntos, las sucesiones
pueden tener elementos repetidos y el orden es importante.
El iterable en (.) o (.) tiene que estar defnido, en caso
contrario obtenemos un error.
Ejercicio ..
a) Evaluar [n
**
2 for n in a] cuando
i) a = [1, 2] ii) a = [2, 1] iii) a = [1, 2, 1]
viendo que la operacin n
**
2 se realiza en cada elemento de a,
respetando el orden.
b) Cambiando listas por tuplas en el apartado anterior, ver los
resultados de:
i) [n
**
2 for n in (1, 2, 1)]
ii) (n
**
2 for n in (1, 2, 1))
Veremos algo de generadores en el captulo . e
Ejercicio .. Resolver los siguientes con a = [1, 2, 3].
a) Conjeturar el valor y longitud de cada uno de los siguientes, y
luego comprobar la conjetura con Python:
i) b = [2
*
x for x in a]
ii) c = [[x, x
**
2] for x in a]
iii) c = [(x, x
**
2) for x in a]
b) En general, las tuplas pueden crearse sin encerrarlas entre pa-
rntesis. Qu pasa si ponemos c = [x, x
**
2 for x in a]
en el apartado anterior? e
Ejercicio .. En el ejercicio . vimos que la variable x usada en
for no es local al for. En cambio, las variables dentro de la defnicin
por comprensin se comportan como variables locales.
Evaluar:
x = 0
to.z. Lsras por comprensn Pg. tty
a = [1, 2, 3]
b = [x + 1 for x in a]
x e
Ejercicio .. Hay muchas formas de encontrar la suma de los n
primeros impares positivos.
Una forma es generar la lista y luego sumarla:
impares = [2
*
k + 1 for k in range(n)]
sum(impares)
o directamente sum([2
*
k + 1 for k in range(n)]).
Python nos permite hacer esto en un nico paso, eliminando la
construccin de la lista:
sum(2
*
k + 1 for k in range(n))
En fn, podemos seguir las ideas de los acumuladores (que es lo
que hace en el fondo Python):
s = 0
for k in range(n):
s = s + 2
*
k + 1
s
a) Probar los tres esquemas anteriores, viendo que dan los mismos
resultados.
b) Calcular las sumas para n = , , , . Qu se observa? Conje-
turar una frmula para n general.
Ayuda: la suma tiene que ver con n

.
c) Podras demostrar la frmula? e
Ejercicio .. Comparar los valores de la funcin factorial(n)
(ejercicio .) con los de math.factorial(n) para n = , . . . , :
a) Construyendo dos listas y viendo si son iguales:
uno = [factorial(n) for n in range(1, 11)]
dos = [math.factorial(n) for n in range(1, 11)]
uno == dos
Pg. tto Cap|rulo to. Recorrendo sucesones
b) Usando un lazo for
t = True
for n in range(1, 11):
if factorial(n) != math.factorial(n):
t = False
break
t
La versin con listas parece ms clara pero es menos efciente,
tanto en el uso de la memoria (cuando n es grande) como en que
construimos las listas completas y luego las comparamos, siendo
que es posible que diferan para valores chicos y no valga la pena
construir las listas completas.
Ver tambin la discusin sobre acumuladores (pg. ). e
.. Filtros
Las listas por comprensin nos permiten fabricar listas a partir de
sucesiones, pero podramos tratar de construir una nueva lista slo
con los elementos que satisfacen cierta condicin, digamos p(x) (que
debe tener valores lgicos).
As, queremos una variante del esquema (.) de la forma:
lista = []
for x in iterable:
if p(x):
lista.append(f(x))
lista
(.)
Correspondientemente, el esquema en (.) se transforma en
[f(x) for x in iterable if p(x)] (.)
y se llama listas por comprension con fltros.
Por ejemplo,
[x for x in range(-5, 5) if x % 2 == 1]
to.. Plrros Pg. tt,
da una lista de todos los impares entre y (inclusivos), es decir,
[-5, -3, -1, 1, 3].
Mientras que [f(x) for x in lista] tiene la misma longitud
de lista, [f(x) for x in lista if p(x)] puede tener longi-
tud menor o inclusive ningn elemento.
Ejercicio .. Dando defniciones por comprensin con fltros, en-
contrar:
a) Los nmeros positivos en [1, -2, 3, -4].
b) Las palabras terminadas en o en
[Ana, Luisa, y, Mateo, Adolfo]
Ayuda: el ndice correspondiente al ltimo elemento de una
sucesin es . e
Ejercicio .. Usando fltros (en vez de un lazo for), dar una def-
nicin alternativa de la funcin posiciones del ejercicio ..
Comparar ambas versiones cuando a = mi mama me mima (sin
tildes) y x es:
a) m b) i c) a d) A e
Ejercicio .. Qu hace la funcin
def haceralgo(a, x):
return [y for y in a if y != x] ?
En el ejercicio ..b) estudiamos una versin usando lazos donde
la lista se modifca. Ver tambin el ejercicio ..d). e
Ejercicio .. Queremos defnir una funcin sublista(a, pos)
que da una lista de los elementos de la lista (o secuencia) a que estn
en las posiciones pos. Por ejemplo
>>> sublista([5, 3, 3, 4, 1, 3, 2, 5], [2, 4, 6, 4])
[3, 1, 2, 1]
Dar dos defniciones distintas de la funcin sublista, una usando
un lazo for y la otra usando fltros.
Pg. tt8 Cap|rulo to. Recorrendo sucesones
Si ponemos indices = posiciones(lista, x), cul ser el re-
sultado de sublista(lista, indices)? e
.. Ejercicios adicionales
En este captulo vimos cmo recorrer secuencias usando for o
fltros, pero en ocasiones es conveniente usar ndices y lazos while,
como muestran el siguiente ejemplo.
Ejercicio .. Python tiene el mtodo reverse que da vuelta una
lista modifcndola (ver el ejercicio .). Esta accin se puede hacer
efcientemente con un lazo while, tomando dos ndices que comienzan
en los extremos y se van juntando:
i, j = 0, len(a) - 1
while i < j:
# intercambiar
a[i], a[j] = a[j], a[i]
i, j = i + 1, j - 1
Defnir una funcin darvuelta siguiendo este esquema y probarla
con distintas listas. e
.. Comentarios
for tiene distintos signifcados dependiendo del lenguaje de pro-
gramacin y no siempre existe. En general, puede reemplazarse
por un lazo while adecuado.
En realidad, el esquema
i = 0
while i < n:
...
i = i + 1
es ligeramente ms efciente en Python que el correspondiente
lazo for:
to.y. Comenraros Pg. tt
for i in range(n):
...
Las estructuras de listas por comprensin y de fltro no estn
disponibles en lenguajes como Pascal o C. Claro que el esque-
ma (.) puede realizarse en estos lenguajes sin mayores pro-
blemas.
En lenguajes que tienen elementos de programacion funcional,
la estructura [f(x) for x in secuencia] muchas veces se lla-
ma map, mientras que la estructura [x for x in iterable if
p(x)] a veces se llama flter o select.
La estructura [f(x) for x in iterable if p(x)] genera-
liza map y select, y puede recuperarse a partir de ambas.
Python tiene las funciones map y filter con caractersticas
similares a las descriptas (ver help(map) o help(filter)). No
veremos estas estructuras en el curso, usando en cambio listas
por comprensin con fltros.
Los lenguajes declarativos como SQL (usado en bases de datos)
tienen fltros muy similares a los que vimos.

Captulo
Cuatro variaciones sobre un
tema
En este captulo estudiamos algunas aplicaciones sencillas que pa-
receran no estar relacionadas entre s, pero que desde las matemticas
pueden verse como variantes del mismo tema.
.. Reloj... no marques las horas
Las horas de la locura las mide el reloj, pero ningn
reloj puede medir las horas de la sabidura.
Proverbios del Inferno ()
William Blake ()
Supongamos que tenemos un tiempo expresado en horas, minu-
tos y segundos, por ejemplo, hs m . s y queremos pasarlo a
segundos.
En el ejercicio . hicimos algo parecido.
Una forma de resolver el problema es pasar horas a segundos,
tt.t. Reloj... no marques las horas Pg. tzt
minutos a segundos, y luego sumar todo:
hs = s = s
m = s = s
. s = . s
total = . s
(.)
Pero parece ms sencillo primero pasar horas a minutos y luego
minutos a segundos:
h = m = m,
m+ m = m,
m = s = s,
s + . s = . s,
que podramos poner en un nico rengln:
( + ) + . = .. (.)
En general, si tenemos a aos, d das, h horas, m minutos y s
segundos, para expresar todo en segundos pondramos (suponiendo
que todos los aos tienen das):
t = a
*
365 + d # das
t = t
*
24 + h # horas
t = t
*
60 + m # minutos
t = t
*
60 + s # segundos
(.)
Aunque no es estrictamente necesario, suponemos que
a, d, h y m son enteros, s puede ser decimal,
a, d , h , m , s < .
(.)
Si los datos estn en la lista tiempo = [a, d, h, m, s] y las
unidades de las conversiones en la lista c = [365, 24, 60, 60], po-
dramos poner:
Pg. tzz Cap|rulo tt. Cuarro varacones sobre un rema
n = len(tiempo) # len(c) es n - 1
t = tiempo[0]
for i in range(1, n):
t = t
*
c[i - 1] + tiempo[i]
t # tiempo pasado a segundos
(.)
Ejercicio .. Tomando como base el esquema (.), defnir una fun-
cin asegs(tiempo) para pasar el tiempo expresado en aos, das,
horas, minutos y segundos a segundos
Aclaracion: suponemos tiempo de la forma [a, d, h, m, s].
Comprobar los resultados cuando los argumentos son:
a) [0, 0, 12, 34, 56.78]
b) [5, 67, 8, 9, 12.34] e
Consideremos ahora el problema inverso: tenemos un tiempo ex-
presado en segundos y queremos pasarlo a aos, das, horas, minutos
y segundos, bajo las restricciones (.).
Recorriendo de abajo hacia arriba el esquema (.), si t es el tiempo
expresado en segundos y lo dividimos por , el cociente es el tiempo
expresado en minutos y el resto son los segundos. Quedara:
s, m = t % 60, t // 60 # segundos y minutos
m, h = m % 60, m // 60 # minutos y horas
h, d = h % 24, h // 24 # horas y das
d, a = d % 365, d // 365 # das y aos
Este esquema tiene el problema de que si t no es entero, tampoco
lo sern t % 60 y t // 60:
>>> 45296.78 % 60, 45296.78 // 60
(56.779999999998836, 754.0)
lo que contradice la suposicin (.).
Como slo los segundos pueden ser decimales, podramos separar
la parte entera de la decimal, y despus seguir trabajando slo con
enteros.
tt.z. Algo de maremrca fnancera Pg. tz
Recordando que el tiempo fnal ser una lista de longitud y la
completaremos desde atrs hacia adelante, si la entrada es t y c =
[365, 24, 60, 60], podemos poner:
n = int(t) # parte entera
f = t - n # parte fraccionaria
tiempo = [0 for i in range(5)]
for i in range(4, -1, -1):
n, tiempo[i] = divmod(n, c[i - 1])
tiempo[-1] = tiempo[-1] + f
tiempo
(.)
Observar cmo el lazo for aqu es el inverso del lazo for en el
esquema (.).
Ejercicio .. Tomando como base el esquema (.), defnir una fun-
cin desegs(tiempo) que dado un nmero no negativo de segundos
lo convierte a aos, das, horas, minutos y segundos respetando las
condiciones (.).
Comprobar que desegs es efectivamente la inversa de asegs, to-
mando como entrada los resultados del ejercicio .. e
.. Algo de matemtica fnanciera
En esta seccin estudiamos una de las tantas herramientas matem-
ticas usadas en las fnanzas, viendo cmo se va actualizando el capital
cuando sometido a inters compuesto.
Empecemos con cosas sencillas.
Ejercicio ..
a) Si la infacin el primer ao fue del %, y el segundo ao fue
del %, cunto cuesta ahora un artculo que dos aos atrs
costaba ?
Aclaracion: hablamos de un artculo genrico, seguramente
habr artculos que aumentaron ms y otros menos que la
Pg. tz{ Cap|rulo tt. Cuarro varacones sobre un rema
infacin indicada.
b) El kilo de pan hoy me cuesta y (exactamente) dos aos
atrs me costaba .. Qu estimacin podramos dar sobre
la infacin promedio en cada uno de estos dos aos? e
Supongamos que hacemos un certifcado a plazo fjo depositando
un capital inicial d

, con una tasa de inters de r

% nominal anual con


capitalizacin mensual.
Al fn del primer mes nuestro capital se ve incrementado por el
inters que es proporcional al capital inicial,
interes = d

tasa mensual.
Para calcular la tasa mensual, usamos que r

es la tasa nominal
anual expresada como porcentaje y que el ao se ha dividido en
perodos, por lo que en un mes la tasa de inters es r

( ), y el
inters es
d


.
Una vez computados los intereses, nuestro capital al vencimiento
del primer perodo ser
v

= capital inicial + interes = d

_ +
r


_ = d

,
donde
t

= +
r


.
Teniendo la opcin de renovar el certifcado, supongamos que
agregamos una cantidad d

(que ser negativa si extraemos en vez de


depositar), es decir, el monto inicial para el prximo certifcado ser
c

= v

+ d

.
Continuando de esta forma, vemos que si
c
n
es el monto al principio del mes n,
tt.z. Algo de maremrca fnancera Pg. tzy
r
n
es la tasa (nominal anual en porcentaje) correspondiente,
t
n
= +
r
n

,
v
n
es el monto al vencer el n-simo certifcado,
d
n
es lo que agregamos para el certifcado en el mes n + ,
entonces para n = , , . . . :
c
n
= v
n
+ d
n
, v
n
= c
n
t
n
. (.a)
Por otro lado, para n = tenemos
c

= d

. (.b)
Por ejemplo, al fnal del tercer perodo el capital ser:
v

= c

= (v

+ d

) t

= (c

+ d

) t

= ((v

+ d

) t

+ d

) t

= ((d

+ d

) t

+ d

) t

,
(.)
que es bien parecida a (.).
Las ecuaciones (.) nos llevan a imitar lo hecho en el esque-
ma (.):
c = d[0] # capital inicial = depsito inicial
for i in range(1, n+1):
t = 1 + r[i - 1] / 1200
v = c
*
t # monto al vencimiento
c = v + d[i] # nuevo capital
(.)
donde
r = [r[0], r[1],...] son las tasas de inters (nominal, anual,
en porciento), y
d = [d[0], d[1],...] son los depsitos mensuales.
Ejercicio .. Tomando como base el esquema (.), defnir una fun-
cin vencimiento(n, d, r) que determine el monto del certifcado
al vencimiento del mes n, antes de hacer el depsito (o extraccin)
correspondiente a ese mes. e
Pg. tzo Cap|rulo tt. Cuarro varacones sobre un rema
Ejercicio .. Al menos para perodos cortos, en muchas ocasiones
podemos considerar que tanto la tasa de inters como los depsitos/ex-
tracciones mensuales permanecen fjos.
Modifcando adecuadamente la funcin del ejercicio ., defnir
una funcin queda(n, c, r, d) para determinar el monto al venci-
miento despus de n perodos, donde c es el capital inicial, r es la tasa
de inters (fja), y d es el monto (fjo) de los n depsitos que hicimos
(despus del inicial c).
Aclaracion: c, r y d son nmeros (que pueden ser decimales). e
Ejercicio .. El banco de Gabi ofrece una tasa de % nominal anual
en certifcados a dos meses, permitiendo una renovacin automtica
con la misma tasa.
a) Si Gabi hace un certifcado por con renovacin autom-
tica, cunto dinero puede retirar al cabo de un ao (o sea al
vencimiento del sexto certifcado)?
Aclaracion: suponemos que no hay otros gastos como estam-
pillados o impuestos.
b) Si como en el apartado anterior, Gabi retira en cada ven-
cimiento, con tasa constante, cunto dinero queda al fnal de
los perodos (antes de retirar los )?
c) Y si deposita (en vez de retirar) mensuales (y de esta
forma aumenta el capital). e
.. Polinomios
Los polinomios son expresiones de la forma
P(x) =
n

k=
a
i
x
i
= a

+ a

x + + a
n
x
n
= a
n
x
n
+ a
n
x
n
+ + a

,
(.)
y son las funciones ms sencillas que podemos considerar: para su
clculo slo se necesitan sumas y productos (y no tenemos que hacer
tt.. Polnomos Pg. tz,
aproximaciones como para el seno o el logaritmo).
Adems los usamos diariamente: un nmero en base es en reali-
dad un polinomio evaluado en ,
=

+ + .
Nuestra primera tarea ser evaluar un polinomio dado.
Ejercicio . (regla de Horner). Construir una funcin que dada una
lista de coefcientes (reales) (a

, a

, a

, . . . , a
n
) y un nmero x R,
evale el polinomio P(x) en la ecuacin (.).
Hacerlo de tres formas:
a) Calculando la suma de trminos como se indica en la ecua-
cin (.), calculando x
k
para cada k.
Corresponde al esquema (.).
b) Como el anterior, pero las potencias en la forma x
k+
= x
k
x,
guardando x
k
en cada paso.
c) Usando la regla de Horner,
((((a
n
x + a
n
)x + a
n
) + )x + a

)x + a

. (.)
Es la versin correspondiente a la ecuacin (.) para el caso
del tiempo, y a (.) para el caso del certifcado, suponiendo
que los depsitos son constantes.
Observar que primero se multiplica por a
n
, luego por a
n
,
etc., es decir, recorremos la lista al revs de lo que hacemos
en las ecuaciones mencionadas. e
En las dos primeras versiones del ejercicio . se hacen n sumas,
n productos y se calculan n potencias, que en la primera versin
representanotros ++ +(n) = n(n) productos, mientras que
en la segunda los productos provenientes de las potencias se reducen a
n .
En cambio, en la regla de Horner tenemos slo n sumas y n pro-
ductos, y es mucho ms efciente que las dos primeras versiones.
Pg. tz8 Cap|rulo tt. Cuarro varacones sobre un rema
Es por eso que para pasar de horas, minutos y segundos a segundos,
intuitivamente elegimos usar la ecuacin (.) antes que el procedi-
miento del esquema (.).
En la mayora de los casos es preferible usar la
regla de Horner para evaluar polinomios, y solo
en algunos pocos casos particulares debe usarse
explcitamente potenciacion.
h
.. Escritura en base entera
Ejercicio .. Dado una base b entera, b > , y un entero n N, nos
gustara encontrar coefcientes a

, a

, . . . , a
k
de modo que
n =
k

i=
a
i
b
i
, donde a
i
Z y a
i
< b. (.)
Siguiendo las ideas de la regla de Horner (ver la ecuacin (.)),
ponemos
n =
k

i=
a
i
b
i
= a
k
b
k
+ a
k
b
k
+ + a

b + a

= (a
k
b
k
+ a
k
b
k
+ + a

) b + a

= (((a
k
b
k
+ a
k
b
k
+ + a

) b + a

= ((((a
k
b + a
n
) b + a
k
) + ) b + a

) b + a

.
A partir de estas expresiones, vemos que a

se obtiene como resto


de la divisin de n por b, por lo que b (n a

), y (n a

)b es un
entero que tiene resto a

cuando dividido por b, etc.


tt.y. Ejerccos adconales Pg. tz
Comparar con el esquema (.). Tambin usamos este proceso
en el ejercicio ..
a) Defnir una funcin que dados n y b encuentre los coefcientes
(a

, a

, . . . , a
k
) de la expresin (.), con a
k
. Por ejemplo,
si n = 10 y b = 2, se debe obtener [0, 1, 0, 1].
Como el ltimo coefciente debe ser no nulo (pedimos n > ),
la longitud de la lista obtenida debe ser la cantidad de cifras
de n cuando expresado en base b.
b) Defnir una funcin que dados n y b exprese a n en base b
como cadena de caracteres. Por ejemplo, si n = 10 y b = 2 se
debe obtener 1010.
c) Usando la regla de Horner, defnir una funcin para obtener el
nmero n (entero positivo) escrito en base , dada su repre-
sentacin como cadena de dgitos en la base b. Por ejemplo, si
la cadena es 1010 y b = 2 se debe obtener 10.
En Python podemos poner int(cadena, b) donde la base b
debe ser un entero tal que b , y cadena es del tipo str
con dgitos segn la base b. Si b se omite se supone que es .
d) En la ecuacin (.), cmo se relacionan k y log
b
n (si a
k

)?
Recordar tambin el ejercicio .. e
.. Ejercicios adicionales
Ejercicio . (Potencias binarias). Otra variante de la idea de la regla
de Horner es el clculo de una potencia pura. Si x R y n N,
podemos calcular x
n
escribiendo n en base :
n =
k

i=
a
i

i
,
Pg. to Cap|rulo tt. Cuarro varacones sobre un rema
y hacer
x
n
= x
a

+a

++
k
a
k
+
k
a
k
=
= x
a

(x

)
a

(x

)
a

(x

k
)
a
k
(x

k
)
a
k
.
Observando que las potencias de x son x, x

, x

,... , llegamos a un
esquema como:
pot = x # x, x
**
2, x
**
4, ...
prod = 1 # el producto a retornar
while True:
if n % 2 == 1: # coeficiente no nulo
prod = prod
*
pot
n = n // 2
if n > 0:
pot = pot
*
pot # x
**
k -> x
**
(2
*
k)
else:
break
return prod
a) Defnir una funcin para el clculo de potencias puras con
estas ideas.
b) Hacer una funcin para calcular x
n
usando un lazo for.
c) Comparando las funciones defnidas en los apartados anterio-
res: cuntas operaciones aritmticas (productos y divisiones)
se realizan en cada caso?
d) Calcular

de tres formas: usando x


**
n, y con la funcin
defnidas en los dos primeros apartados.
k Debido a su alta efciencia, una tecnica similar se usa para encriptar
mensajes usando numeros primos de varias decenas de cifras. e

Captulo
Formatos y archivos de texto
En esta captulo vemos distintas formas de imprimir secuencias
usando for y variantes de print, y cmo guardar informacin en
archivos y luego recuperarla.
Como en otros casos, las sentencias que vemos son particulares a
Python pero tienen su correlato en otros lenguajes.
.. Formatos
Empezamos estudiando cmo imprimir secuencias en forma pro-
lija, especialmente cuando se trata de encolumnar la informacin en
tablas. Por supuesto que la presentacin puede ser mejorada enorme-
mente con otro tipo de aplicaciones como los procesadores de texto
o las de diseo de pgina. Como adems no hay mucha matemtica
involucrada, lo que vemos en esta seccin no forma parte esencial del
curso, si bien ser til muchas veces.
Ejercicio . (opciones de print). Pongamos a = Mateo Adolfo
en la terminal.
a) Ver el resultado de
for x in a:
Pg. tz Cap|rulo tz. Pormaros y archvos de rexro
print(x)
b) print admite un argumento opcional de la forma end=algo.
Por defecto, omitir esta opcines equivalente a poner end=\n,
iniciando un nuevo rengln despus de cada instruccin print.
Poner
for x in a:
print(x, end=)
viendo el resultado.
c) En algunos casos la impresin se junta con >>>, en cuyo caso
se puede agregar una instruccin fnal print(). Mejor an
es poner (en un mdulo que se ejecutar):
for x in a[:-1]:
print(x, end=)
print(a[-1]) e
Ejercicio . (construccin de tablas). Muchas veces queremos la
informacin volcada en tablas.
a) Un ejemplo sencillo sera construir los cuadrados de los prime-
ros nmeros naturales. Podramos intentar poniendo (en un
mdulo que se ejecutar)
for n in range(1, 11):
print(n, n
**
2)
Probar este bloque, viendo cules son los inconvenientes.
b) Uno de los problemas es que nos gustara tener alineados los
valores, y tal vez ms espaciados. Se puede mejorar este aspecto
con formatos para la impresin. Python tiene distintos meca-
nismos para formatear
()
y en el curso nos restringiremos al
mtodo format usando llaves ( { y } ).
Veamos cmo funciona con un ejemplo:
()
S, es una palabra permitida por la RAE.
tz.t. Pormaros Pg. t
for n in range(1, 11):
print({0:2d} {1:4d}.format(n, n
**
2))
El primer juego de llaves tiene dos entradas separadas por
: . La primera entrada, 0, corresponde al ndice de la primera
entrada despus de format. La segunda entrada del primer
juego de llaves es 2d, que signifca que vamos a escribir un
entero con dgitos (d) y se alinean a derecha porque son
nmeros.
El segundo juego de llaves es similar.
i) Observar tambin que dejamos un espacio entre los dos
juegos de llaves: modifcarlos a ningn espacio o varios
para ver el comportamiento.
ii) Ver el efecto de cambiar, por ejemplo, {1:4d} a {1:10d}.
iii) Cambiar el orden poniendo {1:4d} {0:2d}, y ver el
comportamiento.
iv) Poner ahora
for n in range(1, 11):
print({0:2d} {0:4d}.format(n, n
**
2))
y comprobar que el segundo argumento (n
**
2) se ignora.
c) Las cadenas de caracteres usan la especifcacin s (por string),
que se supone por defecto:
print({0} {0:s} {0:20s} {0}.format(
Mateo Adolfo))
A diferencia de los nmeros que se alinean a la derecha, las
cadenas se alinean a la izquierda, pero es posible modifcar la
alineacin con > y . Por ejemplo
print(-{0:20}-{1:^20}-{2:>20}-.format(
izquierda, centro, derecha))
Tambin se puede especifcar < para alinear a la izquierda,
pero en cadenas es redundante.
d) Cuando trabajamos con decimales, las cosas se ponen un tanto
Pg. t{ Cap|rulo tz. Pormaros y archvos de rexro
ms complicadas. Un formato razonable es el tipo g, que agre-
ga una potencia de con e si el nmero es bastante grande
o bastante chico, pudiendo adecuar la cantidad de espacios
ocupados despus del : y la cantidad cifras signifcativas
despus del . :
a = 1234.5678901234
print({0} {0:g} {0:15g} {0:15.8g}.format(a))
print({0} {0:g} {0:15g} {0:15.8g}.format(1/a))
a = 1234567890.98765
print({0} {0:g} {0:15g} {0:15.8g}.format(a))
print({0} {0:g} {0:15g} {0:15.8g}.format(1/a))
e) Si queremos hacer una tabla del seno donde la primera columna
sean los ngulos entre

en incrementos de podramos
poner:
import math
aradianes = math.pi/180
for grados in range(0, 46, 5):
print({0:6} {1:<15g}.format(
grados, math.sin(grados
*
aradianes)))
Probar estas instrucciones y agregar un encabezado con las
palabras grados y seno centradas en las columnas corres-
pondientes. e
Nosotros no veremos ms posibilidades de formatos. Las especif-
caciones completas de todos los formatos disponibles estn en el
manual de la biblioteca de Python (String Services).
Ejercicio .. Las instrucciones siguientes construyen la tabla de ver-
dad para la conjuncin (y lgico):
formato = {0:^5s} {1:^5s} {2:^5s}
print(formato.format(p, q, p y q))
print(19
*
-)
for p in [False, True]:
for q in [False, True]:
tz.z. Archvos de rexro Pg. ty
print(formato.format(
str(p), str(q), str(p and q)))
a) Modifcarlas para obtener la tabla de verdad para la disyuncin
(el o lgico).
b) Modifcarlas para que aparezcan las cuatro columnas p, q, pq,
p q. e
Ejercicio .. Repetir el ejercicio . usando formatos. e
.. Archivos de texto
Cuando se genera mucha informacin, como en las tablas, en
general no queremos imprimirla en pantalla sino guardarla en un
archivo en el disco de la computadora para su uso posterior, tal vez en
otra computadora.
Para nosotros ser conveniente que el archivo sea de texto, de modo
de poder leerlo con un editor de textos como IDLE.
En general, los archivos de texto se guardan con extensin .txt,
pero podran tener cualquier otra como .dat o .sal, o ninguna (en
MS-Windows la cosa puede ser distinta...).
Otra alternativa es que el archivo sea binario (en vez de texto). Los
programas ejecutables (muchas veces con terminacin .exe) son
ejemplos de archivos binarios. Cuando estos archivos se abren
con un editor de texto, aparecen garabatos.
Tenemos dos tareas: escribir en archivos de texto para guardar la
informacin y leer esos archivos para recuperarla. Empecemos por la
escritura.
Al escribir el programa, tenemos que relacionar el nombre del
archivo en el disco de la computadora, llammoslo externo, con un
nombre que le daremos en el programa, llammoslo interno.
Esto es parecido a lo que hicimos en el mdulo holapepe (ejerci-
cio .): pepe es el nombre interno y el nombre externo puede ser Ana
Luisa, Mateo Adolfo o cualquier otro.
Pg. to Cap|rulo tz. Pormaros y archvos de rexro
Ejercicio . (guardando en archivo). El mdulo tablaseno guarda
una tabla del seno, la primera columna en grados y la segunda con el
valor correspondiente del seno como hicimos en el ejercicio ..e).
Observamos las siguientes novedades:
La variable archivo es el nombre interno (dentro del mdulo)
que se relaciona con el nombre externo tablaseno.txt mediante
la instruccin open (abrir en ingls).
El archivo tablaseno.txt se guardar en el directorio de trabajo.
Recordar el ejercicio . y las notas all.
open lleva como segundo argumento w (por write, escribir),
indicando que vamos a escribir el archivo.
Hay que tener cuidado pues si existe un archivo
con el mismo nombre (y en el mismo directorio)
este sera reemplazado por el nuevo.

Hay formas de verifcar si el archivo ya existe y en ese caso no


borrarlo, pero no las veremos en el curso.
El tercer argumento de open es la codifcacin (encoding) ne-
cesaria para leer correctamente el archivo cuando hayamos ter-
minado. En nuestro caso ponemos la codifcacin utf- con
encoding=utf-8.
Es posible que la codifcacin por defecto sea utf- (y no sea
necesario explicitarla) pero esto depende de la confguracin
del sistema operativo: ms vale prevenir...
En el lazo for reemplazamos print por archivo.write, y en
el texto a imprimir agregamos al fnal \n, que no ponamos con
print.
Todo termina cerrando (close en ingls) el archivo que abrimos
con open, con la instruccin archivo.close().
tz.z. Archvos de rexro Pg. t,
a) Ejecutar el mdulo tablaseno, y abrir el archivo tablaseno.txt
con un editor de texto (por ejemplo, el mismo IDLE) para
verifcar sus contenidos.
b) Qu pasa si se elimina \n en el argumento de archivo.write?
c) Cambiar en todos los casos archivo por salida y verifcar el
comportamiento.
d) Cambiar el nombre tablaseno.txt por tabla.sal y estudiar las
diferencias.
e) Cambiar el mdulo de modo de preguntar interactivamente el
nombre del archivo a escribir.
Ayuda: recordar input (ejercicio .). e
Ejercicio . (lectura de archivos de texto). santosvega.txt es un
archivo de texto codifcado en utf- con los primeros versos del poema
Santos Vega de Rafael Obligado.
Nuestro objetivo es que Python lea el archivo y lo imprima en la
terminal de IDLE.
Es conveniente tener una copia del archivo en el mismo directo-
rio/carpeta donde estn nuestros mdulos Python.
a) Ubicndonos con IDLE en el directorio donde est el archivo
santosvega.txt, ponemos en terminal:
archivo = open(santosvega.txt, r,
encoding=utf-8)
Similar al caso de escritura, esta instruccin indica a Python
que en lo que sigue estamos asociando la variable archivo, que
es interna a Python, con el nombre santosvega.txt, que es el
nombre del archivo en el disco de la computadora.
El segundo argumento en open es ahora r (por read, leer),
indicando que vamos a leer el archivo.
No es necesario poner r pues se supone por defecto.
Para no complicarla, lo incluimos.
Pg. t8 Cap|rulo tz. Pormaros y archvos de rexro
Como en el caso de escritura, el tercer argumento de open
es la codifcacin (encoding).
b) Averiguar el valor y el tipo de archivo.
c) Para leer efectivamente los contenidos, ponemos
archivo.read()
que nos mostrar el texto del archivo en una nica cadena,
incluyendo caracteres como \n, indicando el fn de rengln, y
eventualmente algunos como \t, indicando tabulacin (no en
este caso).
El metodo read pone todos los contenidos del archivo de
texto en una unica cadena de caracteres.
d) Volver a repetir la instruccin archivo.read(), viendo que
ahora se imprime slo (la cadena vaca).
Se pueden dar instrucciones para ir al principio del archivo
(o a cualquier otra posicin) sin volver a abrirlo, pero no lo
veremos en el curso.
e) En este ejemplo no hay mucho problema en leer el rengln
impreso mediante archivo.read() porque se trata de un tex-
to relativamente corto. En textos ms largos es conveniente
imprimir (o lo que sea que queramos hacer) cada rengln se-
paradamente, lo que podemos hacer poniendo
archivo = open(santosvega.txt, r,
encoding=utf-8)
for renglon in archivo:
print(renglon)
Es conveniente cerrar (close) antes de volver a abrir (open)
el archivo.
El mtodo readline tambin nos permite leer un rengln:
archivo.readline(). Nosotros no lo veremos.
f ) El resultado del apartado anterior es que se deja otro rengln
en blanco despus de cada rengln. Podemos usar la tcnica
tz.z. Archvos de rexro Pg. t
del ejercicio . poniendo
archivo = open(santosvega.txt, r,
encoding=utf-8)
for renglon in archivo:
print(renglon, end=)
Comprobar el resultado de estas instrucciones.
g) A pesar del lazo for en el apartado e), archivo no es una
sucesin de Python. Probarlo poniendo
archivo = open(santosvega.txt, r,
encoding=utf-8)
archivo[0]
len(archivo)
No es una sucesin pero es un iterable, como lo son las suce-
siones. Veremos algo ms sobre el tema en el ejercicio ..
h) Hacer que Python cuente la cantidad de renglones (incluyendo
renglones en blanco), usando algo como
nrenglones = 0
for renglon in archivo:
nrenglones = nrenglones + 1
print(El archivo tiene, nrenglones,
renglones)
Es la misma construccin del ejercicio ..b).
i) Cuando el archivo no se va a usar ms, es conveniente liberar
los recursos del sistema, cerrando el archivo, como hicimos en
el ejercicio ..
Poner
archivo = open(santosvega.txt, r,
encoding=utf-8)
archivo.close()
archivo.read()
Pg. t{o Cap|rulo tz. Pormaros y archvos de rexro
viendo que la ltima instruccin da error.
j) En el mdulo dearchivoaconsola hacemos una sntesis de lo
que vimos: preguntamos por el nombre del archivo de texto a
imprimir en la consola, abrimos el archivo, lo imprimimos y
fnalmente lo cerramos.
Probarlo ingresando los nombres santosvega.txt y dearchi-
voaconsola.py. e
Ejercicio .. Tomando partes de los mdulos tablaseno y dearchi-
voaconsola, construir una funcin copiar(entrada, salida) que
copie el contenido del archivo de nombre entrada en el de nombre
salida (ambos archivos en el disco de la computadora). e
Abriendo el archivo tablaseno.txt con IDLE vemos el formato de
la tabla: cada rengln tiene dos nmeros y varios espacios ( ). Para
recuperar los nmeros debemos eliminar los espacios, lo que podemos
hacer con el mtodo split para cadenas de caracteres.
Ejercicio . (split).
a) Ver qu hace el mtodo split poniendo help(str.split).
b) Ver el resultado de:
a = mi mam me... mima!
a
a.split()
donde en a ponemos arbitrariamente espacios entremedio.
c) Como el anterior, poniendo
a = mi\nmama me\nmima
Ver tambin el resultado de print(a), observando las dife-
rencias.
d) Qu resultado da .split() (sin espacios)?, y con uno o
ms espacios como .split()? e
Ejercicio .. Usando split, imprimir una por rengln las pa-
labras con o ms letras en el archivo santosvega.txt. e
tz.z. Archvos de rexro Pg. t{t
Ejercicio . (leyendo tablas). En el ejercicio . vimos que cuando
se ingresan datos con input, Python los interpreta como cadenas de
caracteres y debemos pasarlos a otro tipo si es necesario. Algo similar
sucede cuando se lee un archivo de texto.
a) Ubicndose en el directorio correspondiente, en la terminal
poner
archivo = open(tablaseno.txt, r,
encoding=utf-8)
donde tablaseno.txt es el archivo construido en el ejercicio ..
b) Usando for para construir una lista por comprensin(enforma
similar al ejercicio ..e)), ver el resultado de las siguientes
instrucciones:
a = [x for x in archivo]
a
a[0]
a[0].split()
c) Teniendo una idea del comportamiento, podemos fabricar una
lista con los nmeros asociados a la tabla:
b = []
for x in a:
g, s = x.split()
b.append([int(g), float(s)])
b
d) Con el esquema anterior construimos dos listas: a y b. Modif-
carlo de modo de construir la lista b directamente, sin construir
a.
Ayuda: eliminar la construccin de la lista por comprensin
usando un lazo for para recorrer los renglones.
Ser conveniente primero cerrar el archivo y luego volver a
abrirlo. e
Pg. t{z Cap|rulo tz. Pormaros y archvos de rexro
.. Ejercicios adicionales
Ejercicio .. La posibilidad de leer y escribir archivos con Python
nos brinda una interfaz bastante elemental para comunicarnos
con otro sofware.
Por ejemplo, MS-Excel y planillas de clculo similares tambin
tienen la posibilidad de leer y escribir archivos de texto, y en este
ejercicio trataremos de intercambiar datos entre ellos y Python.
a) En una planilla de clculo crear una tabla del seno: la columna
de la izquierda representando grados entre

en incre-
mentos de

y en la columna de la derecha el seno del ngulo


correspondiente.
Guardar la planilla como archivo de texto delimitado por
tabulaciones.
b) De modo similar, construir una planilla de tres columnas y
cuatro flas, donde la primer columna represente apellidos, la
segunda nombres y la tercera edades. Guardar tambin esta
planilla como archivo de texto delimitado por tabulaciones.
c) Modifcando adecuadamente el mdulo dearchivoaconsola,
construir una funcin en Python para leer archivos de texto e
imprimirlos, y luego probarla con los archivos construidos en
los apartados anteriores.
Si los nombres o apellidos tienen tildes, como en Mara Sn-
chez, pueden haber problemas en la lectura.
En estos casos tenemos las opciones de guardar el archivo
de texto desde MS-Excel o similar con la codifcacin utf-,
o bien abrir el archivo con Python usando la codifcacin
apropiada, por ejemplo, poniendo encoding = latin
_
1.
d) Modifcar la funcin del apartado anterior para construir una
lista de Python: las flas sern las flas de la planilla y las entradas
las columnas correspondientes, donde las tabulaciones \t
se reemplazan por separaciones de lista , con split.
Comprobar el funcionamiento usando los archivos construi-
tz.. Ejerccos adconales Pg. t{
dos en a) y b).
e) Defnir una nueva funcin, variante de la del apartado anterior,
para pasar de cadena de caracteres a nmero cada entrada de
la lista (matriz) resultante. Verifcar el resultado leyendo el
archivo construido en a).
f ) Recprocamente, modifcando el mdulo tablaseno, construir
un archivo de texto con la tabla del coseno para ngulos entre

en incrementos de

y luego abrirlo con MS-Excel


(o similar):
separando grados y los senos con tabulaciones (\t),
cada fla con nuevo rengln \n.
Ayuda: usar {0}\t{1}\n.format(...).
Valen las observaciones hechas en c). e

Parte II
Popurr|
Captulo
Nmeros aleatorios
Cualquiera que considere mtodos aritmticos
para producir dgitos aleatorios est, por supuesto,
en estado de pecado.
John von Neumann ()
Muchas veces se piensa que en matemtica las respuestas son
siempre exactas, olvidando que las probabilidades forman parte de
ella y que son muchas las aplicaciones de esta rama.
Una de estas aplicaciones es la simulacin, tcnica muy usada por
fsicos, ingenieros y economistas cuando es difcil llegar a una frmula
que describa el sistema o proceso. As, simulacin es usada para cosas
tan diversas como el estudio de las colisiones de partculas en fsica
nuclear y el estudio de cuntos cajeros poner en el supermercado para
que el tiempo de espera de los clientes en las colas no sea excesivo. La
simulacin mediante el uso de la computadora es tan difundida que
hay lenguajes de programacin (en vez de Python o C) especialmente
destinados a este propsito.
Cuando en la simulacin interviene el azar o la probabilidad, se
usan nmeros generados por la computadora que reciben el nombre
de aleatorios, o ms correctamente, seudo-aleatorios, porque hay un
Pg. t{o Cap|rulo t. Nmeros alearoros
algoritmo determinstico que los construye.
En este captulo miramos propiedades de estos nmeros y algunas
de las facilidades que ofrece Python para su uso.
.. Funciones de nmeros aleatorios en Python
Como en el caso de funciones matemticas como seno o logarit-
mo para las que usamos el mdulo math, para trabajar con nmeros
aleatorios en Python usamos el mdulo random (aleatorio en ingls).
Ejercicio .. Veamos ejemplos de las funciones en random que nos
interesan.
Hay muchas ms que no veremos: usar help(random).
Por supuesto, arrancamos con
import random
a) random.random es la funcin bsica en random. Genera un
decimal (float) aleatoria y uniformemente en el intervalo
|, ).
random.random()
random.random()
b) En general, los nmeros aleatorios se obtienen a partir de un
valor inicial o semilla (seed en ingls). Un mtodo efcaz para
obtener distintos sucesiones de nmeros aleatorios es cambiar
la semilla de acuerdo a la hora que indica el reloj de la compu-
tadora, lo que hace Python automticamente.
Para obtener los mismos nmeros siempre, podemos usar la
misma semilla con random.seed.
random.seed(0)
random.random()
random.random()
random.seed(0)
t.t. Puncones de nmeros alearoros en Pyrhon Pg. t{,
random.random()
c) Enmuchos casos nos interesa trabajar conunrango de nmeros
enteros (no decimales). random.randint es especialmente til,
dando un entero entre los argumentos (inclusivos).
random.randint(-10, 10)
[random.randint(-2, 3) for i in range(20)]
Python tiene otra funcin similar, random.randrange, que
no veremos en el curso para no confundir.
d) random.choice nos permite elegir un elemento de una suce-
sin no vaca.
random.choice(range(5)) # = random.randint(0, 4)
random.choice(mi mama me mima)
random.choice([2, 3, 5, 7, 11, 13, 17])
e) Si queremos elegir varios elementos aleatoriamente, lo que se
llama una muestra aleatoria, podemos usar random.sample.
a = [2, 3, 5, 7, 11, 13, 17]
random.sample(a, 4)
a # no cambia
random.sample(mi mama, 3)
random.sample((1, 5, 8, -1), 2)
random.sample(range(10), 4)
random.sample(range(10), 20) # da error
random.sample([1 for i in range(20)], 5)
f ) random.shuffle genera una permutacin aleatoria in situ
de una lista.
a = [2, 3, 5, 7, 11, 13, 17]
random.shuffle(a)
a
random.shuffle(a)
a
random.shuffle(mi mama) # da error
Pg. t{8 Cap|rulo t. Nmeros alearoros
random.shuffle((1, 5, 8)) # da error
g) Cmo podra obtenerse una permutacin aleatoria de los ca-
racteres en mi mama me mima?
Sugerencia: una posibilidad es combinar random.shuffle,
la funcin sublista del ejercicio . y la funcin sumar del
ejercicio ., pero hay muchas otras posibilidades. e
Ejercicio .. Es posible usar slo unas pocas funciones del mdulo
random y emular con ellas el resto. Veamos algunos ejemplos.
a) Construir una funcin mirandint(a, b) (donde a y b son
enteros) para emular el comportamiento de random.randint
usando slo la funcin random.random.
Sugerencia: cuando a = y b = n , mirandint(0, n-1)
podra defnirse como int(random.random()
*
n), y en gene-
ral podramos poner a + int(random.random()
*
n) donde
n = b a + .
b) Usando mirandint o random.randint, construir una funcin
michoice(s) (donde s es una sucesin) para emular el com-
portamiento de random.choice.
Es bastante ms complicado emular el comportamiento de las
funciones random.shuffle y random.sample. e
.. Qu son los nmeros aleatorios?
Aunque no es nuestra intencin hacer una descripcin rigurosa
de qu son o cmo se obtienen (lo que nos llevara un curso o dos),
miremos un poco ms las propiedades de los nmeros aleatorios.
De alguna forma, no tiene sentido hablar de un nmero aleatorio:
es un nmero aleatorio?
Ms bien, uno piensa en una sucesin de nmeros con ciertas
propiedades, fundamentalmente la de independencia, o sea que el valor
del n-simo nmero no depende de los n valores anteriores (ni de
t.z. Qu son los nmeros alearoros? Pg. t{
los posteriores), y la de distribucion, es decir, cmo se van repartiendo
o distribuyendo los valores.
Para ilustrar estas propiedades, fabriquemos una lista de n =
(o o ) nmeros aleatorios:
import random
n = 200 # o 100 o 1000
lista = [random.random() for i in range(n)]
Dado que no nos interesa mirar uno por uno a los nmeros sino
tener una idea global, vamos a mirar a la lista de nmeros como puntos
en el plano, poniendo como primera coordenada al ndice y como
segunda al nmero original.
Como vamos a hacer varios grfcos, defnimos una funcin:
def pts2d(lista):
"""Pasar nmeros a puntos del plano."""
return [(i, lista[i]) for i in range(len(lista))]
Hacemos el grfco usando el mdulo gracar, obteniendo algo
similar a la fgura .:
import graficar
graficar.puntos(pts2d(lista))
graficar.titulo = str(n) + nmeros aleatorios
graficar.mostrar()
Como vemos en el grfco, los valores estn completamente despa-
rramados, no habiendo un patrn claro de que haya alguna relacin
entre ellos.
Para obtener algn orden, vamos a clasifcar los puntos usando
sort (que modifca la lista, de modo que trabajamos sobre una copia).
clasif = lista[:] # copiar lista para no cambiarla
clasif.sort() # ordenar la nueva lista
graficar.reinicializar() # borrar objetos grficos
graficar.puntos(pts2d(clasif))
graficar.titulo = Los nmeros clasificados
graficar.mostrar()
Pg. tyo Cap|rulo t. Nmeros alearoros
x
0.00 49.75 99.50 149.25 199.00
y
0.01
0.50
0.99
200 nmeros aleatorios
Figura .: nmeros aleatorios entre y representados en el
plano.
En vez de copiar la lista en clasif y luego ordenarla, podramos
haber puesto directamente clasif = sorted(lista), como ve-
remos en el ejercicio ..
No es demasiado importante usar la misma lista en todos los pasos
que vamos haciendo, pero por coherencia la preservamos, lo que
podemos hacer de dos formas: o bien generando siempre la misma
lista usando una nica semilla en random.seed, o bien usando
graficar.reinicializar para no reinicializar IDLE (como ha-
cemos ac).
Obtenemos un grfco como el de la fgura ., donde vemos que
los puntos estn aproximadamente sobre una recta, representando la
distribucion uniforme de ellos.
Decimos que los nmeros estn uniformemente distribuidos pues
la probabilidad de que uno de los nmeros est en un subintervalo
no depende de la ubicacin del subintervalo, sino slo de su longitud.
Es decir, podemos pensar que intervalos de igual longitud reciben
aproximadamente la misma cantidad de puntos. En otras palabras,
como los nmeros estn entre y , en un intervalo |a, b| |, |
t.z. Qu son los nmeros alearoros? Pg. tyt
x
0.00 49.75 99.50 149.25 199.00
y
0.01
0.50
0.99
Los nmeros clasificados
Figura .: Los nmeros clasifcados.
habr aproximadamente n (b a) puntos:
a = [x for x in lista if 0.1 < x < 0.2]
len(a), 0.1
*
n
a = [x for x in lista if 0.55 < x < 0.65]
len(a), 0.1
*
n
El que la lista ordenada tuviera como grfco prcticamente una
recta es un efecto de la uniformidad y no de ser nmeros aleatorios,
pues para obtener una recta con n puntos podramos haber tomado
directamente la lista [x/n for x in range(n)] (= , n, n, . . . )
que no parece muy aleatoria que digamos, pero s que su grfco est
sobre una recta.
En cambio, el hecho de ser aleatoria y los nmeros obtenidos en
forma independiente, se refeja en que si tomamos una sublista de, diga-
mos, n nmeros, en general sta tendr el mismo comportamiento
que la original.
Ejecutar los siguientes grupos:
n2 = n // 2
lista2 = lista[:n2]
Pg. tyz Cap|rulo t. Nmeros alearoros
graficar.reinicializar()
graficar.puntos(pts2d(lista2))
graficar.titulo = La mitad de los nmeros
graficar.mostrar()
a = [x for x in lista2 if 0.1 < x < 0.2]
len(a), 0.1
*
n2
a = [x for x in lista2 if 0.85 < x < 0.95]
len(a), 0.1
*
n2
lista2.sort() # no importa que la lista cambie
graficar.reinicializar()
graficar.puntos(pts2d(lista2))
graficar.titulo = Mitad de los nmeros ordenados
graficar.mostrar()
Ejercicio .. Repetir los pasos anteriores tomando:
slo los ltimos n nmeros,
los que estn en posicin par,
eligiendo n puntos con random.sample,
comprobando que no hay diferencias cualitativas. e
En cambio, si tomamos los cuadrados, el comportamiento es dife-
rente: los nmeros se agrupan ms cerca de , y la distribucin deja de
ser uniforme.
graficar.reinicializar()
lista3 = [x
**
2 for x in lista]
graficar.puntos(pts2d(lista3))
graficar.titulo = Los nmeros elevados al cuadrado
graficar.mostrar()
Por intervalos, vemos que en intervalos cercanos a hay ms n-
meros que cuando tomamos el intervalo cerca de :
a = [x for x in lista3 if 0.1 < x < 0.2]
len(a), 0.1
*
n
t.. Aplcacones Pg. ty
a = [x for x in lista3 if 0.85 < x < 0.95]
len(a), 0.1
*
n
Clasifcando, la curva se parecer a una parbola:
graficar.reinicializar()
lista3.sort()
graficar.puntos(pts2d(lista3))
graficar.titulo = Los nmeros al cuadrado ordenados
graficar.mostrar()
.. Aplicaciones
Ejercicio .. La funcin dado1 (en el mdulo dados) simula tirar
un dado mediante nmeros aleatorios, retornando un nmero entero
entre y (inclusivos).
a) Hacer varias tiradas, por ejemplo construyendo una lista.
b) Modifcar la funcin para simular tirar una moneda con resul-
tados cara o ceca. e
Ejercicio .. La funcin dado2 (en el mdulo dados) hace una si-
mulacin para encontrar la cantidad de veces que se necesita tirar un
dado hasta que aparezca un nmero prefjado.
Observar que si el argumento es un nmero menor que o mayor
que , el lazo no termina nunca.
a) Ejecutar la funcin varias veces, para tener una idea de cunto
tarda en aparecer un nmero.
b) Modifcar el lazo de modo de no usar break en el lazo poniendo
veces = 1 inicialmente.
Sugerencia: cambiar tambin la condicin en while.
c) Corriendo la funcin veces, calcular el promedio de los
tiros que tard en aparecer el nmero predeterminado.
Recordar que el promedio generalmente es un nmero deci-
mal.
Pg. ty{ Cap|rulo t. Nmeros alearoros
Se puede demostrar que el promedio debe ser aproximada-
mente .
d) Modifcar la funcin a fn de simular que se tiran simultnea-
mente dos dados, y contar el nmero de tiros necesarios hasta
obtener un resultado entrado como argumento (entre y ). e
Ejercicio .. Defnir una funcin que diga cuntas veces debi tirar-
se un dado hasta que aparezca el seis k veces consecutivas, donde k es
argumento.
Sugerencia: poner un contador c inicialmente en , y dentro de un
lazo el contador se incrementa en si sali y si no se vuelve a . e
En los ejercicios anteriores surge la duda de si el programa termi-
nar alguna vez, dado que existe la posibilidad de que nunca salga el
nmero prefjado, o que nunca salga k veces consecutivas un mismo
nmero. Suponiendo que el generador de nmeros aleatorios es co-
rrecto, se puede demostrar matemticamente que la probabilidad de
que esto suceda es .
Trabajando con tamaos chicos no hay inconvenientes, pero puede
suceder que haya problemas en la prctica, ya que ningn generador
es perfecto (siendo determinstico). Por ejemplo, si en vez de dados
consideramos permutaciones de n, y n es ms o menos grande (alrede-
dor de ), es posible que nunca consigamos una permutacin dada
con el generador de Python.
Ejercicio .. Mari quiere jugar al Quini y como est haciendo el
curso de programacin, se le ocurri usar la compu para encontrar
los nmeros, eligiendo aleatoriamente nmeros distintos entre
y (inclusivos). El profe le dijo que podra usar random.sample,
random.shuffle, o slo random.randint y pop. Podras ayudarla
a usar estas tres variantes? e
Ejercicio .. Recordando lo hecho en la seccin .:
a) Desarrollar una funcin para hacer una lista de r nmeros
enteros, elegidos aleatoria y uniformemente entre y s, donde
r, s N son argumentos.
t.. Aplcacones Pg. tyy
b) Modifcar la funcin de modo que al terminar imprima la can-
tidad de veces que se repite cada elemento.
Debido a la distribucin uniforme, las cantidades de las apa-
riciones deberan ser muy similares, aproximadamente rs
cada uno, cuando r s. e
Ejercicio ..
a) Defnir una funcin que elija aleatoriamente el nmero apro-
ximadamente el % de las veces, el nmero el % de las
veces, el el % de las veces y el el % de las veces.
Sugerencia: considerar las sumas acumuladas ., . + .,...
(recordar el ejercicio .).
b) Generalizar al caso en que en vez de las frecuencias ., ., .
y ., se d una lista (f

, . . . , f
n
) de nmeros no negativos tales
que

n
i=
f
i
= . Probar para distintos valores y verifcar que las
frecuencias son similares a las deseadas. e
Ejercicio . (dos con el mismo cumpleaos). Mucha gente se sor-
prende cuando en un grupo de personas hay dos con el mismo da de
cumpleaos: la probabilidad de que esto suceda es bastante ms alta
de lo que se cree normalmente.
a) Cuntas personas te parece que debera haber para que haya
dos con el mismo cumpleaos (en general, en promedio)?
Supongamos que en una sala hay n (n N) personas y supongamos,
para simplifcar, que no hay aos bisiestos (no existe el de febre-
ro), de modo que podemos numerar los posibles das de cumpleaos
, , . . . , .
b) Para qu valores de n se garantiza que haya al menos dos
personas que cumplen aos el mismo da?
Sugerencia: recordar el principio de Dirichlet.
El principio de Dirichlet (o del casillero o del palomar) dice
que si hay n + objetos repartidos en n casillas, hay al menos
una casilla con o ms objetos.
Pg. tyo Cap|rulo t. Nmeros alearoros
c) Si la sala es un cine al cual van entrando de a una las personas,
cuntas personas, en promedio, entrarn hasta que dos de ellas
tengan el mismo da de cumpleaos? Responder esta pregunta
escribiendo una funcin que genere aleatoriamente das de
cumpleaos (nmeros entre y ) hasta que haya dos que
coincidan, retornando la cantidad de personas necesarias.
Hacer varias corridas para tener una idea ms acabada.
Adems de suponer que no hay aos bisiestos, para la simula-
cin suponemos tambin que existe la misma probabilidad
de nacer en cualquier da, lo que no es estrictamente cierto.
d) Si en tu curso hay compaeros, apostaras que hay dos que
cumplen aos el mismo da?
El valor terico para el apartado c) es aproximadamente ..
k Aunque parece trivial, el problema se relaciona con temas tan di-
versos como metodos para estimar el total de una poblacion o con
las funciones de hash que usa Python para el manejo efciente de
listas (ver comentarios al fnal del captulo :). e
Ejercicio .. Un problema que caus gran revuelo hacia en
Estados Unidos es el siguiente:
En un show televisivo el locutor anuncia al participante
que detrs de una de las tres puertas que ve, hay un auto
km, no habiendo nada detrs de las otras dos (el auto
se coloca detrs de una de las puertas aleatoriamente,
con la misma probabilidad para cada puerta).
El locutor le pide al participante que elija una de las
puertas.
Sin abrir la puerta elegida por el participante, el locu-
tor (quien conoce dnde est el auto) abre otra puerta
mostrndole que no hay nada detrs de sta, y le da la
opcin al participante de cambiar su eleccin, pudien-
do optar entre mantener su primera eleccin o elegir la
tercera puerta.
t.{. Mrodos de Monre Carlo Pg. ty,
Debe el participante cambiar su eleccion?
El revuelo surgi porque mucha gente opinaba que era lo mismo
cambiar la eleccin que no cambiarla, mientras que otros pensaban
que era mejor cambiar.
a) Qu te parece (intuitivamente)?
b) Para tener una idea de la solucin al problema, defnir una fun-
cin para simular la situacin bajo las siguientes suposiciones:
i) las puertas estn numeradas , y ;
ii) la compu pone aleatoriamente el auto detrs de alguna de
las puertas (con igual probabilidad);
iii) nosotros elegimos siempre la puerta nmero ;
iv) el locutor elige una puerta detrs de la cual no est el
auto ni es la que elegimos. Si tiene dos posibilidades, elige
una aleatoriamente.
La funcin debe imprimir la puerta detrs de la cual est el
auto, la puerta elegida por el locutor, y retornar True si ganamos
el auto y False en otro caso.
c) Repetir el apartado anterior pero donde siempre cambiamos
nuestra eleccin (en vez de mantenerla).
d) Modifcando adecuadamente las funciones de los apartados b)
y c) (por ejemplo, comentando la impresin), hacer varias corri-
das ( o ) conestas funciones obteniendo el promedio
de las veces que ganamos.
En base a los resultados obtenidos, qu estrategia seguiras,
cambiaras o no tu eleccin? e
.. Mtodos de Monte Carlo
Existen muchos mtodos, llamados genricamente de Monte Carlo,
para aproximar cantidades determinsticas mediante probabilidades, y
en esta seccin vemos algunos ejemplos de esta tcnica.
Pg. ty8 Cap|rulo t. Nmeros alearoros
k Uno de las primeras aplicaciones fue la aguja de Bufon (ejerci-
cio :.:), pero el metodo comenzo a aplicarse sistematicamente
cuando S. Ulam (:o:8) y j. von ^eumann (quien eligio el nom-
bre de Monte-Carlo en honor al casino famoso) lo usaron hacia
:o en estudios de fsica atomica.
Ejercicio .. Defnir una funcin para simular una mquina que
emite nmeros al azar (uniformemente distribuidos) en el intervalo
|, ) uno tras otro hasta que su suma excede . Comprobar que al usar
la mquina muchas veces, la cantidad promedio de nmeros emitidos
es aproximadamente e = . . . . e
Ejercicio .. Defnir una funcin para aproximar tomando n
pares de nmeros aleatorios (a, b), con a y b entre y , contar cun-
tos de ellos estn dentro del crculo unidad (es decir, a

+ b

< ).
El cociente entre este nmero y n (ingresado como argumento), es
aproximadamente el cociente entre las reas del crculo de radio y el
cuadrado de lado . e
.. Ejercicios adicionales
Ejercicio . (aguja de Bufon). Una aguja fna (tericamente un
segmento) de longitud , es arrojada sobre un tablero dividido por
lneas paralelas donde la distancia entre dos consecutivas es . Mostrar,
mediante una funcin adecuada, que el promedio de veces que la aguja
cruzar una de las lneas es aproximadamente .
k Georges Louis Leclerc, Conde de Buon (:,o,:,88), planteo este
problema en :,, dando origen a la teora de probabilidad geom-
trica. e
.. Comentarios
Hay distintos algoritmos para generar nmeros aleatorios, y los
resultados pueden ser muy distintos segn el algoritmo, a dife-
t.o. Comenraros Pg. ty
rencia de lo que sucede con el seno o el logaritmo (que pueden
calcularse con diferentes algoritmos pero los resultados son si-
milares).
El libro de Knuth (b, vol. ) es una excelente referencia
para quienes quieran aprender sobre qu debe pedirse a un ge-
nerador de nmeros aleatorios, y distintos tipos de algoritmos
para construirlos.
Muchos de los sistemas operativos y las CPU tienen sus propios
generadores, no necesariamente iguales al que usa Python.
En general, los algoritmos para construir nmeros aleatorios
trabajan con nmeros enteros. Por cuestiones prcticas se pone
un lmite sobre el tamao, forzando a los nmeros aleatorios
a repetirse cclicamente.
El algoritmo que usa Python tiene un ciclo de

, que
tiene unas cifras en base , ampliamente sufciente para
nosotros!
Python tiene varias funciones para nmeros aleatorios, inclusive
usando distintas distribuciones probabilsticas, pero nosotros
vamos a usar siempre la distribucin uniforme. El manual de la
biblioteca tiene informacin completa sobre el mdulo random.
Los ejemplos del mtodo de Monte Carlo que dimos (ejerci-
cios ., . y .) son ms que nada de inters terico e
introductorio al tema, pues las aproximaciones respectivas son
lentas.

Captulo
Clasifcacin y bsqueda
Siempre estamos buscando algo y es mucho ms fcil encontrarlo
si los datos estn clasifcados u ordenados, por ejemplo, una palabra en
un diccionario. No es sorpresa que bsqueda y clasifcacin sean temas
centrales en informtica: el xito de Google se basa en los algoritmos
de clasifcacin y bsqueda que usa.
Es usual que en los cursos bsicos de programacin (como ste)
se enseen algoritmos elementales de clasifcacin, que en general
necesitan del orden de n

pasos para clasifcar una lista de longitud


n. En contraposicin, el mtodo de clasifcacin que usa Python es
bastante sofsticado y rpido, necesitando del orden de n log n pasos
(entre comparaciones y asignaciones).
No vamos a tener tiempo en el curso para estudiar los mtodos
elementales como insercin directa, seleccin directa o intercambio
directo (burbujeo).
()
De cualquier forma, vamos a ver el metodo de con-
teo en el ejercicio . que extiende tcnicas ya vistas, y es muy sencillo
y rpido (usando del orden de n pasos) en ciertas circunstancias.
Anlogamente, con in, index y count (o los ejercicios . y .)
podemos buscar un objeto en una lista recorrindola linealmente (mi-
rando cada elemento en el orden en que aparece), pero podemos mejo-
()
El interesado puede consultar el excelente libro de Wirth ().
t{.t. Clasfcacn Pg. tot
rar la efciencia si la lista est ordenada usando bsqueda binaria, lo
que hacemos en la seccin ..
.. Clasifcacin
Ejercicio .. Para clasifcar una lista (modifcndola) podemos usar
el metodo sort en Python. Si no queremos modifcar la lista o tra-
bajamos con una cadena de caracteres o tupla que no se pueden
modifcar podemos usar la funcion sorted que da una lista.
Verifcar los resultados de los siguientes en la terminal de IDLE,
donde usamos la funcin sumar defnida en el ejercicio .:
a) import random
a = list(range(10))
random.shuffle(a)
a
b = sorted(a)
b
a # no se modific
a.sort(reverse=True) # clasificar al revs
a
b) a = mi mam me mima # con tilde
a.sort() # da error porque es inmutable
b = sorted(a)
b # da una lista
a # no se modific
sumar(b)
Es posible que la (con tilde) no aparezca en el lugar correc-
to. Para que lo haga hay que cambiar algunas cosas que nos
desviaran demasiado. Nuestra solucin ser sencillamente
no usar tildes o diresis al clasifcar caracteres.
c) a = (4, 1, 2, 3, 5)
Pg. toz Cap|rulo t{. Clasfcacn y bsqueda
sorted(a) # da una lista
sorted(a, reverse=True) # orden inverso e
Si t es una lista, podemos considerar t.sort() y t.reverse(),
que modifcan a t. Si s es una secuencia (no necesariamente mutable),
sorted(s) da una lista (y s no se modifca), pero reversed(s) no es
una lista sino un objeto del tipo reversed , que no veremos en el
curso.
Ejercicio . (key). A veces queremos ordenar segn algn crite-
rio distinto al usual, y para eso tanto en sort como en sorted
podemos usar la opcin key (llave o clave).
key debe indicar una funcin que a cada objeto asigna un valor
(usualmente un nmero, pero podra ser otro tipo como cadena), de
modo que se puedan ordenar distintos objetos mediante estos valores.
a) Por ejemplo, supongamos que tenemos la lista
a = [[Pedro, 7], [Pablo, 6], [Chucho, 7],
[Jacinto, 6], [Jos, 5]]
de nombres de chicos y sus edades.
Ordenando sin ms, se clasifca primero por nombre y luego
por edad:
sorted(a)
b) Si queremos clasifcar por edad, defnimos la funcin que a
cada objeto le asigna su segunda coordenada:
def edad(x):
return x[1]
sorted(a, key=edad)
Observar que se mantiene el orden original entre los que tie-
nen la misma edad: [Pablo, 6] est antes de [Jacinto,
6] pues est antes en la lista a.
Esta propiedad del mtodo de clasifcacin se llama estabili-
dad.
t{.t. Clasfcacn Pg. to
c) La estabilidad nos permite clasifcar primero por una llave y
luego por otra.
Por ejemplo, si queremos que aparezcan ordenados por edad,
y para una misma edad por orden alfabtico, podramos poner:
b = sorted(a) # orden alfabtico primero
sorted(b, key=edad) # y despus por edad
La ltima llave por la que se clasifca es la ms importante.
En el ejemplo, primero alfabticamente (menos importante) y
al fnal por edad (ms importante).
d) Consideremos una lista de nombres:
nombres = [Ana, Gabi, Mari, Mateo,
Geri, Guille, Maggie, Pedro,
Pablo, Chucho, Jacinto, Jos]
y llamemos n a la longitud de esta lista.
i) Construir una lista edades, con n enteros aleatorios entre
y (inclusivos).
ii) Construir una lista notas, con n enteros aleatorios entre
y (inclusivos).
iii) Construir una lista datos con elementos de la forma [x,
y, z], con x en nombres, y en edades y z en notas. si-
guiendo el orden de las listas originales.
iv) Clasifcar datos de manera que los datos aparezcan orde-
nados por nota inversamente (de mayor a menor), luego
por edad, y fnalmente por nombre. Es decir, al terminar
vendrn primero los que tienen mayores notas, si empatan
la nota viene primero el de menor edad, y a una misma
edad y nota, se ordenan alfabticamente por nombre. e
Ejercicio .. Defnir una funcin que tome como argumento una
cadena de caracteres y escriba los caracteres ingresados y la cantidad
de apariciones, ordenados decrecientemente segn la cantidad de apa-
riciones, y alfabticamente ante igualdad de apariciones.
Pg. to{ Cap|rulo t{. Clasfcacn y bsqueda
Por ejemplo, si argumento es mece, se debe imprimir algo como:
Caracter cantidad
e 2
c 1
m 1
Aclaracion: suponemos que la cadena tiene slo letras y nmeros,
pero no letras con tildes ni signos de puntuacin.
Ver tambin el ejercicio .. e
Ejercicio . (clasifcacin por conteo). Un mtodo de clasifcacin
sencillo y rpido es poner los objetos en cajas correspondientes.
Por ejemplo, supongamos que sabemos de antemano que los ele-
mentos de
a = [a[0], a[1],..., a[n-1]]
son enteros que satisfacen 0 <= a[i] < m para i = , , . . . , n, y m es
relativamente pequeo.
Podemos imaginar que la lista que tenemos que clasifcar son n
bolitas alineadas, cada una con un nmero entre y m .
Por ejemplo, si
a = [0, 2, 2, 1, 0, 1, 0, 1, 0, 2]
las bolitas estaran alineadas como en la fgura . (arriba). Orientn-
donos con esa fgura, consideramos m cajas numeradas de a m ,
colocamos cada bolita en la caja que tiene su nmero, y fnalmente
vaciamos los contenidos de las cajas ordenadamente, empezando desde
la primera, alineando las bolitas a medida que las sacamos.
En el algoritmo, en vez de colocar cada bolita en su caja, conta-
mos las veces que apareci:
# al principio, las cajas estn vacas
cuenta = [0 for i in range(m)]
# ponemos cada bolita en su caja,
t{.t. Clasfcacn Pg. toy

disposicin inicial



poniendo en cajas

disposicin fnal
Figura .: Ordenando por conteo.
# aumentando el nmero de bolitas en esa caja
for k in a: # k debe estar entre 0 y m-1
cuenta[k] = cuenta[k] + 1
# ahora vaciamos las cajas, alineando las
# bolitas a medida que las sacamos
i = 0 # lugar en la lnea
for k in range(m): # para la caja 0, 1,..., m-1
while cuenta[k] > 0: # si tiene una bolita
cuenta[k] = cuenta[k] - 1 # la sacamos
a[i] = k # la ponemos en la lnea
i = i + 1 # prximo lugar en la lnea
a) Defnir una funcin conteo(a, m) que clasifca la lista a con
este mtodo (modifcando la lista). Luego comparar con sort
cuando a es una lista de nmeros enteros aleatorios entre
y .
b) Cmo podramos encontrar m si no se conoce de antemano?
Pg. too Cap|rulo t{. Clasfcacn y bsqueda
Aclaracion: suponemos dada una lista con nmeros enteros
no negativos.
c) Se podra cambiar el lazo for k in a... por una funcin o
mtodo de Python?
Se puede ver que el mtodo usa del orden de n + m pasos, asig-
naciones y comparaciones, lo que lo hace ms efciente que otros
algoritmos generales cuando m es chico, digamos menor que n.
Otra forma de mirar la tcnica es pensar que cuenta[k] no es
otra cosa que la frecuencia con la que aparece el dato k.
k El metodo se generaliza al llamado bucket sort o bin sort,
()
y se
usa en muchas situaciones. Por ejemplo, una forma de clasifcar
cartas (naipes) es ordenarlas primero segun el palo y despues
ordenar cada palo. e
.. Listas como conjuntos
A veces es conveniente tratar a una sucesin como un conjunto, es
decir, no nos interesan los elementos repetidos ni el orden. En estos
casos, es conveniente eliminar los elementos repetidos, procedimiento
que llamamos purga.
Python tiene la estructura set (conjunto) que permite tomar
unin, interseccin y otras operaciones entre conjuntos. set es
un iterable (se puede usar con for), pero a diferencia de las suce-
siones, sus elementos no estn ordenados y no pueden indexarse.
Nosotros no veremos esta estructura.
Ejercicio . (purgar una lista). En este ejercicio vamos a purgar
una lista dada, eliminando los elementos repetidos pero conservando
el orden original entre los que sobreviven (algo como la estabilidad).
Por ejemplo, si inicialmente a = [1, 3, 1, 5, 4, 3, 5, 1, 4, 2,
5], queremos obtener la lista [1, 3, 5, 4, 2].
a) Si no queremos modifcar a, un primer esquema es
()
Bucket: balde o cubo, bin: caja, sort: clasifcacin.
t{.z. Lsras como conjunros Pg. to,
b = []
for x in a:
if x not in b:
b.append(x)
b
Defnir una funcin con estas ideas y probarla en el ejemplo
dado.
b) En base al esquema anterior, defnir una funcin purgar(a)
de modo que a se modifque adecuadamente sin usar una lista
auxiliar.
Aclaracion: no debe usarse una lista auxiliar pero elementos
de a pueden cambiar de posicin o ser eliminados.
Sugerencia: usar un ndice para indicar las posiciones que
sobrevivirn.
Sugerencia si la anterior no alcanza.
m = 0 # a[0],...,a[m - 1]
# son los elementos sin repetir
for x in a:
if x not in a[:m]: # primera aparicin,
a[m] = x # incorporarlo a lo
m = m + 1 # que quedar
a[m:] = [] # considerar slo a[0],..., a[m-1]
c) Qu problemas tendra usar el esquema
m = 1
for x in a[1:]: # no tocar el primer elemento
if x not in a[:m]:
a[m] = x
m = m + 1
a[m:] = [] # considerar slo a[0],..., a[m-1]
en el apartado anterior, empezando desde y no desde ? e
Ejercicio ..
Pg. to8 Cap|rulo t{. Clasfcacn y bsqueda
a) Defnir una funcin cuentas(a) dada una lista a retorna una
nueva lista [[x, p], [y, q],...] donde x, y,... son los
elementos de a sin repeticiones, y p, q,... es la cantidad de
apariciones.
Por ejemplo, si a = [1, 3, 1, 4, 3, 1, 4, 2], el resul-
tado debe ser [[1, 3], [3, 2], [4, 2], [2, 1]].
b) Modifcar la funcin anterior para retornar la lista ordenada
decrecientemente segn la cantidad de apariciones (a igual
cantidad, ordenada crecientemente).
Comparar con el ejercicio .. e
Ejercicio . (purgar una lista ordenada). En este ejercicio que-
remos eliminar elementos repetidos de la lista a que est ordenada de
menor a mayor. Por ejemplo, si a = [1, 2, 2, 5, 6, 6, 9], quere-
mos obtener [1, 2, 5, 6, 9].
Podramos usar directamente el ejercicio ., pero una variante
del apartado b) es ms efciente:
m = 0 # a[0],...,a[m - 1]
# son los elementos sin repetir
for i in range(1, n): # n es la longitud de a
if a[m] < a[i]: # incluir a[i] si no es a[m]
m = m + 1
a[m] = a[i]
a[m+1:] = [] # considerar slo a[0],..., a[m]
Construir una funcin purgarordenado que modifca su argumen-
to siguiendo este esquema.
La efciencia se refere a que el mtodo del ejercicio . en general
hace del orden de n

comparaciones, mientras que el presentado


ac usa del orden de n. e
Ejercicio . (de lista a conjunto). Defnir una funcin para pasar
una lista a conjunto, ordenndola y purgndola (en ese orden). Por
ejemplo, si a = [3, 1, 4, 2, 3, 1], el resultado debe ser [1, 2,
3, 4] (a no debe modifcarse).
t{.z. Lsras como conjunros Pg. to
En general (no siempre) es ms efciente primero clasifcar y des-
pus purgar (segn el ejercicio .) que purgar primero (segn
el ejercicio .) y despus clasifcar. e
Ejercicio . (unin de listas). En este ejercicio queremos cons-
truir la unin de las listas a y b, es decir, una lista ordenada c con
todos los elementos que estn en a o b (pero aparecen en c una sola
vez), y a y b no se modifcan. Por ejemplo, si a = [3, 1, 4, 2, 3,
1] y b = [2, 3, 1, 5, 2], debe ser c = [1, 2, 3, 4, 5]. En par-
ticular, la unin de a con a son los elementos de a clasifcados y sin
repeticiones (pero sin modifcar a).
a) Construir una funcin poniendo una lista a continuacin de la
otra:
c = a + b
y luego clasifcando y purgando (con sort y purgarordenado
respectivamente) la lista c.
b) Defnir una funcin para el problema usando un lazo para
recorrer simultneamente a y b despus de pasarlas de lista a
conjunto, generalizando el esquema de purgarordenado:
# ac a y b ya estn clasificadas y purgadas,
# con longitudes n y m respectivamente
i, j = 0, 0 # ndices para a y b
c = [] # no hay elementos copiados
while (i < n) and (j < m):
if a[i] < b[j]:
c.append(a[i]) # copiar en c
i = i + 1 # y avanzar en a
elif a[i] > b[j]:
c.append(b[j]) # copiar en c
j = j + 1 # y avanzar en b
else: # a[i] == b[j]
c.append(a[i]) # copiar en c
i = i + 1 # y avanzar en
Pg. t,o Cap|rulo t{. Clasfcacn y bsqueda
j = j + 1 # ambas listas
c = c + a[i:] # copiar el resto de a
c = c + b[j:] # copiar el resto de b
Este procedimiento de combinar listas ordenadas se llama
fusin (merge).
En general, este mtodo es ms efciente que el del apartado
anterior. e
Ejercicio . (interseccin de listas). Del mismo modo, pode-
mos considerar la interseccin de las listas a y b, es decir, una lista
ordenada c con todos los elementos que estn en a y b simultneamen-
te (pero aparecen en c una sola vez). Por ejemplo, si a = [3, 1, 4,
2, 3, 1] y b = [2, 3, 1, 5, 2], debe ser c = [1, 2, 3]. Si a y b
no tienen elementos comunes, c es la lista vaca. Como en la unin,
la interseccin de a con a son los elementos de a clasifcados y sin
repeticiones.
Construir una funcin copiando las ideas del ejercicio ..b).
Sugerencia: eliminar algunos renglones en el esquema, copiando
en c slo si el elemento est en ambas listas. e
Ejercicio . (estadsticos). Cuando se estudian estadsticamente
los datos numricos (a

, a

, . . . , a
n
), se consideran (entre otros) tres
tipos de medidas:
La meda o promedo:

n
n

i=
a
i
.
La medana: Intuitivamente es un valor m tal que la mitad de
los datos son menores o iguales que m y la otra mitad son
mayores o iguales que m. Para obtenerla, se ordenan los datos
y la mediana es el elemento del medio si n es impar y es el
promedio de los dos datos en el medio si hay un nmero par
de datos.
Observar que la mediana puede no ser un dato en el caso de
n par.
t{.. Bsqueda bnara Pg. t,t
El algoritmo fnd de Hoare () permite encontrar la
mediana sin necesidad de clasifcar completamente la lista.
La moda: Es un valor a

con frecuencia mxima, y puede haber


ms de una moda.
Por ejemplo, si los datos son , , , , , , , , , , la media es .,
la mediana es , y las modas son , y .
a) Defnir sendas funciones para encontrar la media, mediana y
moda, de listas de nmeros enteros.
b) Aplicar las funciones del apartado anterior a listas de longitud
, y de nmeros enteros entre y generados aleatoria-
mente.
Si sabemos que los nmeros en las listas no tienen un rango dema-
siado grande, la moda y la mediana se pueden encontrar usando
la tcnica del ejercicio .. e
.. Bsqueda binaria
Ejercicio . (el regalo en las cajas). Propongamos el siguiente jue-
go:
Se esconde un regalo en una de diez cajas alineadas de iz-
quierda a derecha, y nos dan cuatro oportunidades para
acertar. Despues de cada intento nuestro, nos dicen si ga-
namos (terminando el juego) o si el regalo esta hacia la
derecha o izquierda.
a) Simular este juego en la computadora, donde una caja es un
nmero de (extrema izquierda) a (extrema derecha):
la computadora elige aleatoriamente una ubicacin (entre
posibles) para el regalo,
el usuario elige una posicin (usar input),
Pg. t,z Cap|rulo t{. Clasfcacn y bsqueda
la computadora responde si el regalo est en la caja elegida
(y el usuario gana y el juego se termina), o si el regalo est
a la derecha o a la izquierda de la posicin propuesta por el
usuario,
si despus de cuatro oportunidades no acert la ubicacin, el
usuario pierde y la computadora da el nmero de caja donde
estaba el regalo.
b) Ver que siempre se puede ganar con la estrategia de busqueda
binaria: elegir siempre el punto medio del rango posible.
c) Ver que no siempre se puede ganar si slo se dan tres oportuni-
dades.
d) Cuntas oportunidades habr que dar para n cajas, suponien-
do una estrategia de bsqueda binaria?
Ayuda: la respuesta involucra log

.
e) Repetir el apartado d) (para calcular la cantidad de oportuni-
dades) y luego el apartado a) para la versin donde en vez de
tenerlas alineadas, las cajas forman un tablero de m n, y la
bsqueda se orienta dando las direcciones norte, noreste,...,
sur,..., noroeste. e
Ejercicio .. Se ha roto un cable maestro de electricidad en algn
punto de su recorrido subterrneo de cuadras. La compaa local de
electricidad puede hacer un pozo en cualquier lugar para comprobar
si hasta all el cable est sano, y bastar con detectar el lugar de la falla
con una precisin de m.
Por supuesto, una posibilidad es ir haciendo pozos cada m, pero
el encargado no est muy entusiasmado con la idea de hacer tantos
pozos, porque hacer (y despus tapar) los pozos cuesta tiempo y dinero,
y los vecinos siempre se quejan por el trnsito, que no tienen luz, etc.
Qu le podras sugerir al encargado? e
Cuando la sucesin a est ordenada, la bsqueda de x en a se
facilita enormemente, por ejemplo al buscar en un diccionario o en
una tabla.
t{.. Bsqueda bnara Pg. t,
Uno de los mtodos ms efcientes para la bsqueda en una secuen-
cia ordenada es la busqueda binaria: sucesivamente dividir en dos y
quedarse con una de las mitades, como hicimos en el ejercicio ..
Ejercicio . (bsqueda binaria). Si queremos saber si un elemento
x est en la lista a de longitud n, sin ms informacin sobre la lista
debemos inspeccionar todos los elementos de a, por ejemplo si x no
est, lo que lleva del orden de n pasos. La cosa es distinta si sabemos
que a est ordenada no decrecientemente, es decir, a[0] <= a[1]
<=...<= a[n-1].
La idea del mtodo de bsqueda binaria es partir la lista en dos
partes iguales (o casi) y ver de qu lado est el elemento buscado, y
luego repetir el procedimiento, reduciendo la longitud de la lista en
dos cada vez.
a) Un primer intento es:
poco = 0
mucho = n - 1
while poco < mucho:
medio = (poco + mucho) // 2
if a[medio] < x:
poco = medio
else:
mucho = medio
# a continuacin comparar x con a[mucho]
Ver que este esquema no es del todo correcto, y puede llevar
a un lazo infnito.
Sugerencia: considerar a = [1, 3] y x = 2.
b) El problema con el lazo anterior es que cuando
mucho = poco + , (.)
como medio = (poco + mucho) obtenemos
medio = poco. (.)
Pg. t,{ Cap|rulo t{. Clasfcacn y bsqueda
i) Verifcar que (.) implica (.).
ii) Verifcar que, en cambio, si mucho poco + entonces
siempre debe ser poco < medio < mucho.
c) Ver que el siguiente esquema es correcto:
poco = 0
mucho = n - 1
while poco + 1 < mucho:
medio = (poco + mucho) // 2
if a[medio] < x:
poco = medio
else:
mucho = medio
# ahora comparar x con a[mucho] y con a[poco]
y usarlo para defnir una funcin busbin(a, x) para buscar
un elemento en una lista (ordenada no decrecientemente!)
retornando False o True y en este caso imprimiendo su posi-
cin.
d) Probar busbin(a, x) cuando a es una lista ordenada de
nmeros enteros elegidos al azar entre y , en los siguientes
casos:
i) x es elegido aleatoriamente en el mismo rango pero puede
no estar en la lista a (hacerlo varias veces).
ii) x = 0.
iii) x = 1001.
e) Cmo se relacionan el mtodo de bsqueda binaria (en es-
te ejercicio) y el del regalo en las cajas (ejercicio .)? Por
ejemplo, cul sera la lista ordenada?
Python tiene distintas variantes y aplicaciones de bsqueda bi-
naria en el mdulo estndar bisect, que no veremos en el curso
(consultar el manual de la biblioteca). e
t{.{. Ejerccos adconales Pg. t,y
.. Ejercicios adicionales
Ejercicio . (generala). En el juego de la generala se tiran dados
y se tiene:
full si hay dados con un mismo nmero y con otro nmero,
pker cuando hay dados iguales (pero no ),
escalera cuando hay nmeros consecutivos, y
generala cuando los dados son iguales.
Defnir una funcin para simular este juego, imprimiendo alguna
de las posibilidades anteriores si sali, o si no sali ninguna. e
.. Comentarios
Los interesados en el apasionante tema de clasifcacin y bs-
queda pueden empezar mirando el libro de Wirth () y luego
profundizar con el de Knuth (). El libro de Sedgewick y
Wayne () es de un nivel intermedio, pero est en ingls.
Python usa funciones hash
()
para encontrar rpidamente ele-
mentos en una secuencia no ordenada, es decir, en general no
usa ni un recorrido lineal ni bsqueda binaria.
Los tres libros mencionados anteriormente incluyen descrip-
ciones de esta tcnica y algoritmos asociados.
Los curiosos pueden poner help(hash) y despus probar con
hash(mama), hash(mami), hash(1), hash(1.0), etc.

()
Normalmente traducidas como transformaciones de llave (o clave).
Captulo
El mdulo gracar y
funciones numricas
En este captulo vemos cmo Python nos puede ayudar en el estu-
dio de funciones f A R, (donde Aes un intervalo o eventualmente
todo R) como las que se ven en clculo o anlisis matemtico, visuali-
zndolas con el mdulo gracar.
Este mdulo no estndar nos permite hacer grfcos en dos dimen-
siones de puntos y curvas, aprovechando las facilidades grfcas del
mdulo tkinter de Python, y se puede bajar de la pgina del libro.
gracar es muy elemental, muy lejos de las posibilidades grfcas de,
por ejemplo, Mathematica, pero es adecuado para nuestros propsitos,
no tenemos que instalar programas adicionales, y es independiente del
sistema operativo pues est escrito (claro) en Python.
El mdulo no estndar matplotlib tiene muchas ms posibilida-
des. Lamentablemente no est disponible para todos los sistemas
operativos en las versiones ms recientes de Python.
En el curso usaremos gracar como caja negra, como hacemos
con math, slo usaremos algunos comandos y no estudiaremos las
instrucciones en l. En este captulo nos concentramos en los grfcos
Pg. t,,
de funciones, pero como ya hemos visto en el captulo gracar
tambin nos permite agregar otros elementos, como puntos, rectas,
tangentes, poligonales, texto y otros ms.
Ejercicio ..
a) Copiar el mdulo gracar en el directorio donde se guardan
nuestros mdulos, y poner help(graficar) y despus, por
ejemplo, help(graficar.funcion) (funcion sin tildes).
Recordar que antes de usar help hay que colocarse en el di-
rectorio correcto y usar import.
b) Ejecutar el mdulo grseno para hacer un grfco del seno entre
y , con los valores de las opciones por defecto.
En el contenido de grseno, observamos que:
El primer argumento de graficar.funcion es la funcin, que
debe estar defnida con anterioridad, y los otros dos son los
extremos del intervalo (cerrado) donde hacer el grfco.
gracar espera que primero se defnan los elementos del grfco,
y luego lo construye con graficar.mostrar().
El grfco no conserva la escala entre los ejes, sino que por
defecto pone el grfco en el tamao de la ventana disponible.
Los ejes x y y se dibujan en el borde, dejando ms limpio el
grfco, y pueden no cortarse en (, ).
c) Podemos cambiar o agregar algunos elementos del grfco.
Por ejemplo, si ponemos en el mdulo grseno, antes de
graficar.mostrar():
i) graficar.titulo = Seno en [0, pi], el ttulo de la
ventana cambiar acordemente.
Sabiendo la forma de introducir el smbolo (que depen-
de del sistema operativo y teclado), no hay problema en
reemplazar pi por en el ttulo pues usamos utf-.
Pg. t,8 Cap|rulo ty. El mdulo gracar y funcones numrcas
Siempre se pueden ingresar caracteres utf- con c-
digos especiales (independientes del sistema operativo
o teclado), pero para lo que hacemos no vale la pena
meterse en ese lo: en todo caso dejamos pi.
ii) graficar.ymin = -0.2 y graficar.ymax = 1.2 hacen
que el grfco tenga un poco ms de espacio en el eje y.
iii) En cambio, rebanamos el grfco con graficar.ymin =
0.2 y graficar.ymax = 0.8.
iv) Con graficar.aspecto = True hacemos que los ejes ten-
gan la misma escala. En este caso, el alto se determina a
partir del ancho, aunque algunos elementos grfcos pue-
den no quedar bien. e
Ejercicio .. Grafcar:
a) x en el intervalo |, |.
b) cos x en el intervalo |, |.
c)

x en el intervalo |, |. e
Ejercicio .. gracar permite hacer el grfco de varias funciones
simultneamente, alternando los colores automticamente. En estos
casos conviene poner leyendas para distinguirlas, como hacemos en
el mdulo grexplog, donde grafcamos las funciones e
x
entre y ,
log x entre (casi) y ,
()
y las comparamos con la funcin identidad,
Id(x) = x, puesto que siendo inversas una de la otra, los grfcos de e
x
y log x son simtricos respecto de la diagonal y = x.
a) El grfco no refeja bien la simetra respecto de la diagonal
y = x, debido a que las escalas de los ejes son distintas. Ver si
poniendo graficar.aspecto = True mejora el grfco.
b) La posicin de las leyendas est indicada como NO por esqui-
na ^orOeste.
i) Comentar el rengln correspondiente y ver cul es la posi-
cin de las leyendas por defecto.
()
Ver tambin el ejercicio ..
Pg. t,
ii) Cambiar el mdulo de modo que las leyendas aparezcan
en la esquina sureste.
c) Modifcar grexplog para hacer un grfco similar para las fun-
ciones x

y

x (en vez de exp y log), tomando xmin = 0, xmax
= 10 y ymin = xmin:
i) Sin explicitar el valor de graficar.ymax (por ejemplo, co-
mentando el rengln correspondiente).
ii) Tomando graficar.ymax = 10. e
Ejercicio .. Cuando queremos hacer el grfco de una funcin que
no tiene una expresin sencilla, como f (x) = x

+ x , lo ms simple
es defnirla primero.
a) En un mdulo o la terminal poner:
def f(x):
"""Funcin a graficar."""
return x
**
2 + 3
*
x - 1
graficar.funcion(f, -3, 1)
graficar.titulo = Grfico de x
**
2 + 3
*
x - 1
graficar.mostrar()
b) Las rectas pueden darse por dos de sus puntos o bien por pun-
to y pendiente. Por ejemplo, si queremos agregar rectas re-
presentando los ejes coordenados, podramos poner antes de
graficar.mostrar():
graficar.recta((0, 0), 0) # eje x
graficar.recta((0, 0), (0, 1)) # eje y
c) El problema es que queda demasiado colorinche: la alternancia
de colores es la misma para curvas, poligonales o rectas. Pero
podemos ponerles colores distintos individualmente.
Cambiar las instrucciones anteriores a:
graficar.recta((0, 0), 0,
estilo = {fill: gray})
Pg. t8o Cap|rulo ty. El mdulo gracar y funcones numrcas
graficar.recta((0, 0), (0, 1),
estilo = {fill: gray})
de modo que ahora los ejes aparecen en color gris.
d) Las marcas en el eje vertical no parecen razonables. Agregar
antes de graficar.mostrar:
graficar.yticks = list(range(-3, 4, 2))
e) Para grafcar la tangente en x = ., podemos poner (siempre
antes de graficar.mostrar):
x = -0.5
y = f(x)
graficar.tangente(f, x)
graficar.puntos([(x, y)]) # lista de un punto
mostrando tambin el punto (x, f (x)). e
Ejercicio .. Recordando el ejercicio .:
a) Sin hacer el grfco, qu tipo de funcin es la que expresa c en
trminos de f (lineal, cuadrtica,...)?
b) Hacer el grfco de las funciones acelsius y la identidad en el
intervalo |, |, y comprobar que las curvas se cortan en el
punto obtenido en el ejercicio ..e) usando el cursor.
c) Usando leyendax y leyenday,
()
cambiar los nombres de los
ejes de modo que en el eje horizontal aparezca la leyenda f (en
vez de x) y en el vertical la leyenda c (en vez de y), y poner un
ttulo adecuado al grfco. e
Ejercicio . (grfco de funciones con saltos). gracar hace el gr-
fco evaluando la funcin en algunos puntos
()
y luego unindolos, por
lo que las funciones discontinuas no se grafcan correctamente.
a) Supongamos que queremos grafcar la funcin y = x que
no est defnida para x = en el intervalo |, |.
()
En todo caso poner help(graficar).
()
Por defecto, puntos equiespaciados.
Pg. t8t
i) El bloque
import graficar
def f(x):
return 1/x
graficar.funcion(f, -1, 1)
graficar.mostrar()
posiblemente dar error de divisin por cero.
ii) Podemos cambiar la opcin npuntos de grfcos de fun-
ciones, de modo de no evaluar x para x = . Para un
intervalo simtrico alrededor de , podemos poner un n-
mero par de puntos: cambiar el rengln que empieza con
graficar.funcion en el bloque anterior por
graficar.funcion(f, -1, 1, npuntos=100)
y ver el resultado.
iii) Una solucin ms satisfactoria es dividir el intervalo en dos
o ms para evitar los saltos, como hacemos en el mdulo
gr1sobrex en el que se puede ajustar eps.
Ponemos explcitamente el estilo (en este caso, color azul)
para evitar que las ramas de la hiprbola se dibujen con
distintos colores.
b) La funcin tangente, tan, no est defnida en +k, para k
Z. Hacer un grfco de esta funcin en el intervalo (, ).
La evaluacin de Python de tan no da error, como vimos
en el ejercicio .. e
Ejercicio .. Recordando el ejercicio .:
a) Hacer un grfco aproximado (sin tener en cuenta saltos) del
impuesto y la ganancia neta, cuando la ganancia bruta est
entre y .
b) En el grfco se podr observar que la ganancia neta para un
ingreso de es mayor que la correspondiente a ingresos
un poco mayores.
Pg. t8z Cap|rulo ty. El mdulo gracar y funcones numrcas
Usando el ratn, determinar un valor aproximado de x tal
que la ganancia neta para un ingreso de + x sea
igual a la ganancia neta para un ingreso de . Luego
determinar matemticamente x. e

Captulo
Clculo numrico elemental
Una de las aplicaciones ms importantes de la computadora (y a
la cual debe su nombre) es la obtencin de resultados numricos.
()
A
veces es sencillo obtener los resultados deseados pero otras debido a
lo complicado del problema o a los errores numricos es sumamente
difcil, lo que ha dado lugar a toda un rea de las matemticas llamada
calculo numerico.
Sorprendentemente, al trabajar con nmeros decimales (float)
pueden pasar cosas como:
a + b == a an cuando b > 0,
(a + b) + c != a + (b + c), o sea, la suma no es asociativa.
En este captulo empezamos mirando a estos inconvenientes, para
pasar luego a ver tcnicas efectivas de resolucin de problemas.
.. La codifcacin de decimales
Como vimos al calcular

en el ejercicio ., Python puede


trabajar con cualquier nmero entero (sujeto a la memoria de la compu-
()
En Espaa en vez de computadora se la llama ordenador, destacando otras aplica-
ciones fundamentales que consideramos en otros captulos.
Pg. t8{ Cap|rulo to. Clculo numrco elemenral
tadora) pero no con todos los nmeros decimales. Para los ltimos
usa una cantidad fja de bits (por ejemplo ) divididos en dos grupos,
uno representando la mantisa y otro el exponente como se hace en la
notacin cientfca al escribir .

(. es la mantisa y el
exponente en base , pero la computadora trabaja en base ).
Python usa una estructura especial que le permite trabajar con
enteros de cualquier tamao, si es necesario fraccionndolos pri-
mero para que la computadora haga las operaciones y luego rear-
mndolos, procesos que toman su tiempo.
Por cuestiones prcticas, no se decidi hacer algo similar con
los decimales, que tambin mediante fraccionamiento y rearmado
podran tener tanta precisin como se quisiera. Esto se puede
hacer con el mdulo estndar decimal, que no veremos en el
curso.
Es decir, la computadora trabaja con nmeros decimales que se
expresan exactamente como suma de potencias de , y slo unos pocos
de ellos porque usa un nmero fjo de bits. As, si usamos bits
para representar los nmeros decimales, tendremos disponibles

, que parece mucho pero estamos lejos de poder representar


a todos los racionales!
Podramos representar a nmeros racionales de la forma ab
como un par (a, b) (como en el ejercicio . o el mdulo estndar
fractions que no vemos), pero de cualquier forma nos faltan los
irracionales, a los que slo podemos aproximar.
Peor, un mismo nmero tiene distintas representaciones y entonces
se representan menos de

nmeros. Por ejemplo, pensando en base


(y no en base ), podemos poner . = .

= .

=
.

, donde los exponentes son , y , y las mantisas son


., . y ., respectivamente.
Se hace necesario, entonces, establecer una forma de normalizar la
representacin para saber de qu estamos hablando. Cuando la parte
entera de la mantisa tiene (exactamente) una cifra no nula, decimos
que la representacin es normal, por ejemplo .

est en forma
to.t. La codfcacn de decmales Pg. t8y
1 2 4 8 16
Figura .: Esquema de la densidad variable en la codifcacin de
nmeros decimales.
normal, pero no .

ni ..
No es que slo nmeros grandes o irracionales no se puedan re-
presentar, como vemos en el siguiente ejercicio.
Ejercicio .. Decimos que x, < x < , puede representarse como
suma fnita de potencias de si podemos encontrar a Ny n Ntales
que
x = a
n
=
a

n
.
Por ejemplo, . se puede representar de esta forma pues . =

.
a) Ver que ., . y . no pueden ponerse como sumas fnitas
de potencias de . En particular, no pueden representarse exac-
tamente como decimales (float) en Python.
b) Como las representaciones no son exactas, hay errores en las
asignaciones a = 0.1, b = 0.2 y c = 0.7.
Efectivamente, ver que a + b + c y b + c + a dan valores
distintos, si bien muy parecidos. e
La representacin de nmeros decimales mediante mantisa y ex-
ponente hace que a diferencia de lo que sucede con los nmeros
enteros la distancia entre un nmero decimal que se puede represen-
tar y el prximo vaya aumentando a medida que sus valores absolutos
aumentan, propiedad que llamamos de densidad variable.
En matemticas no hay un nmero real (en R) que sea el siguiente
de otro.
Para entender la densidad variable, puede pensarse que hay la
misma cantidadde nmeros decimales representados entre (inclusive)
y (exclusive) que entre y , o que entre y , etc. (las sucesivas
Pg. t8o Cap|rulo to. Clculo numrco elemenral
potencias de ). Por ejemplo, si hubieran slo nmeros en cada uno
de estos intervalos, tendramos un grfco como el de la fgura ..
Por el contrario, hay tantos nmeros enteros representados entre
(inclusive) y (exclusive), como entre y , etc. Es decir, entre
y hay el doble de nmeros enteros representados que entre y
. En este caso, la densidad es constante.
Ejercicio .. Trabajando con nmeros (en R) en matemticas, nun-
ca puede ser a + = a. La mquina piensa las cosas en forma distinta,
y nuestro primer objetivo ser encontrar una potencia de , a, tal que
a == 1 + a.
Ponemos:
a = 1.0 # y no a = 1 !!!
while 1 + a > a:
a = 2
*
a
a
Si en vez de a = 1.0 ponemos a = 1 inicialmente, tendre-
mos un lazo infnito (por que?).
a) Encontrar n tal que el valor de a es
n
de dos formas: usando
logaritmos y poniendo un contador en el lazo while.
b) Ver que el valor de a es efectivamente a + 1 pero distinto de a
- 1: a - 1 es el mayor decimal en Python tal que sumndole
da un nmero distinto.
c) Calcular a + i para i entre y (inclusive). Son razonables
los resultados? e
Ejercicio . (
mq
). Esencialmente dividiendo por a > la desigual-
dad a + > a en el ejercicio anterior podemos hacer:
b = 1.0
while 1 + b > 1:
b = b / 2
b = 2
*
b # nos pasamos: volver para atrs
to.t. La codfcacn de decmales Pg. t8,
Ahora no importa si ponemos b = 1 o b = 1.0 pues la divisin
por dar un nmero decimal (float).
b es el epsilon de maquina, que indicamos por
mq
, al que podemos
interpretar de varias formas equivalentes:

mq
es la menor potencia (negativa) de que sumada a da
mayor que ,
+
mq
es el nmero que sigue a (para Python),

mq
es la distancia entre nmeros en el intervalo |, | (segn
comentamos al hablar de la densidad variable).
Desde ya que:
Como mencionamos, en matemticas no hay un nmero real que
sea el siguiente de otro. La existencia de
mq
refeja limitaciones
de la computadora que no puede representar todos los nmeros.
El valor de
mq
vara entre computadoras, sistemas operativos y
lenguajes.
a) La funcin epsilon (en el mdulo decimales) es una variante
de la expresin anterior, toma como argumento el valor inic,
que suponemos positivo, y retorna el menor x positivo tal que
inic + x > inic.
()
Ponemos epsmaq = epsilon(1.0) (el b
anterior), o en notacin matemtica,
mq
.
La funcin epsilon nos ayudar a entender la densidad
variable:
i) Comparar los valores de epsilon con argumentos , +
, + , . . . ,

, y luego con argumentos , , +


, . . . ,

.
Sugerencia: hacer listas por comprensin (observar tam-
bin que = , = ( + ),...,
j
= (

j
),...).
()
Suponemos tambin que inic + 1 > inic.
Pg. t88 Cap|rulo to. Clculo numrco elemenral
ii) Suponiendo que el valor de epsilon(x) se mantiene cons-
tante para x en el intervalo I
k
= |
k
,
k
) para k N, ver
que la cantidad de nmeros que se pueden representar en
I
k
es independiente de k y luego calcular esa cantidad.
iii) Evaluar 2
**
k / epsilon(2
**
k) para k = , . . . , , y ver
que es una potencia de (cul?). Cmo se relacionan
estas cantidades con lo hecho en el apartado anterior?
b) Al principio del ejercicio dijimos que bsicamente calculba-
mos 1/a, donde a es el valor calculado en el ejercicio .. Es
cierto que epsmaq es aproximadamente 1/a?, qu relacin hay
entre estos nmeros y
mq
?
Sugerencia: multiplicar a y epsmaq. e
Ejercicio . (
mn
). Otro indicador importante es
mn
, el epsilon
mnimo, que es el menor nmero decimal positivo que se puede repre-
sentar.
Podemos pensar que para la computadora
mn
es el decimal que
sigue a .
Decir por qu falla el esquema de ejercicios anteriores:
c = 1.0
while c > 0:
c = c / 2
c = 2
*
c # nos pasamos: volver al anterior
En el mdulo decimales construimos epsmin eliminando el pro-
blema al conservar el ltimo valor no nulo: comprobar que su compor-
tamiento es correcto. e
Ejercicio . (nmeros grandes). Tratemos de encontrar la mayor
potencia de que se puede representar en Python como nmero deci-
mal.
a) Recordando lo hecho en el ejercicio ., ponemos
a = 876
**
123 # no hay problemas con enteros
to.t. La codfcacn de decmales Pg. t8
float(a) # da error
876.0
**
123 # da error
obteniendo errores de overfow (desborde o exceso), es decir,
que Python no ha podido hacer la operacin pues se trata de
nmeros decimales grandes.
Ya hemos visto (ejercicios ., . o .) que a tiene cifras
en base .
b) Haciendo un procedimiento similar a los que vimos en los
ejercicios anteriores, y esperando tener un error (como en el
apartado a)) o que no termine nunca, cruzando los dedos po-
nemos:
x = 1.0
while 2
*
x > x:
x = 2
*
x
x
Como en el ejercicio ., es crucial poner x = 1.0 y no x =
1.
Cuando Python encuentra un numero decimal muy
grande que no puede representar o bien da overfow
(como vimos antes) o bien lo indica con inf por infnito,
pero hay que tener cuidado que no es el infnito que
conocemos.
c) Usando la tcnica para calcular
mn
, en el mdulo decimales
construimos el nmero maxpot2, la mxima potencia de que
se puede representar.
Encontrar n tal que maxpot2 es aproximadamente 2
**
n.
d) En analoga con el ejercicio ..b), averiguar la relacin entre
epsmin y maxpot2.
e) Usando el valor de n obtenido en c), ver que poniendo
y = 2
**
(n + 1) - 1
no hay error porque es un nmero entero.
Pg. to Cap|rulo to. Clculo numrco elemenral
Por la forma en que trabaja Python, float(y) puede dar error
an cuando se puede representar como suma de potencias de
hasta n (y =

n
k=

k
=
n+
).
Poniendo x = maxpot2, y considerando desde las matem-
ticas los valores de n y y, tendramos (usando que n > ),
x =
n
< y =
n+
<
n+
= x
<
n+
+ (
n+
) =
n+
= y,
pero Python piensa distinto:
2
*
x # -> inf
x < y # -> verdadero
y < 2
*
x # -> verdadero
2
*
x < 2
*
y # -> falso
2
*
x > 2
*
y # -> verdadero
f ) inf no es unnmero que podemos asignar directamente (como
lo son 2 o math.pi), para obtenerlo podemos pasar una cadena
a decimal:
a = inf # -> error
a = float(infinity) # o float(inf)
b = 2
*
x # -> inf
a == b # -> verdadero
En conclusin:
Python a veces da el valor inf cuando hace calculos con
decimales, pero solo numeros no demasiado grandes se deben
comparar con inf. e
Ejercicio .. Recordando lo expresado al principio y como repaso
de lo visto, para cada caso encontrar decimales x, y y z tales que los
siguientes den verdadero:
a) x + y == x con y positivo.
b) (x + y) + z != x + (y + z).
c) x + y + z != y + z + x. e
to.z. Errores numrcos Pg. tt
.. Errores numricos
Con la experiencia de la seccin anterior, tenemos que ser cuidado-
sos con los algoritmos, sobre todo cuando comparamos por igualdad
nmeros decimales parecidos.
En el ejercicio . vimos que podemos tener a + b + c b + c + a,
pero en ese caso los resultados eran parecidos. En los prximos ejerci-
cios vemos cmo estos pequeos errores pueden llevar a conclusiones
desastrosas.
Ejercicio . (de vuelta con Euclides). En el mdulo euclides2 vol-
vemos a considerar el algoritmo de Euclides, ahora con un lazo for
del cual salimos eventualmente con break.
Similares a las versiones que vimos en el captulo (ejercicios .
y .), mcd1 calcula el mximo comn divisor usando restas sucesivas
y terminando cuando a y b son iguales, mientras que mcd2 usa restos y
termina cuando b se anula.
a) Estudiar las funciones mcd1 y mcd2, y ver que se obtienen resul-
tados esperados con los argumentos 315 y 216.
b) En principio no habra problemas en considerar como argu-
mentos 3.15 y 2.16 para mcd1 y mcd2: los resultados deberan
ser como los anteriores slo que divididos por (es decir,
.).
Ver que esto no es cierto: para mcd1 se alcanza el mximo
nmero de iteraciones () y los valores fnales de a y b son
muy distintos (y queremos que sean iguales), mientras que
para mcd2 los valores fnales de a y b son demasiado pequeos
comparados con la solucin ..
Explorar las causas de los problemas, por ejemplo impri-
miendo los primeros valores de a y b en cada funcin.
c) En las funciones mcd3 y mcd4 evitamos las comparaciones di-
rectas, incorporando una tolerancia o error permitido. Ver que
estas funciones dan resultados razonables para las entradas
Pg. tz Cap|rulo to. Clculo numrco elemenral
anteriores. e
Llegamos a una regla de oro en clculo numrico:
^unca deben compararse numeros decimales por
igualdad sino por diferencias sufcientemente
pequeas.

Para calcular
mq
,
mn
y otros nmeros de la seccin . justa-
mente violamos esta regla: queramos ver hasta dnde se puede
llegar (y nos topamos con incoherencias).
Exactamente qu tolerancia usar en cada caso es complicado, y es-
t relacionado conlas diferencias conceptuales entre error absoluto
y relativo, (a su vez relacionados con
mn
y
mq
, respectivamen-
te). Estas diferencias se estudian en cursos de estadstica, fsica o
anlisis numrico, y no lo haremos ac.
Nos contentaremos con poner una tolerancia razonable, ge-
neralmente del orden de

mq
.
Ejercicio . (problemas con la ecuacin cuadrtica). Como sabe-
mos, la ecuacin cuadrtica
ax

+ bx + c = (.)
donde a, b, c R son datos con a , tiene soluciones reales si
d = b

ac
no es negativo, y estn dadas por
x

=
b +

d
a
y x

=
b

d
a
. (.)
a) Defnir una funcin que, dados a, b y c, verifque si a y
d , poniendo un aviso en caso contrario, y en caso afrmativo
calcule x

y x

usando las ecuaciones (.), y tambin ax

i
+
bx
i
+ c, i = , , viendo cun cerca estn de .
to.. Mrodos rerarvos: punros fjos Pg. t
b) Cuando d b

, es decir, cuando ac b

, pueden surgir
inconvenientes numricos. Por ejemplo, calcular las races usan-
do la funcin del apartado anterior, cuando a = , b =

y
c = , verifcando si se satisface la ecuacin (.) en cada ca-
so. e
.. Mtodos iterativos: puntos fjos
Una de las herramientas ms poderosas en matemticas, tanto para
aplicaciones tericas como prcticas en este caso gracias a la capa-
cidad de repeticin de la computadora son los mtodos iterativos.
Casi todas las funciones matemticas no elementales como cos, sen,
log, etc., son calculadas por la computadora mediante estos mtodos.
Pero, qu es iterar?: repetir una serie de pasos. Por ejemplo, mu-
chas calculadoras elementales pueden calcular la raz cuadrada del
nmero que aparece en el visor. En una calculadora con esta posibili-
dad, ingresando cualquier nmero (positivo), y apretando varias veces
la tecla de raz cuadrada puede observarse que rpidamente el resul-
tado se aproxima o converge al mismo nmero, independientemente
del valor ingresado inicialmente.
Hagamos este trabajo en la computadora.
Ejercicio . (punto fjo de la raz cuadrada).
a) Utilizando la construccin
y = x
for i in range(n):
y = math.sqrt(y)
defnir una funcin que tomando como argumentos x positivo
y n natural, calcule
_

x
---
n races
(= x

n
),
Pg. t{ Cap|rulo to. Clculo numrco elemenral
imprimiendo los resultados intermedios.
b) Ejecutar la funcin para distintos valores de x positivo, y n ms
o menos grande dependiendo de x. Qu se observa? e
En el ejercicio anterior vemos que a medida que aumentamos el
nmero de iteraciones (el valor de n) nos aproximamos cada vez ms
a 1. Por supuesto que si empezamos con x = 1, obtendremos siempre
el mismo como resultado, ya que

= .
Cuando un punto x en el dominio de la funcin f es tal que
f (x) = x,
decimos que x es un punto fjo de f , de modo que es un punto fjo de
la funcin f (x) =

x.
Visualmente se pueden determinar los puntos fjos como los de la
interseccin del grfco de la funcin con la diagonal y = x, como se
ilustra en la fgura . (izquierda) cuando f (x) = cos x.
Ejercicio .. Haciendo un grfco combinado de f (x) =

x y de
y = x para x con el mdulo gracar, encontrar otro punto fjo
de f (distinto de ). e
Ejercicio .. Repetir los ejercicios anteriores considerando f (x) =
x

en vez de f =

x. Cules son los puntos fjos?, qu pasa cuando
aplicamos repetidas veces f comenzando desde x = , ., o ? e
En lo que resta de la seccin trabajaremos con funciones continuas,
intuitivamente funciones que pueden dibujarse sin levantar el lpiz
del papel. Ejemplos de funciones continuas son: cualquier polinomio,
x, cos x, y

x (para x ).
Suponemos conocidas las defniciones de funcin continua y de
funcin derivable, que generalmente se da en los cursos de anlisis
o clculo matemtico.
Desde ya que hay funciones continuas que no se pueden dibujar:
x para x > , pues cerca de x = se nos acaba el papel,
to.. Mrodos rerarvos: punros fjos Pg. ty
senx para x > , pues cerca de x = oscila demasiado,

f (x) =
:

'
x senx si x ,
si x =
pues cerca de x = oscila demasiado,
y hay funciones que no son continuas como
signo(x) para x R, pues pega un salto en x = ,
la funcin de Dirichlet
f (x) =
:

'
si x Q,
si x R Q,
que es imposible de visualizar.
Muchas funciones de importancia terica y prctica tienen puntos
fjos con propiedades similares a la raz cuadrada y .
Supongamos que x

es un punto dado o inicial y defnimos


x

= f (x

), x

= f (x

), . . . , x
n
= f (x
n
), . . .
y supongamos que tenemos la suerte que x
n
se aproxima o converge al
nmero a medida que n crece, es decir,
x
n
cuando n es muy grande.
Puede demostrarse entonces que, si f es continua, es un punto fjo
de f .
Por ejemplo, supongamos que queremos encontrar x tal que cos x =
x. Mirando el grfco a la izquierda en la fgura ., vemos que efecti-
vamente hay un punto fjo de f (x) = cos x, y podemos apreciar que el
punto buscado est entre . y .
Probando la tcnica mencionada, dado x

R defnimos
x
n+
= cos x
n
para n = , , , . . .,
y tratamos de ver si x
n
se aproxima a algn punto cuando n crece. A
la derecha en la fgura . vemos cmo a partir de x

= , nos vamos
Pg. to Cap|rulo to. Clculo numrco elemenral
x
0.00 0.30 0.60 0.90 1.20
y
0.00
0.60
1.20
Punto fijo de cos(x)
cos(x)
identidad
x
0.00 0.30 0.60 0.90 1.20
y
0.00
0.60
1.20
Punto fijo de cos(x)
cos(x)
identidad
inicial
raz
Figura .: Grfco de cos x y x (izquierda) y convergencia a punto
fjo desde x

= (derecha).
aproximando al punto fjo, donde los trazos horizontales van desde
puntos en el grfco de f a la diagonal y = x y los verticales vuelven al
grfco de f .
Ejercicio . (punto fjo de f (x) = cos x). Con las notaciones ante-
riores para f (x) = cos x y x
i
:
a) Usando un lazo for, construir una funcin que dados x

y n
calcule x
n
, y observar el comportamiento para distintos valores
de x

y n.
b) Modifcar la funcin para que tambin imprima cos x
n
y com-
probar que para n ms o menos grande se tiene x
n
cos x
n
.
c) Modifcar la funcin para hacer iteraciones, mostrando
los resultados intermedios cada . Observar que despus de
cierta cantidad de iteraciones, los valores de x
k
no varan.
x

es una buena aproximacin al nico punto fjo de f (x) =


cos x, an cuando puede ser que x

cos x

(= x

) debi-
do a errores numricos.
En realidad, las espirales cuadradas indican que los valores
tericos de x
n
oscilan alrededor de la solucin, y si trabajra-
mos con aritmtica exacta, nunca obtendramos la solucin.
to.. Mrodos rerarvos: punros fjos Pg. t,
Tambin es muy posible que la solucin a cos x = x sea un
nmero que no se puede representar en la computadora, por
ejemplo si es irracional.
d) Modifcar la funcin de modo de no hacer ms iteraciones si
x
k+
x
k
< ,
donde > es un nuevo argumento (e. g., = . =

),
an cuando k sea menor que n.
Sugerencia: usar break en algn lugar adecuado.
Observar que la condicin x
k+
x
k
< es equivalente a
f (x
k
) x
k
< . e
Ejercicio .. La funcin puntofijo (en el mdulo numerico) sin-
tetiza lo hecho en el ejercicio .: retorna un cero de la funcin con
una tolerancia permitida en un nmero mximo de iteraciones.
a) Modifcar la funcin de modo de que el nmero de iteraciones
mximas y la tolerancia sean argumentos.
b) Modifcar la funcin de modo de siempre imprimir la cantidad
de iteraciones realizadas y el error obtenido. e
Cuando usamos un mtodo iterativo para obtener una solucin
aproximada (como en el caso de las iteraciones de punto fjo), es tradi-
cional considerar tres criterios de parada , saliendo del lazo cuando se
cumple algunas de las siguientes condiciones:
la diferencia en x es sufcientemente pequea, es decir, x
n+

x
n
<
x
,
la diferencia en y es sufcientemente pequea, es decir, f (x
n+
)
f (x
n
) <
y
, o, en el caso de bsqueda de ceros, si f (x
n
) <
y
,
se ha llegado a un nmero mximo de iteraciones, es decir, n =
n
mx
,
donde
x
,
y
y n
mx
son datos, ya sea como argumentos en la funcin
o determinados en ella. En la funcin puntofijo consideramos dos
Pg. t8 Cap|rulo to. Clculo numrco elemenral
de ellos (el segundo es casi equivalente al primero en este caso), pero
en general los tres criterios son diferentes entre s.
Ejercicio .. La fgura . fue hecha con el mdulo grpuntojo,
que grafca la funcin y los puntos que se obtienen a partir del mtodo.
Ejecutarlo y comprobar que se obtienen resultados similares a la fgura
mencionada.
grpuntojo es una plantilla para explorar el comportamiento de
distintas funciones cambiando algunos parmetros. Usa los m-
dulos gracar y grnumerico que usaremos como cajas negras.
Usar grpuntojo para ilustrar el mtodo de punto fjo:
a) Para la funcin

x en el intervalo |, | con los puntos iniciales


, ., y .
b) Para la funcin x

, con el mismo intervalo y puntos iniciales. e


La importancia de los puntos fjos es que al encontrarlos estamos
resolviendo la ecuacin f (x)x = . As, si nos dan la funcin g y nos
piden encontrar una raz de la ecuacin g(x) = , podemos defnir
f (x) = g(x) +x o f (x) = x g(x) y tratar de encontrar un punto fjo
para f .
Por ejemplo, es una raz de la ecuacin tan x = , y para obtener
un valor aproximado de podemos tomar g(x) = tan x, f (x) = x
tan x, y usar la tcnica anterior.
Ejercicio .. Resolver los siguientes apartados con la ayuda del
mdulo grpuntojo para ver qu est sucediendo en cada caso.
a) Encontrar (sin la compu) los puntos fjos de f (x) = x tan x,
es decir, los x para los que f (x) = x, en trminos de . Ver que
es uno de los infnitos puntos fjos.
b) Usando la funcin puntofijo, verifcar que con o iteracio-
nes se obtiene una muy buena aproximacin de comenzando
desde x

= .
c) Sin embargo, si empezamos desde x

= , nos aproximamos a
, otro punto fjo de f .
to.{. El mrodo de Newron Pg. t
d) f () no est defnida, y es previsible encontrar problemas
cerca de este punto. Como ., hacer una tabla de los
valores obtenidos despus de iteraciones, comenzando desde
los puntos ., ., . . . , . (desde . hasta . en incrementos
de .) para verifcar el comportamiento.
e) Si en vez de usar f (x) = x tan x usramos f (x) = x + tan x,
los resultados del apartado a) no varan. Hacer los apartados b)
y c) con esta variante y verifcar si se obtienen resultados simi-
lares. e
Ejercicio .. Puede suceder que las iteraciones tengan un compor-
tamiento cclico, por ejemplo al tomar f (x) = x

y x

= , y tambin
las iteraciones pueden dispararse al infnito, por ejemplo si toma-
mos f (x) = x

y x

> , o hacerlo en forma oscilatoria, como con


f (x) = x

y x

> .
Usando el mdulo grpuntojo, hacer un grfco de tres o cuatro
iteraciones en los casos mencionados para verifcar el comportamien-
to. e
Recordar entonces que:
Un metodo iterativo puede no converger a una
solucion, o converger pero no a la solucion
esperada.
.. El mtodo de Newton
La tcnica de punto fjo para encontrar races de ecuaciones no
surgi con las computadoras. Por ejemplo, el metodo babilonico es una
tcnica usada por los babilonios hace miles de aos para aproximar a
la raz cuadrada, y resulta ser un caso particular de otro para funciones
mucho ms generales que estudiamos en esta seccin.
Pg. zoo Cap|rulo to. Clculo numrco elemenral
Recordemos que la derivada de f en x, f

(x), se defne como


f

(x) = lm
h
f (x + h) f (x)
h
,
es decir,
f

(x)
f (x + h) f (x)
h
si h es sufcientemente chico. (.)
Si la derivada existe, o sea, si los cocientes incrementales se parecen
cada vez ms a algo a medida que h se hace ms y ms chico, decimos
que la funcin es derivable (en x), pero es posible que los cocientes no
se parezcan a nada.
Intuitivamente, f es derivable en x cuando podemos trazar la recta
tangente al grfco de la curva en el punto (x, f (x)). Como basta
dar la pendiente y un punto para defnir una recta, para determinar
la tangente en (x, f (x)) basta dar su pendiente, y sta es lo que se
denomina f

(x).
Supongamos ahora que f es una funcin derivable en todo punto,
y que x

es un cero de f . Si x es un punto prximo a x

, digamos
x

= x + h, despejando en la relacin (.), llegamos a


f (x + h) f (x) + f

(x) h,
y como h = x

x, queda
= f (x

) = f (x) + f

(x) (x

x).
Despejando ahora x

, suponiendo f

(x) , queda
x

x
f (x)
f

(x)
.
Esto establece un mtodo iterativo, el metodo de ^ewton, conside-
rando la sucesin
x
n+
= x
n

f (x
n
)
f

(x
n
)
para n = , , . . . , (.)
to.{. El mrodo de Newron Pg. zot
siempre que f

no se anule en los puntos x


n
.
Podemos interpretar la ecuacin (.) como diciendo que busca-
mos un punto fjo de la funcin
g(x) = x
f (x)
f

(x)
. (.)
Ejercicio . (mtodo babilnico). Supongamos que no sabemos
cmo calcular la raz cuadrada de un nmero y queremos encontrar

a para algn a positivo. Como decir que b =



a es (por defnicin)
lo mismo que decir que b

= a, tratamos de encontrar un cero de la


funcin f (x) = x

a.
a) Encontrar la funcin g dada en la ecuacin (.) si f (x) =
x

a.
Ayuda: f

(x) = x.
Respuesta: g(x) = (x + ax).
El mtodo babilnico para aproximar

a, consiste en calcular
sucesivamente las iteraciones
x
n
=

_x
n
+
a
x
n
_ para n = , , . . . , (.)
a partir de un valor inicial x

dado (x

> ). En otras palabras, x


n
=
g(x
n
), donde g es la funcin encontrada en a).
b) Defnir una funcin babilonico(a, it) implementando la
iteracin (.) a partir de x

= , haciendo it iteraciones.
c) Calcular babilonico(2, it) para it , , , y comparar
los resultados con math.sqrt(2).
d) Comparar los resultados de babilonico(a, 6) para a = y
a = .
Aproximar

es equivalente a aproximar

, slo hay
que correr en un lugar la coma decimal en la solucin, pero
en la funcin babilonico no lo tenemos en cuenta.
Pg. zoz Cap|rulo to. Clculo numrco elemenral
Es ms razonable considerar primero nicamente nmeros
en el intervalo |, ), encontrar la raz cuadrada all, y lue-
go escalar adecuadamente. Este proceso de normalizacion o
escalado es esencial en clculo numrico: trabajar con papas y
manzanas y no con tomos y planetas, o, ms cientfcamente,
con magnitudes del mismo orden.
Cuando se comparan papas con manzanas en la compu-
tadora, se tiene en cuenta el valor de
mq
, pero al trabajar
cerca del hay que considerar a
mn
. e
Difcilmente queramos encontrar ceros de una funcin tan sen-
cilla como x

a. La mayora de las veces las funciones sern ms


complejas, posiblemente involucrando funciones trascendentes (como
trigonomtricas o exponenciales) y los coefcientes no se conocern
con exactitud. De modo que en general no se implementa el mtodo de
Newton como expresado en (.), sino que se reemplaza la derivada
de la funcin por una aproximacin numrica, evitando el clculo de
una frmula de la derivada.
Para aproximar la derivada usamos
f

(x)
f (x + x) f (x x)
x
, (.)
donde x es una constante dada, ya que es mucha mejor aproximacin
que la dada en (.).
Podemos visualizar esta propiedad en la fgura .. La tangente a
la funcin es la recta en verde, y queremos calcular su pendiente que
es la derivada.
La recta que pasa por (x, f (x)) y (x +h, f (x +h)) est en marrn,
y la pendiente de esta recta es la aproximacin (.).
Encambio, la recta por (xh, f (xh)) y (x+h, f (x+h))
est en rojo, y su pendiente se parece mucho ms a la pendiente de la
recta verde.
Podemos justifcar matemticamente la propiedad usando el desa-
rrollo de Taylor. Tendremos:
f (x + h) = f (x) + f

(x) h + f

(x)h

+ O(h

),
to.{. El mrodo de Newron Pg. zo
x
y
Aproximando la tangente
x x + h/2 x - h/2 x + h
Figura .: Aproximando la pendiente de la recta tangente.
de modo que el error para calcular f

(x) en (.) es
f (x + h) f (x)
h
f

(x) = O(h),
mientras que el error en (.)
f (x + h) f (x h)
h
f

(x) = O(h

).
La idea de usar derivadas aproximadas se extiende tomando h
variable (ac lo tomamos fjo) dando lugar al metodo secante que
es muy usado en la prctica como alternativa al de Newton, y que
no veremos en el curso.
La funcin newton (en el mdulo numerico) toma dos argumentos,
la funcin f y el punto inicial x

, y en ella implementamos el mto-


do de Newton, aproximando internamente la derivada de la funcin
usando (.) con x =

.
La eleccin x =

es arbitraria, y podra ser mucho ms


grande o chica dependiendo del problema. Ver los comentarios
sobre errores absolutos y relativos en las notas de la pgina .
Pg. zo{ Cap|rulo to. Clculo numrco elemenral
x
-2.00 -0.50 1.00 2.50 4.00
y
-20.00
-5.00
10.00
Ilustracin del mtodo de Newton
f
y = 0
x
-2.00 -0.50 1.00 2.50 4.00
y
-20.00
-5.00
10.00
Ilustracin del mtodo de Newton
f
y = 0
inicial
raz
Figura .: Grfco de f en la ecuacin (.) (izquierda) y convergen-
cia del mtodo de Newton desde x

= . (derecha).
En la funcin newton no consideramos la posibilidad f

(x) = .
Ejercicio . (Newton con derivadas aproximadas). Tomemos
f (x) = (x + ) (x ) (x ), (.)
que tiene ceros en , y y se ilustra a la izquierda en la fgura ..
f tiene derivadas que no son difciles de calcular, pero de cualquier
manera usamos la funcin newton tomando como punto inicial .,
obteniendo las aproximaciones sucesivas que pueden observarse a la
derecha de la fgura .. Esta fgura fue hecha con el mdulo grnewton,
que es una plantilla para ilustrar el mtodo de Newton, anloga al
mdulo grpuntojo.
a) Ejecutar el mdulo grnewton, viendo que se obtienen resulta-
dos similares a los de la fgura.
b) Considerar otros puntos iniciales para obtener las otras dos
races ( y ). e
Ejercicio .. Resolver los siguientes apartados con la ayuda del
mdulo grnewton y la funcin newton:
a) Encontrar soluciones aproximadas de la ecuacin cos x =
tomando puntos iniciales . y ..
to.y. El mrodo de la bseccn Pg. zoy
b) Encontrar una solucin aproximada de cos x = x y comparar
con los resultados del ejercicio ..
c) Encontrar aproximadamente todas las soluciones de las ecua-
ciones:
i) x

x + = ii) x

x + = .
Resolver tambin estas ecuaciones en forma exacta y comparar
con los resultados obtenidos.
La primera ecuacin tiene races y la segunda .
Ayuda: para las soluciones exactas usar (.) en el primer
caso y en el segundo dividir primeramente por x , ya que
es solucin.
d) Obtener una solucin aproximada de cada una de las ecuacio-
nes
i) ln x = x, ii) x

sen x + = .
La primera ecuacin tiene una raz y la segunda infnitas. e
.. El mtodo de la biseccin
Supongamos que tenemos una funcin continua f defnida sobre el
intervalo |a, b| a valores reales, y que f (a) y f (b) tienen distinto signo,
como la funcin f grafcada en la fgura .. Cuando la dibujamos
con el lpiz desde el punto (a, f (a)) hasta (b, f (b)), vemos que en
algn momento cruzamos el eje x, y all encontramos una raz de f , es
decir, un valor de x tal que f (x) = .
En el metodo de la biseccion se comienza tomando a

= a y b

= b,
y para i = , , , . . . se va dividiendo sucesivamente en dos el interva-
lo |a
i
, b
i
| tomando el punto medio c
i
, y considerando como nuevo
intervalo |a
i+
, b
i+
| al intervalo |a
i
, c
i
| o |c
i
, b
i
|, manteniendo la pro-
piedad que en los extremos los signos de f son opuestos (que podemos
expresar como f (a
i
)f (b
i
) < ), como se ilustra en la fgura ..
Pg. zoo Cap|rulo to. Clculo numrco elemenral
a =a
0
b =b
0
=b
1
c
0
=a
1
=a
2
c
1
=b
2
c
2
Figura .: Funcin continua con distintos signos en los extremos.
En los cursos de anlisis o clculo se demuestra que si f es con-
tinua en |a, b|, y tiene signos distintos en a y b, entonces f se
anula en algn punto del intervalo. Una forma de demostrar esta
propiedad es con el mtodo de la biseccin usando la propiedad
de completitud de los reales.
Se fnaliza segn algn criterio de parada (como mencionados en
la pg. ), por ejemplo cuando se obtiene un valor de x tal que f (x)
es sufcientemente chico o se han realizado un mximo de iteraciones.
Recordando la flosofa de comparar papas con manzanas, el valor

y
a poner depender del problema que se trate de resolver.
Tambin en este sentido, observamos que

, por lo que el intervalo inicial se di-


vide aproximadamente en despus de iteraciones y en
=

despus de iteraciones. Es decir, despus de


iteraciones el intervalo mide menos del . % del intervalo ori-
ginal, y despus de iteraciones mide menos del . % del
intervalo original. No tiene mucho sentido considerar muchas
ms iteraciones en este mtodo, salvo que los datos originales y la
funcin f puedan calcularse con mucha precisin y el problema
amerite este clculo.
La funcin biseccion (en el mdulo numerico) utiliza el mtodo
de la biseccin para encontrar races de una funcin dados dos puntos
to.y. El mrodo de la bseccn Pg. zo,
en los que la funcin toma distintos signos.
Observemos la estructura de la funcin:
. Los extremos del intervalo inicial son poco y mucho.
. En la inicializacin, se calcula el valor de la funcin en el
extremo poco, fpoco. Si este valor es sufcientemente chico en
valor absoluto, ya tenemos la raz y salimos.
. Procedemos de la misma forma con el extremo mucho, obte-
niendo fmucho.
. Si la condicin de distinto signo en los extremos no se satisface
inicialmente, el mtodo no es aplicable y salimos poniendo un
cartel apropiado.
. Arreglamos los valores poco y mucho de modo que fpoco < .
. El lazo principal se realiza mientras no se haya encontrado
solucin:
Se calcula el punto medio del intervalo, medio, y el valor
fmedio de la funcin en medio.
Si la diferencia entre mucho y poco es sufcientemente chica,
damos a medio como raz.
Si el valor absoluto de fmedio es sufcientemente chico, tam-
bin damos a medio como raz.
Si no, calculamos un nuevo intervalo, cuidando de que los
signos en los extremos sean distintos.
. El lazo principal no puede ser infnito, pues vamos reduciendo
a la mitad el tamao del intervalo en cada iteracin.
Ejercicio . (mtodo de la biseccin). Consideremos la funcin
f (x) = x (x + ) (x + ) (x ),
que tiene ceros en x = , , , , como se ilustra en la fgura .
(izquierda). Usando el mtodo de la biseccin para esta funcin to-
mando como intervalo inicial |., .|, obtenemos una sucesin de
Pg. zo8 Cap|rulo to. Clculo numrco elemenral
x
-3.00 -1.75 -0.50 0.75 2.00
y
-3.00
1.00
5.00
Ilustracin del mtodo de la biseccin
f
y = 0
x
-3.00 -1.75 -0.50 0.75 2.00
y
-3.00
1.00
5.00
Ilustracin del mtodo de la biseccin
f
y = 0
intermedios
iniciales
raz
Figura .: Mtodo de biseccin (ejercicio .) funcin (izquierda)
y puntos obtenidos para el intervalo inicial |., .| (derecha).
intervalos dados por los puntos que se muestran en la misma fgura a
la derecha.
a) En caso de que haya ms de una raz en el intervalo inicial, la
solucin elegida depende de los datos iniciales. Verifcar este
comportamiento ejecutando biseccion sucesivamente con los
valores ., y . para mucho, pero tomando poco = 3 en todos
estos casos.
b) Por qu si ponemos poco = y mucho = obtenemos la raz
x = en una iteracin?
En general, nunca obtendremos el valor exacto de la raz:
recordar que para la computadora slo existen unos pocos
racionales.
c) En biseccion no verifcamos si poco < mucho, y podra suce-
der que poco > mucho. Tiene esto importancia?
d) Dividir la tolerancia en
x
y
y
(en vez de ), de modo de termi-
nar las iteraciones si mucho poco <
x
o si f (medio) <
y
.
e) Teniendo en cuenta lo expresado al principio de la seccin,
tendra sentido agregar un criterio de modo de parar si el
to.y. El mrodo de la bseccn Pg. zo
nmero de iteraciones es grande?
Si la cantidad mxima de iteraciones fuera n, cuntas itera-
ciones deben realizarse para alcanzarla, en trminos de
x
y los
valores originales de poco y mucho? e
El mtodo de la biseccin es bien general y permite encontrar las
races de muchas funciones. No es tan rpido como el de Newton,
pero para la convergencia de ste necesitamos que las derivadas per-
manezcan lejos de cero, que las derivadas segundas no sean demasiado
salvajes, y tomar un punto inicial adecuado.
Por supuesto que el mtodo de la biseccin y el de bsqueda binaria
(en la seccin .) son esencialmente la misma cosa. Si tenemos una
lista de nmeros no decreciente a

a
n
, uniendo los puntos
(k , a
k
) con (k, a
k
) para k = , . . . , n, tendremos el grfco de
una poligonal y en particular una funcin continua y aplicar el
mtodo de la biseccin a esta poligonal es equivalente a usar bsqueda
binaria, slo que consideramos nicamente valores enteros de x, y por
eso hacemos
medio =
poco + mucho

_,
terminando en cuanto la diferencia en x es , que se traduce como
mucho poco .
Ejercicio .. La fgura . se hizo con el mdulo grbiseccion, que
como los mdulos grpuntojo y grnewton es una plantilla, en
este caso para ilustrar el mtodo de la biseccin. Ejecutar el mdulo,
viendo que se obtienen resultados similares.
Con la ayuda de este mdulo y la funcin biseccion, usar el m-
todo de la biseccin para resolver los apartados del ejercicio ., y
comparar con las soluciones obtenidas all. e
Ejercicio . (inters sobre saldo). Maggie quiere comprar una
tablet y en un folleto de propaganda vio que poda comprar una por
Pg. zto Cap|rulo to. Clculo numrco elemenral
de contado o en cuotas mensuales de .. Si dispone de
los , le conviene comprarla en efectivo o en cuotas?
Para analizar el problema, primero veamos cul es la tasa de inters
(nominal anual) que cobra el negocio. Hay muchas formas de calcularla
y nos vamos a concentrar en el llamado interes sobre saldo que vimos
en la seccin ., y particularmente el ejercicio ..
Si pedimos prestada una cantidad c (en ) con un tasa de inters
anual (nominal) r (en ), que pagaremos en cuotas mensuales fjas de
p (en ) comenzando al fnal del primer mes, y que el prstamo tiene
las caracterstica de que el inters se considera sobre el saldo, esto es, si
b
m
es el saldo adeudado a fn del mes m, justo antes de pagar la cuota
m-sima, y c
m
es el saldo inmediatamente despues de pagar esa cuota,
poniendo t = + r( ), tendremos:
b

= tc, c

= b

p, b

= tc

, c

= b

p, . . .
y en general
c
m
= b
m
p = t c
m
p, (.)
donde inclusive podramos poner c

= c, constituyendo una variante


de las ecuaciones (.).
a) Considerando que c y r estn fjos, existe un valor de p de
modo que el saldo sea siempre el mismo, es decir, c
m+
= c
m
para m = , , , . . . ?, cul?
Respuesta: cuando el inters mensual es la cuota: cr.
b) Del mismo modo, encontrar una tasa crtica, r
crt
(c, p) (depen-
diendo slo de c y p), tal que la deuda se mantenga constante,
c
m+
= c
m
para m = , , , . . .
Respuesta: pc.
c) Defnir una funcin saldo(c, r, p, m) que dados el monto
inicial c, la tasa r, y el pago mensual p, calcule el saldo (la
deuda) inmediatamente despus de pagar la m-sima cuota, es
decir, c
m
= saldo(c, r, p, m) para m = , , , . . .
to.y. El mrodo de la bseccn Pg. ztt
r
40.00 80.00
s
-1000.00
0.00
1000.00
Saldo al cabo de 24 meses variando r
saldo
Figura .: Grfco de saldo(c, r, p, m) cuando r vara (c, p y m
constantes).
Aclaracion :: no se pide encontrar una frmula, slo traducir
a Python la ecuacin (.).
Aclaracion :: suponemos c > , r , p > y m .
En el ejercicio . encontramos una frmula explcita.
d) Usar la funcin saldo con c = (el precio de la oferta),
p = ., r = r
crt
calculado en b) para distintos valores de m.
e) Para c, r y p fjos, la funcin saldo(c, r, p, m) es decreciente
con m si p es mayor que el monto calculado en a) porque cada
vez se adeuda menos. Cmo es el comportamiento de saldo
cuando slo vara c?, y si slo vara r?
Respuesta: crecientes en ambos casos.
f ) Usando el mdulo gracar, hacer un grfco de la funcin
saldo cuando c = (lo que pagara Maggie hoy), p = .
(el pago mensual), m = (la cantidad de cuotas), variando r
entre y , confrmando lo visto en el apartado anterior. El
grfco debera ser similar al de la fgura ..
g) El grfco anterior muestra que la curva corta al eje r, y pode-
Pg. ztz Cap|rulo to. Clculo numrco elemenral
mos usar el mtodo de la biseccin.
Qu condiciones sobre c, p y m podramos pedir para usar
poco = 0 y mucho = rcrit, donde rcrit es la tasa crtica en-
contrada en el apartado b)?
Respuesta: podramos poner poco = 0 si p m c, y mucho
= rcrit siempre (suponiendo c > y p > ).
h) Defnir una funcin para resolver el apartado anterior en gene-
ral (para cualesquiera valores de c, p y m), usando el mtodo
de la biseccin y teniendo cuidado de elegir valores apropiados
de poco y mucho dentro de la funcin.
i) Calcular la tasa (anual nominal) que pagara Maggie si decide
comprar en cuotas.
Respuesta: . %.
j) Como dispone ahora de , Maggie podra poner ese di-
nero en certifcados a plazo fjo cada mes, extrayendo .
mensualmente para pagar la cuota.
Si el banco ofrece una tasa de % (nominal anual), cun-
tos meses podra pagar la cuota (sacando del certifcado del
banco)?
Respuesta: meses.
k) En el apartado anterior, qu tasa debera ofrecer el banco para
que pagar en cuotas fuera equivalente a hacer certifcados en
el banco?
Respuesta: la misma del apartado i).
l) Suponiendo que la tasa anual de infacin est entre % y
%, y que los bancos ofrecen una tasa no mayor al % en
certifcados a plazo fjo, debera Maggie hacer la compra en
efectivo o en cuotas haciendo certifcados a plazo fjo en el
banco?
En calculadoras fnancieras y planillas de clculo estn implemen-
tadas funciones similares. Por ejemplo, en MS-Excel estn las
funciones (donde p debe ser negativo si es un pago, r es la tasa y
m es la cantidad de cuotas):
to.y. El mrodo de la bseccn Pg. zt
AMORT(r, m, c): Calcula p dados m, r y c.
VALACT(r, m, p): Calcula c dados m, r y p.
TASA(m, p, c): Calcula r dados m, c y p.
NPER(r, p, c): Calcula m dados r, a y p.
Por ejemplo, en el problema original pondramos TASA(24,
-79.90, 1099)
*
1200 obteniendo .. e
Ejercicio .. En principio no podramos usar el mtodo de Newton
para resolver el ejercicio ., ya que no tenemos una frmula explcita
para la derivada correspondiente. Sin embargo, en el clculo efectivo
usamos una aproximacin a la derivada dada por la relacin (.), y
esa objecin desaparece.
En el ejercicio . vemos una frmula explcita. De cualquier
forma, el clculo de la derivada no es sencillo.
Resolver el ejercicio . usando el mtodo de Newton, tomando
como punto inicial un valor adecuado (por ejemplo, el promedio de
poco y mucho en ..g)) y comparar con los resultados obtenidos
mediante biseccin.
Sugerencia no muy elegante: para determinar r, usar c, p y m como
variables globales (fjas) al defnir la funcin.
Sugerencia mas elegante: defnir una funcin que englobe al mto-
do de Newton, algo como
def sol(c, p, m):
...
def saldo(r):
...
...
inic = ...
return numerico.newton(saldo, inic) e
Terminamos relacionando algunos conceptos que vimos.
Ejercicio . (inters sobre saldo II). En el ejercicio . usamos
la expresin (.) para expresar la deuda al principio del mes m, c
m
.
Pg. zt{ Cap|rulo to. Clculo numrco elemenral
a) Interpretando (.) como la aplicacin de la regla de Horner
para un polinomio evaluado en t, cules seran los coefcientes
del polinomio (de grado m)?
En otras palabras, la funcin saldo no hace ms que evaluar
un polinomio en t.
b) Recordando que t = +r, ver que si r > podemos poner
c
m
= ct
m
p
t
m

t
.
Sugerencia: recordar la suma de la progresin geomtrica,
n

k=
x
k
= (x
n+
)(x ) si x .
Si los pagos o los perodos no fueran uniformes, tendramos
que volver a la versin original. e
.. Ejercicios adicionales
Los polinomios sirven para aproximar tanto como se desee cual-
quier funcin continua, lo que constituye un tema central de las ma-
temticas. Suponemos conocidos los polinomios de Taylor, y en esta
seccin estudiaremos los polinomios interpoladores de Lagrange.
As, en la fgura . mostramos cmo aproximar a sen x mediante
desarrollos de Taylor de grados y alrededor de , y con el polino-
mio de Lagrange tomando los valores del seno en x = , , , .
Como se puede apreciar, cerca de x = se obtiene una muy buena
aproximacin en todos los casos.
k Los polinomios de Taylor usan la informacion de la funcion y sus
derivadas en un punto, y los de Lagrange usan la informacion de la
funcion en varios puntos. Una alternativa muy usada, sobre todo
en grafcos, son los splines, polinomios que utilizan informacion
sobre la funcion y sus derivadas en varios puntos.
to.o. Ejerccos adconales Pg. zty
x
0.00 0.79 1.57 2.36 3.14
y
-0.20
0.50
1.20
Polinomios aproximantes para sen x
sen
lagrange
taylor grado 3
taylor grado 5
puntos Lagrange
Figura .: Distintas aproximaciones a sen x mediante polinomios.
Ejercicio . (polinomios interpoladores de Lagrange). Un poli-
nomio P(x) como en la ecuacin (.), de grado a lo sumo n, est
determinado por los n + coefcientes. Supongamos que no conoce-
mos los coefcientes, pero podemos conocer los valores de P(x) en
algunos puntos, cuntos puntos necesitaremos para determinar los
coefcientes?
Como hay n + coefcientes, es natural pensar que quedarn deter-
minados por n + ecuaciones, es decir, bastarn n + puntos.
Una forma de resolver el problema es con el polinomio interpolador
de Lagrange: dados (x
i
, y
i
), i = , . . . , n + , defnimos:
P(x) =
n+

i=
y
i

ji
x x
j
x
i
x
j
. (.)
El polinomio en general resulta de grado n, y no necesariamente
n. Pensar, por ejemplo, en puntos sobre una recta: determinan
un polinomio de grado y no .
a) Ver que efectivamente, P(x) defnido por la ecuacin (.)
satisface P(x
i
) = y
i
para i = , . . . , n + .
b) Construir una funcin para evaluar el polinomio P(x) defnido
Pg. zto Cap|rulo to. Clculo numrco elemenral
en la ecuacin (.), donde los datos son (x
i
, y
i
), i n+,
y x.
Aclaracion: slo se pide una traduccin literal de la ecuacin.
c) Usarla para calcular el valor del polinomio de grado a lo sumo
que pasa por los puntos (, ), (, ), (, ), (, ), en el punto
x = .
d) Usarla para calcular una aproximacin de sen (=

)
usando los valores del seno para , , y .
Ver la fgura ..
e) Calcular aproximaciones a sen usando los polinomios de
Taylor de grados y alrededor de ,
T

(x) = x

!
x

, T

(x) = x

!
x

+

!
x

,
y comparar los resultados con el obtenido en el apartado ante-
rior.
k joseph-Louis Lagrange (:,o:8:) nacio en Turn (Italia) bajo el
nombre de Giuseppe Lodovico Lagrangia. Fue uno de los fundado-
res del calculo de variaciones y las probabilidades, e hizo numerosas
contribuciones en otras areas como astronoma y ecuaciones dife-
renciales.
Quienes hayan estudiado calculo reconocen su nombre por los
multiplicadores para encontrar extremos de funciones de varias
variables, y lo volveremos a encontrar en el ejercicio :,.. e
.. Comentarios
Apenas hemos araado el caparazn del clculo numrico.
Por un lado, hay mtodos mucho ms avanzados para resolver
los problemas presentados ac.
Por otro lado, hay temas como la resolucin de ecuaciones
diferenciales o la de sistemas lineales que no hemos tocado en
absoluto (estos temas merecen al menos uno o dos cursos desti-
nados exclusivamente a ellos).
to.,. Comenraros Pg. zt,
Figura .: Dos imgenes del fractal asociado a la convergencia del
mtodo de Newton para z

.
El mtodo de Newton o variantes se generaliza a varias variables
(reemplazando adecuadamente la derivada unidimensional), e
inclusive a variables complejas.
En cambio, es muy difcil generalizar el mtodo de la biseccin
a ms de una dimensin.
Los mtodos iterativos estn ntimamente relacionados con los
conjuntos fractales como el de la fgura ..
Para hacer estos grfcos usamos el mtodo de Newton tra-
tando de encontrar las races (complejas) del polinomio z

,
marcando con rojo (resp. azul o verde) los puntos que cuan-
do tomados como iniciales el mtodo converge hacia (resp.
i

).
A la izquierda de la fgura vemos el grfco en el cuadrado de
centro y lado , y a la derecha un detalle del cuadrado centrado
en . +. i (punto resaltado a la izquierda en blanco) y
lado ..
Observar que el grfco a la derecha es un zoom por un
factor de del grfco a la izquierda, lo que tambin indica
que no se trata de una cuestin de errores numricos sino que
Pg. zt8 Cap|rulo to. Clculo numrco elemenral
es una propiedad intrnseca.
Este es unejemplo extremo de lo expresado enel cartel sobre
cmo depende la solucin obtenida del punto inicial (pg. ).
Excepto la fgura ., todas las fguras en este captulo, incluso
la ., fueron hechas con el mdulo gracar.

Captulo
Nmeros enteros
En este captulo nos concentramos en la resolucin de problemas
de matemtica discreta relacionados con nmeros enteros.
.. Ecuaciones diofnticas y la tcnica de barrido
Comenzamos resolviendo ecuaciones donde las incgnitas son
nmeros enteros, y las tcnicas del captulo no pueden aplicarse.
El mximo comn divisor y el mnimo comn mltiplo de enteros
positivos a y b pueden pensarse como soluciones a ecuaciones en
enteros. Por ejemplo como vimos en el problema de Pablito y su
pap (ejercicio .) para el mcm queremos encontrar x e y enteros
positivos tales que ax = by. En general el problema tiene infnitas
soluciones (si el par (x, y) es solucin, tambin lo ser (kx, ky) para
k entero positivo), y buscamos el par ms chico.
Este tipo de ecuaciones algebraicas (polinmicas) con coefcientes
enteros donde slo interesan las soluciones enteras se llaman diofanti-
cas, en honor a Diofanto de Alejandra (aproximadamente )
quien fue el primero en estudiar sistemticamente problemas de ecua-
ciones con soluciones enteras, siendo autor del infuyente libro Aritme-
tica.
Pg. zzo Cap|rulo t,. Nmeros enreros
En esta seccin veremos varias de estas ecuaciones y su solucin
mediante la llamada tecnica de barrido.
()
Ejercicio .. Geri y Guille compraron botellas de vino para una
reunin. Ambos queran quedar bien y Guille gast por botella,
mientras que Geri, que es ms sibarita, gast por botella. Si entre
los dos gastaron , cuntas botellas compr cada uno?, cunto
gast cada uno?
a) Encontrar una solucin (con lpiz y papel).
Respuesta: hay tres soluciones posibles, en las que Geri y
Guille compraron (respectivamente) y , y , y botellas.
b) Defnir una funcin para resolver el problema.
Ayuda: indicando por x la cantidad que compr Geri, y por
y la cantidad que compr Guille, se trata de resolver la ecuacin
x + y = , con x, y Z, x, y . Por lo tanto, x

= . Usando un lazo for, recorrer los valores de x posibles,


x = , , . . . , , buscando y Z, y .
Debe descartarse un doble lazo for como en el esquema
for x in range(9): # 410 // 50 -> 8
for y in range(14): # 410 // 30 -> 13
if 50
*
x + 30
*
y == 410:
...
que es sumamente inefciente pues estamos haciendo =
pasos.
En cambio debe usarse (en este caso) un nico lazo, ya sea
for x in range(1 + 410 // 50):
y = (410 - 50
*
x) // 30
if 50
*
x + 30
*
y == 410:
...
(.)
que realiza pasos, o bien
for y in range(1 + 410 // 30):
()
Bah, a lo bestia!
t,.t. Ecuacones dofnrcas y la rcnca de barrdo Pg. zzt
x = (410 - 30
*
y) // 50
...
que realiza pasos.
En este caso es ms efciente el primero (pues hay menos
valores de x que de y), pero cualquiera de los dos esquemas
es aceptable.
Tambin podramos poner
for x in range(1 + 410 // 50):
y = int((410 - 50
*
x) / 30)
...
pero estaramos ignorando las ventajas de usar divisin entera
antes que la decimal ms una conversin.
c) Construir una funcin para resolver en general ecuaciones
de la forma ax + by = c, donde a, b, c N son dados por el
usuario y x, y son incgnitas enteras no negativas. La funcin
debe retornar todos los pares [x, y] de soluciones en una lista,
retornando la lista vaca si no hay soluciones.
Recordar los comentarios hechos sobre la efciencia. e
La estrategia de resolucin del ejercicio . es recorrer todas las
posibilidades, una por una, y por eso se llama de barrido. La ecuacin
que aparece en ese ejercicio, x + y = , es lineal, y como en el
caso del mximo comn divisor y el mnimo comn mltiplo, hay
tcnicas mucho ms efcientes para resolver este tipo de ecuaciones.
Estas tcnicas son variantes del algoritmo de Euclides (e igualmente
elementales), pero no las veremos en el curso.
La tcnica de barrido puede extenderse para barrer ms de dos
nmeros, como en el siguiente ejercicio.
Ejercicio .. En los partidos de rugby se consiguen tantos mediante
tries ( tantos cada try), tries convertidos ( tantos cada uno) y penales
convertidos ( tantos cada uno).
Defnir una funcin que ingresando la cantidad total de puntos
que obtuvo un equipo al fnal de un partido, imprima todas las formas
Pg. zzz Cap|rulo t,. Nmeros enreros
posibles de obtener ese resultado. Por ejemplo, si un equipo obtuvo
tantos, debera imprimirse algo como:
Posibilidad Tries Tries convertidos Penales
1 0 0 7
2 0 3 0
3 1 1 3
4 3 0 2
Teniendo en cuenta los comentarios sobre la efciencia hechos en
el ejercicio . (y en particular el esquema (.)), ac habr que
hacer dos lazos for pero no tres.
Se pretende hacer una tabla razonablemente prolija, usando print
con espacios adecuados. No se piden columnas alineadas (a dere-
cha, izquierda o centradas) como los de la seccin .. e
Tambin la tcnica de barrido puede usarse para resolver ecua-
ciones diofnticas no lineales.
Ejercicio .. Defnir una funcin que dado n N determine si exis-
ten enteros no-negativos x, y tales que x

+ y

= n, exhibiendo en
caso positivo un par de valores de x, y posibles, y en caso contrario
imprimiendo un cartel adecuado.
Teniendo en cuenta los comentarios del ejercicio . alrededor
del esquema (.), sin usar races cuadradas (o algn sustituto)
ac no podemos hacer mucho mejor que algo como:
for x in range(1, n + 1):
for y in range(1, n + 1):
if x
*
x + y
*
y == n:
...
si bien como estamos buscando una y no todas las soluciones
podramos considerar slo soluciones donde x y:
for x in range(1, n + 1):
for y in range(x, n + 1):
if x
*
x + y
*
y == n:
...
t,.z. Crbas Pg. zz
En fn, usando la raz cuadrada podramos poner
for x in range(1, 1 + math.sqrt(n)):
y = int(math.sqrt(n - x
**
2))
if x
*
x + y
*
y == n:
...
k Lagrange demostro en :,,o que todo entero positivo es suma de cua-
tro cuadrados (algunos eventualmente nulos), pero en :oo Fermat
haba demostrado que un entero positivo es suma de dos cuadrados
si y solo los factores primos impares de n que tienen resto al dividir-
los por aparecen a una potencia par. Por ejemplo, =

no puede escribirse como suma de cuadrados y =

s (e. g.,

). e
.. Cribas
Una criba (o cedazo o tamiz) es una seleccin de los elementos de
en una lista que satisfacen cierto criterio que depende de los elementos
precedentes, y en cierta forma es una variante de la tcnica de barrido.
Quizs la ms conocida de las cribas sea la atribuida a Eratstenes
para encontrar los nmeros primos entre y n (n N), donde el criterio
para decidir si un nmero k es primo o no es la divisibilidad por los
nmeros que le precedieron.
Como ya mencionamos (pg. ), para nosotros un nmero en-
tero p es primo si < p y sus nicos divisores positivos son y
p.
k Eratostenes (:,o a. C.: a. C.) fue el primero en medir con una
buena aproximacion la circunferencia de la Tierra. Y pensar que
Colon usaba un huevo :,oo aos despues!
Ejercicio . (criba de Eratstenes). Supongamos que queremos en-
contrar todos los primos menores o iguales que un dado n N. Recor-
dando que no es primo, empezamos con la lista
. . . n.
Pg. zz{ Cap|rulo t,. Nmeros enreros
Recuadramos , y tachamos los restantes mltiplos de de la lista,
que no pueden ser primos, quedando
. . .
Ahora miramos al primer nmero que no est marcado (no tiene
recuadro ni est tachado) y por lo tanto no es mltiplo de ningn
nmero menor: . Lo recuadramos, y tachamos de la lista todos los
mltiplos de que quedan sin marcar. La lista ahora es
. . .
y seguimos de esta forma, recuadrando y tachando mltiplos hasta
agotar la lista.
a) La funcin criba en el mdulo eratostenes es una implementa-
cin de esta idea, donde indicamos que un nmero est tachado
o no con el arreglo esprimo que tiene valores lgicos.
b) Una vez que i en el lazo principal supera a

n, no se modifcar
su condicin de ser primo o no.
Como ya observamos, si a b = m y

m < b < m, debe
ser < a <

m.
Por lo tanto, podemos reemplazar range(2, n + 1) en el
lazo principal por range(2, s + 1), donde s =

n.
Recordar que para a > , int(a) da por resultado a.
Tambin podemos cambiar el lazo en j por:
for j in range(i
*
i, n+1, i):
Hacer estos cambios, viendo que para n = , , se
obtienen los mismos resultados.
La criba de Eratstenes es muy efciente. La cantidad de pasos que
realiza es del ordende n log(log n) pasos, mientras que la cantidad
de primos que no superan n, (n), es del orden de n log n segn
el teorema de los nmeros primos (ver el ejercicio .). Es decir,
el trabajo que realiza la criba es prcticamente lineal con respecto
a la cantidad de elementos que encuentra. e
t,.z. Crbas Pg. zzy
Ejercicio .. En la crcel haba n celdas numeradas de a n, cada
una ocupada por un nico prisionero. Cada celda poda cambiarse de
abierta a cerrada o de cerrada a abierta dando media vuelta a una llave.
Para celebrar el Centenario de la Creacin de la Repblica, se resolvi
dar una amnista parcial. El Presidente envi un ofcial a la crcel con
la instruccin:
Para cada i = , , . . . , n, girar media vuelta la llave de las
celdas i, i, i, . . .
comenzando con todas las celdas cerradas. Un prisionero era liberado
si al fnal de este proceso su puerta estaba abierta. Qu prisioneros
fueron liberados?
Sugerencia: no pensar, hacer el programa!
k Se puede demostrar que se obtienen los cuadrados , , , . . . que
no superan n. e
Ejercicio . (el problema de Flavio Josefo I). Durante la rebelin
juda contra Roma (unos aos d. C.), judos quedaron atrapados
en una cueva. Prefriendo la muerte antes que la captura, decidieron
formar un crculo, matando cada de los que quedaran, hasta que
quedara uno solo, quien se suicidara. Conocemos esta historia por
Flavio Josefo (historiador famoso), quien siendo el ltimo de los sobre-
vivientes del crculo, no se suicid.
Desde las matemticas, nos interesa determinar la posicin en la
que debi colocarse Flavio Josefo dentro del crculo para quedar como
ltimo sobreviviente.
Para analizar el problema y en vez de ser tan crueles y matar
personas supondremos que tenemos inicialmente un crculo de n
jugadores, numerados de a n, y que sale del crculo el m-simo
comenzando a contar a partir del primero, recorriendo los crculos
cada vez ms reducidos siempre en el mismo sentido.
Por ejemplo si n = y m = , saldrn sucesivamente los jugadores
numerados , , , , quedando al fnal slo el nmero , como ilustra-
mos en la fgura . (con el sentido antihorario), donde los nmeros
Pg. zzo Cap|rulo t,. Nmeros enreros
1
2
3
4
5
2
4
1
5
3
Figura .: Esquema del problema de Flavio Josefo con n = y m = .
fuera del crculo indican en qu momento salieron: el n-simo jugador
que sale es el sobreviviente.
Podemos estudiar el problema implementando una criba, conside-
rando una lista salio, de longitud n + 1 (el ndice no se usar), de
modo que al terminar, salio[j] indicar la vuelta en la que sali el
jugador j.
Inicialmente podemos poner todas las entradas de salio en
para indicar que nadie sali, poniendo en la entrada en la posicin .
Quedara un esquema como el siguiente:
salio = [-1 for k in range(n+1)] # nadie sali
salio[0] = 0 # no usar esta posicin
s = n # seala posicin del que sale
for vuelta in range(1, n + 1): # n vueltas
cuenta = 0 # contamos m jugadores
while cuenta < m:
if s < n: # incrementar 1
s = s + 1
else: # empezar con 1
s = 1
if salio[s] < 0: # si no sali
cuenta = cuenta + 1 # contarlo
salio[s] = vuelta # la vuelta en que sali
(.)
t,.z. Crbas Pg. zz,
a) Construir una funcin josefo1 que toma como argumentos
a los enteros positivos n y m, y retorna la lista salio, indicada
anteriormente.
En el ejemplo con n = y m = , se debe retornar [0, 2, 4,
1, 5, 3].
b) La permutacion de Flavio josefo es el orden en que van saliendo,
incluyendo el que queda al fnal. Para n = y m = , el orden
es , , , , .
Modifcar la funcin del apartado anterior de modo que
retorne las tupla (salio, flavio), con flavio[0] = 0.
Es decir, para n = y m = se debe retornar ([0, 2, 4, 1,
5, 3], [0, 3, 1, 5, 2, 4]).
flavio es la permutacin inversa de salio: flavio[i] es j
salio[j] es i.
c) Qu posicin ocupaba en el crculo inicial Flavio Josefo (en la
versin original del problema)?
d) Cul es el sobreviviente si n = y m = ?
e) Modifcar la funcin de modo que tome los argumentos n, m y
s y responda cuntas vueltas sobrevivi la persona que estaba
inicialmente en el lugar s.
f ) Modifcar la funcin de modo de imprimir una tabla con la
posicin inicial y el orden de eliminacin, algo como
Posicin inicial Vuelta
1 2
2 4
3 1
4 5
5 3
cuando n = y m = . e
Ejercicio . (el problema de Flavio Josefo II). La criba segn el
esquema (.) es bastante inefciente:
Pg. zz8 Cap|rulo t,. Nmeros enreros
Cuando m es grande comparado con la cantidad de jugadores
que van quedando, estamos contando muchas veces el mismo
jugador (por ejemplo si n = y m = ).
Podramos mejorar esto considerando slo restos, es decir,
usando aritmtica modular con la funcin %.
Como los restos al dividir por k N estn entre y k , es
conveniente considerar los ndices de las listas a partir de .
Una vez que han salido varios jugadores, tenemos que pasar
muchas veces por el mismo jugador que ya no est para contar.
Lo mejor sera sacarlo efectivamente de la lista.
As, podramos considerar una lista quedan de los que... quedan!,
inicialmente con los valores , . . . , n (en vez de entre y n). A
medida que sacamos jugadores de quedan formamos las listas salio y
flavio de antes.
Tendramos algo como:
quedan = list(range(n)) # entre 0 y n-1
nq = n # la cantidad en quedan
salio = [-1 for x in range(n)]
flavio = []
s = -1
for vuelta in range(n): # n vueltas
s = (s + m) % nq
sale = quedan.pop(s)
nq = nq - 1 # queda uno menos
flavio.append(sale)
salio[sale] = vuelta
s = s - 1 # contar a partir de ac
Defnir una funcin con este esquema que tome como argumen-
tos m y n y que retorne la tupla (salio, flavio). En el caso n =
y m = , se debe retornar ([1, 3, 0, 4, 2], [2, 0, 4, 1, 3])
pues numeramos entre y n .
En mi mquina, el nuevo esquema es unas veces ms rpido que
t,.. Dvsbldad y nmeros prmos Pg. zz
el (.) para n = y m = . e
.. Divisibilidad y nmeros primos
Los nmeros primos son considerados como ladrillos para la cons-
truccin de los enteros, pero en ms de un sentido se sabe poco de
ellos.
Quizs sea justamente por la cantidad de preguntas sencillas que
no se han podido responder que estos nmeros han fascinado a los
matemticos desde poca remotas.
Por otra parte, con el auge de internet el estudio de los nmeros
primos dej de ser un juego de matemticos para convertirse en un
tema de aplicacin candente: la criptografa ha aprovechado la enorme
difcultad computacional que es determinar los factores primos de un
entero para, por ejemplo, enviar datos bancarios por internet.
En esta seccin veremos algoritmos elementales (e inefcientes!)
para el estudio y resolucin de algunas de estas preguntas.
Comenzamos con divisibilidad y la factorizacin de enteros.
Ejercicio . (divisores). En este ejercicio queremos defnir una fun-
cin divisores(n) que dado el nmero natural n encuentra la lista
de los divisores positivos de n, es decir los enteros m, m n tales
que m n. Por ejemplo:
>>> divisores(6)
[1, 2, 3, 6]
a) Una posibilidad es considerar un lazo for recorriendo todos
los enteros entre y n, viendo en cada caso si es divisor o no.
b) La anterior es bastante inefciente, pues podramos analizar
slo nmeros que no superan

n: si a, b N y ab = n enton-
ces a

n o b

n. Cambiar el lazo anterior usando esta
propiedad. e
Pg. zo Cap|rulo t,. Nmeros enreros
Ejercicio . (nmeros perfectos). Un nmero es perfecto si es suma
de sus divisores propios (menores que l). Por ejemplo, es perfecto
pues = + + .
Defnir una funcin esperfecto(n) que retorna verdadero o falso
segn si n es perfecto o no, y luego encontrar los nmeros perfectos
que no superan . e
Ejercicio .. No es difcil ver que el entero a > no es primo si y
slo si existen enteros b y c tales que a = b c y < b

a.
En base este resultado, defnir una funcin esprimo(n) que decide
si el nmero entero positivo n es primo o no.
^ota: la funcin no debera usar ms de

n pasos.
Ayuda: ver el ejercicio .. e
Ejercicio .. En este ejercicio queremos defnir una funcin que
dado n N lo descomponga en sus factores primos, contando la multi-
plicidad, retornando una lista de listas.
Por ejemplo:
>>> factores(20)
[[2, 2], [5, 1]]
>>> factores(21)
[[3, 1], [7, 1]]
a) Defnir una funcin verificar para verifcar los resultados
obtenidos. Por ejemplo:
>>> verificar([[3, 2], [3607, 1], [3803, 1]])
123456789
b) Defnir la funcin factores de dos formas distintas:
i) Usando la criba de Eratstenes, encontrando los primos
que no superan

n y que dividen a n.
ii) Usando un esquema del tipo:
...
factores = []
t,.. Dvsbldad y nmeros prmos Pg. zt
d = 2 # divisor posible
while True:
s = int(math.sqrt(n))
while ((n % d) != 0) and (d <= s):
d = d + 1
if (d > s): # ac n es 1 o es primo
if n > 1:
factores.append([n, 1])
break
# ac b divide a n y d <= s
m = 1 # la multiplicidad
n = n // d # n se modifica
while n % d == 0:
n = n // d
m = m + 1
factores.append([d, m])
...
Probar ambas versiones con distintas entradas, como , , ,
, , .
c) Cul de los dos mtodos te parece ms efciente (realiza menos
pasos)? e
Para muchos matemticos, el tesoro al fnal del arcoris es una
frmula para obtener todos los nmeros primos.
En los prximos ejercicios, no completamente resueltos desde la
teora, muestran algunas de las aproximaciones humanas a ese tesoro.
Uno de los primeros intento de frmula fue dada por Euclides:
Ejercicio . (primos de Euclides). Para demostrar que hay infni-
tos primos (en el libro IX de Los Elementos), Euclides supone que hay
un nmero fnito de ellos, digamos (p

, p

, . . . , p
n
), y considera el
nmero
x = p

p
n
+ , (.)
Pg. zz Cap|rulo t,. Nmeros enreros
de donde deduce que ninguno de los p
i
, i = , . . . , n divide a x, y por
lo tanto debe ser primo. Pero x > p
i
para todo i, por lo tanto llegamos
a un absurdo pues x no est en la lista de los fnitos primos.
Decimos que x es un primo de Euclides si es de la forma dada en
la ecuacin (.), donde p

, . . . , p
n
son los primeros n primos. Por
ejemplo, los primeros primos de Euclides son = + , = + y
= + .
Sin embargo, ni todos los primos son de esta forma (como ), ni
todos los nmeros de esta forma son primos. Por ejemplo
= + = .
Encontrar todos los nmeros menores que que son de la
forma (.) y que no son primos de Euclides.
k ^o se sabe si hay infnitos primos de Euclides. e
A falta de frmula, se ha intentado estudiar los primos como si
fueran al azar, mirando estadsticamente cmo se reparten los
primos en la recta.
Ejercicio . (distribucin de los nmeros primos).
a) El teorema de los numeros primos establece que, a medida que n
crece, el nmero de primos menores o iguales que n, indicado
por (n), se aproxima a n log n.
Comprobarlo usando la funcin criba con n =
k
con
k = , , .
Sugerencia: no es necesario usar criba para cada uno de estos
valores, bastar tomar el mayor n y luego fltrar adecuadamente.
La aproximacin es muy lenta: para n =

el cociente
(n)(n log n) es . aproximadamente.
b) Usando (o modifcando) la criba de Eratstenes, determinar
cuntos de los primos que no superan terminan res-
pectivamente en , , y .
t,.. Dvsbldad y nmeros prmos Pg. z
Observar que, al menos en el rango considerado, la distri-
bucin es muy pareja. Asintticamente son iguales, segn
los resultados de Mertens que mencionamos al fnal del este
captulo. e
A contrapelo del estudio estadstico que sugiere que los primos
estn a distancias regulares, el prximo problema muestra que podra
no ser as.
Ejercicio . (primos gemelos). Los primos p y q se dicen gemelos
si diferen en . Es claro que excepto y , la diferencia entre dos
primos consecutivos debe ser o ms. Los primeros primos gemelos
son los pares (, ), (, ) y (, ), y el par ms grande conocido
()
est formado por


,
(cada uno con cifras decimales), pero no se sabe si hay infnitos
pares de primos gemelos.
Hacer una funcin para encontrar todos los pares de primos geme-
los menores que n, y ver que hay pares de primos gemelos menores
que .
Si usamos listas con fltros, una primera posibilidad es usar un
fltro del tipo
[... p in criba(n - 2)
if p + 2 in criba(n - 2)]
()
Como no queremos calcular ms de una vez criba(n - 2),
mejor es hacer
primos = criba(n - 2)
[... p in primos if p + 2 in primos]
()
Esta ltima posibilidad tiene el inconveniente que recorremos
toda la lista para cada p, haciendo el algoritmo inefciente. Ms
razonable es mirar directamente a los ndices:
()
Julio de , http://primes.utm.edu/top20/page.php?id=1#records
Pg. z{ Cap|rulo t,. Nmeros enreros
p = criba(n - 2)
[... i in range(len(p) - 1)
if p[i + 1] == p[i] + 2]
()
Para n = , en mi mquina el ltimo esquema es el doble
de rpido que el esquema () y unas veces ms rpido que el
esquema (). Para n = en cambio, () es veces ms rpido
que () y veces ms rpido que (). e
Los nmeros primos surgen del intento de expresar un nmero
como producto de otros, pero podemos pensar en otras descomposi-
ciones. Por ejemplo, tomando sumas en vez de productos, como en el
siguiente ejercicio.
Ejercicio . (conjetura de Goldbach). La conjetura de Goldbach,
originada en la correspondencia entre Christian Goldbach y Euler en
, dice que todo nmero par mayor que puede escribirse como la
suma de dos nmeros primos impares (no necesariamente distintos).
a) Defnir una funcin que dado el nmero n par, n , lo des-
componga en suma de dos primos impares, exhibindolos (ve-
rifcando la conjetura) o en su defecto diga que no se puede
descomponer as.
b) Una variante de la conjetura, llamda conjetura debil de Goldbach,
es que todo nmero impar mayor a puede escribirse como
suma de tres primos impares. Defnir una funcin (que podra
usar la anterior) para verifcar que todo nmero n impar, n ,
puede escribirse como suma de tres primos impares.
Como se puede apreciar enel apartado b), la conjetura original
implica esta versin.
c) La cuenta de Goldbach es la cantidad de formas en las que
un nmero par puede escribirse como suma de dos primos
impares. Por ejemplo, = + = + , por lo que la cuenta
de Goldbach de es .
Hacer una funcin para determinar la cuenta de Goldbach
de un entero par mayor que , y luego encontrar el mximo y
t,.{. Ejerccos adconales Pg. zy
mnimo de la cuenta de Goldbach de todos los pares entre y
. e
.. Ejercicios adicionales
Ejercicio . (perodo de una fraccin). A diferencia de las cifras
enteras, que se van generando de derecha a izquierda por sucesivas di-
visiones (como en la funcin ifwhile.cifras), la parte decimal se va
generando de izquierda a derecha (tambin por divisiones sucesivas).
De la escuela recordamos que todo nmero racional pq ( < p <
q) tiene una expresin decimal peridica. Por ejemplo,
= . . . . = . tiene perodo ,
= . . . . = . tiene perodo y antepero-
do ,
= . = . . . . = . tiene perodo y anteperodo
,
hay nmeros como = . = . que tienen dos represen-
taciones, una con perodo y otra con perodo .
a) Construir una funcin periodo(p, q) que dados los enteros
positivos p y q imprima la parte decimal (del desarrollo en base
) de la fraccin pq, distinguiendo su perodo y anteperodo.
El comportamiento debe ser algo como:
>>> periodo(617, 4950)
Los decimales son: [1, 2, 4, 6]
El anteperodo es: [1, 2]
El perodo es: [4, 6]
Sugerencia: guardar los cocientes y restos sucesivos de la
divisin hasta que se repita un resto.
Sugerencia si la anterior no alcanza. en cuanto un resto se repi-
te, se repetir el cociente, as como todos los restos y cocientes
siguientes. Asociar cada resto r con el cociente c que produce
Pg. zo Cap|rulo t,. Nmeros enreros
al hacer la divisin r = c q + r

, donde r

es el nuevo
resto.
b) Defnir una funcin que dados el anteperodo y el perodo (co-
mo listas de nmeros) encuentre el numerador y denominador.
Es decir, encontrar bsicamente una inversa a la funcin del
apartado anterior.
c) Encontrar el entero n entre y tal que n tiene mxima
longitud del perodo.
Respuesta: , que tiene perodo de longitud .
d) Encontrar todos los enteros entre y para los cuales n
tiene perodo n . Son todos primos?, hay primos que no
cumplen esta condicin? e
Ejercicio . (La funcin de Euler). Para n N, la funcion de
Euler se defne como la cantidad de coprimos positivos menores que n,
es decir,
(n) = m N m n y mcd(m, n) = .
a) Probar que n N es primo (n) = n .
b) Defnir una funcin que dado n N calcule (n).
Sugerencia: Usar un fltro con el mximo comn divisor.
k Hay otros metodos mas efcientes para calcular basados en
propiedades que no veremos en el curso. Sin embargo, el calculo
de es tan difcil computacionalmente como la factorizacion
de enteros.
c) Calcular (n) para varios valores de n, y despus conjeturar y
demostrar para cules valores de n (n) es par.
Sugerencia para la demostracion: mcd(n, k) = mcd(n
k, n) = .
d) Un primo p tal que (p) es una potencia de se llama primo
de Fermat, y debe ser de la forma p =

k
+ .
t,.y. Comenraros Pg. z,
Los nicos primos de Fermat que se conocen son (k = ),
, , y (k = ). Ver que para k = , n =

k
+ no es
primo.
k Gauss demostro que se puede construir con regla y compas un
polgono regular de n lados si (n) es una potencia de , esto
es, si n es el producto de una potencia de y primos de Fermat.
Pierre Vantzel demostro en :8, que la condicion tambien es
necesaria. e
.. Comentarios
Entre las ecuaciones diofnticas no lineales ms interesantes es-
tn las de la forma x
n
+ y
n
= z
n
. Cuando n = , las soluciones
forman una terna pitagorica y estn completamente caracteri-
zadas. Para n > la ecuacin no tiene soluciones. Justamente
P. Fermat () escribi en el margen de su copia de la
Aritmtica de Diofanto (traducida por Bachet) sobre la impo-
sibilidad de resolucin cuando n > :
Encontre una demostracion verdaderamente destaca-
ble, pero el margen del libro es demasiado pequeo
para contenerla.
R. Taylor y A. Wiles demostraron el teorema en , casi
aos despus!
Como ya mencionamos, divisibilidad y nmeros primos han
dejado de ser temas exclusivamente tericos.
El problema ms acuciante es encontrar un algoritmo efcien-
te para factorizar enteros: quien lo encuentre puede hacer
colapsar al sistema bancario mundial!
Curiosamente, decidir si un nmero es primo o no es mu-
cho ms sencillo: en , M. Agrawal, N. Kayal y N. Saxena
probaron que existe un algoritmo muy efciente para este pro-
blema.
Pg. z8 Cap|rulo t,. Nmeros enreros
En el ejercicio . vimos mtodos para resolver estos pro-
blemas, que son extremadamente inefcientes para nmeros
grandes ( o ms cifras decimales).
La funcin de Euler que calculamos en el ejercicio . es
un herramienta fundamental en el algoritmo de criptografa
de R. Rivest, A. Shamir y L. Adleman (), uno de los ms
usados.
Por supuesto, lo que hacemos ac es muy elemental, lejos
de lo que se hace en la realidad. El ejercicio . da una idea
de cosas que se pueden hacer para mejorar la efciencia.
Si bien se sabe que hay infnitos primos desde Euclides, re-
cin hacia fnes del siglo XIX pudieron resolverse algunas
cuestiones muy generales sobre cmo se distribuyen.
El teorema de los numeros primos, mencionado en los ejer-
cicios . y ., fue conjeturado por Gauss hacia o ,
cuando tena unos aos, y fue demostrado en inde-
pendientemente por Jacques Hadamard () y Charles
Jean de la Valle-Poussin ().
Johann Peter Gustav Lejeune Dirichlet () demostr
en que toda progresin aritmtica a + bk, k = , , . . . ,
contiene infnitos primos si mcd(a, b) = . Este resultado
implica que hay infnitos primos que terminan en en su
expresin decimal, infnitos que terminan en , etc., pero no
dice cmo es la distribucin.
El problema fue estudiado en forma ms general por Franz
Carl Joseph Mertens (), quien refn los resultados
de Dirichlet. En particular, sus resultados implican que hay
tantos primos que terminan en como en , o , como
sugiere el ejercicio ..b)
Un poco como contrapartida al teorema de Dirichlet, Ben
Green y Terence Tao demostraron en que los nmeros
primos contienen progresiones aritmticas arbitrariamente
largas.
t,.y. Comenraros Pg. z
Hay muchas preguntas an sin responder: no se sabe si hay
infnitos primos de Euclides (ejercicio .), o si hay infnitos
primos gemelos (ejercicio .), o si la conjetura de Goldbach
es cierta (ejercicio .).
Estos son temas de intenso estudio actual, y constantemente
aparecen resultados.
Por ejemplo, si bien la conjetura de Goldbach no se ha
demostrado, en mayo de H. Helfgott, demostr la versin
dbil (ejercicio ..b)).
Los ejercicios . y . estn tomado de Engel ().

Captulo
Grafos
Muchas situaciones pueden describirse por medio de un diagrama
en el que dibujamos puntos y segmentos que unen algunos de esos
puntos. Por ejemplo, los puntos puede representar gente y los segmen-
tos unir a pares de amigos, o los puntos pueden representar centros
de comunicacin y los segmentos enlaces, o los puntos representar
ciudades y los segmentos las carreteras que los unen.
La idea subyacente es la de grafo, un conjunto de vertices (gente,
centros o ciudades) y un conjunto de aristas (relaciones, enlaces o
calles).
.. Ensalada de defniciones
Comenzamos presentando una ensalada de conceptos, defni-
ciones y notaciones, muchos de los cuales pueden no ser familiares o
diferir con las de otros autores. La idea es leer esta seccin sin tratar de
memorizar las defniciones, y volver a ella cuando se use algn trmino
de teora de grafos que no se recuerde.
El conjunto de vrtices se indica por V y el de aristas por E. Si
llamamos al grafo G, normalmente pondremos G = (V, E).
t8.t. Ensalada de defncones Pg. z{t
A fn de distinguir los vrtices entre s es conveniente darles nom-
bres, pero para el uso computacional en general supondremos que
si hay n vrtices, stos se denominan , , . . . , n, es decir, suponemos
V = , , . . . , n. Ms an, casi siempre usaremos el nombre n (o algo
que empiece con n) para el cardinal de V.
En los grafos que veremos, las aristas estn formadas por un par
de vrtices, y como el orden no importar, indicaremos la arista que
une el vrtice a con el vrtice b por a, b. Claro que decir a, b E
es lo mismo que decir b, a E.
A veces se consideran grafos dirigidos o digrafos, en los que las
aristas estn orientadas, y por lo tanto se indican como (a, b) (y
se llaman arcos en vez de aristas), distinguiendo entre (a, b) y
(b, a). Nosotros no estudiaremos este tipo de grafos.
As como n es el nombre ofcial de V (el cardinal de V), el
nombre ofcial para E es m.
Si e = a, b E, diremos que a y b son vecinos o adyacentes,
que a y b son los extremos de e, o que e incide sobre a (y b). A veces,
un vrtice no tiene vecinos no hay aristas que incidan sobre l y
entonces decimos que es un vrtice aislado.
Slo consideraremos grafos simples en los que no hay aristas unien-
do un vrtice con s mismo, ni aristas paralelas o repetidas que unen
los mismos pares de vrtices. En este caso, podemos relacionar n = V
y m = E: si hay n elementos, hay {
n

) = n (n ) subconjuntos de
elementos, de modo que m {
n

).
En la fgura . mostramos un ejemplo de grafo donde n = ,
E = , , , , , , , , , , , , , ,
y por lo tanto m = , y el vrtice es aislado.
Siguiendo con la analoga de rutas, es comn hablar de camino,
una sucesin de vrtices el orden es importante de la forma
(v

, v

, . . . , v
k
), donde v
i
, v
i
E para i = , . . . , k, y sin aristas
repetidas (pero pueden haber vrtices repetidos). Si u = v

y v = v
k
,
decimos que el camino (v

, v

, . . . , v
k
) es un camino de u a v, o que
Pg. z{z Cap|rulo t8. Grafos
Ejemplo de grafo simple
1
2 3
4
5 6
Figura .: Un grafo con vrtices y aristas. El vrtice es aislado.
une u y v, o sencillamente es un camino uv. La longitud del camino
(v

, v

, . . . , v
k
) es k, la cantidad de aristas que tiene (y no la cantidad
k + de vrtices). Un camino en principio puede tener vrtices repeti-
dos, y si se cierra sobre s mismo de modo que v

= v
k
, decimos que
se trata de un camino cerrado o ciclo, mientras que si no tiene vrtices
repetidos decimos que es un camino simple. Del mismo modo, un ciclo
es simple si no tiene vrtices repetidos (salvo el primero y el ltimo).
Por ejemplo, en la fgura .:
(, , , , ) es un camino de longitud ,
(, , ) es un camino simple,
(, , , , , , ) es un ciclo,
(, , , , ) es un ciclo simple (no tiene vrtices repetidos).
De fundamental importancia es reconocer si un grafo es conexo,
es decir, si existe un camino desde cualquier vrtice a cualquier otro
vrtice. La relacin defnida en V V por u v si y slo si u = v o
existe un camino uv, es una relacin de equivalencia,
()
y las clases de
equivalencia se llaman componentes conexas o simplemente componen-
()
Ver el ejercicio ..
t8.t. Ensalada de defncones Pg. z{
tes del grafo. Por ejemplo, el grafo de la fgura . no es conexo, pues
tiene un vrtice aislado, y sus componentes son , , , , y .
Si el grafo es conexo (y simple), como se puede unir un vrtice
con los n restantes, debe tener al menos n aristas. De modo que
para un grafo (simple) conexo, m tiene que estar bsicamente entre n
y n

.
()
Dada su estructura, es ms sencillo trabajar con rboles que con gra-
fos. Un arbol es un grafo (simple) conexo y sin ciclos, pero hay muchas
formas equivalentes de describirlo, algunas de las cuales enunciamos
como teorema (que por supuesto creeremos):
.. Teorema (Caracterizaciones de rboles). Dado un grafo simple
G = (V, E) con V = n, las siguientes condiciones son equivalentes.
a) G es un arbol, es decir, es conexo y no tiene ciclos.
b) Para cualesquiera a, b V existe un nico camino que los une.
c) G es conexo y E = n .
d) G no tiene ciclos y E = n .
e) G es conexo, y si se agrega una arista entre dos vertices cuales-
quiera, se crea un unico ciclo.
f) G es conexo, y si se quita cualquier arista queda no conexo.
A veces en un rbol consideramos un vrtice particular como raz,
y miramos a los otros vrtices como descendientes de la raz: los que se
conectan mediante una arista a la raz son los hijos, los que se conectan
con un camino de longitud son los nietos y as sucesivamente. Dado
que hay un nico camino de la raz a cualquier otro vrtice, podemos
clasifcar a los vrtices segn niveles: la raz tiene nivel , los hijos nivel
, los nietos nivel , etc.
Por supuesto, podemos pensar que los nietos son hijos de los hijos,
los hijos padres de los nietos, etc., de modo que en un rbol con
raz hablaremos de padres, hijos, ascendientes y descendientes de
un vrtice. Habr uno o ms vrtices sin descendientes, llamados hojas
()
Ms precisamente, entre n y n (n ).
Pg. z{{ Cap|rulo t8. Grafos
mientras que la raz ser el nico vrtice sin ascendientes. Tambin es
comn referirse al conjunto formado por un vrtice (aunque el vrtice
no sea la raz) y sus descendientes como una rama del rbol.
G

= (V

, E

) es un subgrafo de G = (V, E) si V

V y E


E. Decimos que el subgrafo G

es generador de G si V = V

, y en
particular, nos van a interesar arboles generadores. Si G = (V, E) y
V

V, llamamos subgrafo inducido por V

al grafo G

= (V

, E

)
donde E

= u, v E u, v V

.
Ejercicio .. Defnir una funcin simple(uv, vw) que dados los
caminos uv y vw como listas de vrtices, retorna un camino simple
uw. Por ejemplo, si uv es |, , , | y vw es |, , |, un camino simple
uw es |, , |.
Aclaracion : suponemos u, v y w distintos entre s.
Aclaracion : los caminos uv y vw pueden no ser simples.
Aclaracion : se pide un camino simple uw aunque puede ha-
ber ms de uno, por ejemplo si uv = |, , , , | y vw = |, , , |,
entonces |, , |, |, , , | y |, , , , | son caminos simples . e
.. Representacin de grafos
Antes de meternos de lleno con los algoritmos, tenemos que decidir
cmo guardaremos la informacin de un grafo en la computadora.
Ya sabemos que los vrtices sern , , . . . , n, y nos falta guardar la
informacin de las aristas. Hay muchas formas de hacerlo, pero en
este curso nos concentraremos en dos: dar la lista de aristas (con sus
extremos) y dar la lista de adyacencias o vecinos, una lista donde el
elemento en la posicin i es a su vez una lista de los vecinos de i.
Ejemplo .. Para el grafo de la fgura ., podramos poner
ngrafo = 6 # cantidad de vrtices
aristas = [[1, 2], [1, 3], [2, 3], [2, 6],
[3, 4], [3, 6], [4, 6]]
t8.z. Represenracn de grafos Pg. z{y
Observar que los elementos de aristas sona suvez listas enlas que
el orden es importante para Python (pues |, | |, |). Sin embargo,
al tratarse de aristas de un grafo para nosotros sern iguales.
Recordando lo hecho en la el captulo al tratar listas como
conjuntos, para conservar la salud mental trataremos de ingre-
sar la arista u, v poniendo u < v, aunque en general no ser
necesario.
Ver el ejercicio ..
La lista de vecinos tendr ndices desde , por lo que pondremos
None en la posicin a fn de evitar errores (pero la lista de aristas
tiene ndices desde ).
vecinos = [None,
[2, 3], [1, 3, 6], [1, 2, 4, 6],
[3, 6], [], [2, 3, 4]]
Observar que hay informacin redundante en la lista de veci-
nos. Por ejemplo, en la lista vecinos anterior, como 2 est en
vecinos[1], sabemos que , es una arista del grafo, y en prin-
cipio no sera necesario repetir esta informacin poniendo 1 en
vecinos[2].
La redundancia hace que sea preferible el ingreso de la lista de
aristas antes que la de vecinos, porque se reducen las posibilidades
de error. Esencialmente, ambas requieren del mismo lugar en
memoria pues si a, b E, al ingresarla en la lista de aristas
ocupa dos lugares (uno para a y otro para b), y en la lista de
vecinos tambin (un lugar para a como vecino de b y otro para b
como vecino de a). e
Ejercicio .. Defnir una funcin para que dada la lista de vecinos
imprima, para cada vrtice, los vrtices que son adyacentes.
Por ejemplo, si la entrada es el grafo del ejemplo ., la salida
debera ser algo como
Vrtice Vecinos
1 2 3
2 1 3 6
Pg. z{o Cap|rulo t8. Grafos
3 1 2 4 6
4 3 6
5
6 2 3 4 e
Ejercicio .. Como es til pasar de una representacin a otra, def-
nimos las funciones dearistasavecinos y devecinosaaristas en el
mdulo grafos.
Comprobar el comportamiento de estas funciones con las entradas
del ejemplo ., pasando de una a otra representacin (en ambos
sentidos).
Observar:
Como es usual, suponemos que los datos ingresados son correc-
tos: los vrtices de las aristas que se ingresan son enteros entre
y ngrafo y no hay aristas repetidas o de la forma i, i.
En dearistasavecinos ponemos explcitamente vecinos[0]
= None.
Endevecinosaaristas slo agregamos una arista cuando v < u,
evitando poner una arista dos veces.
Pusimos for v in range(1, ngrafo), ya que no existe el
vrtice , y no hay vrtices u con ngrafo < u.
Las inicializaciones de vecinos y aristas en cada caso.
Usamos la construccin for u, v in aristas en la funcin
dearistasavecinos, an cuando cada arista est representada
por una lista (y no una tupla) (ver el ejercicio ..c)). e
Ejercicio .. Defnir una funcin normalizar(aristas) que mo-
difca la lista de aristas de modo que las aristas sean de la forma |u, v|
con u < v, y estn ordenadas crecientemente: |a, b| precede a |u, v| si
a < u o (a = u y b < v). e
Ejercicio .. A fn de evitar errores cuando ingresamos datos y no
escribir tanto, es conveniente guardar los datos del grafo en un archivo
de texto. Por comodidad (y uniformidad), supondremos que el archivo
t8.z. Represenracn de grafos Pg. z{,
de texto contiene en la primera lnea el nmero de vrtices, y en las
restantes los vrtices de cada arista: por lo menos debe tener un renglon
(correspondiente al nmero de vrtices), y a partir del segundo debe
haber exactamente dos datos por rengln.
Por ejemplo, para el grafo del ejemplo ., el archivo tendra (ni
ms ni menos):
6
1 2
1 3
2 3
2 6
3 4
3 6
4 6
Defnir una funcin que toma como argumento el nombre de
un archivo de texto donde se guarda la informacin sobre el grafo
(como indicada anteriormente). Comprobar la correccin de la funcin
imprimiendo la lista de aristas, una por rengln.
Qu pasa si el grafo no tiene aristas? e
Ejercicio.. Uncoloreo de ungrafo G = (V, E) es asignar uncolor
a cada vrtice de modo que vrtices adyacentes no tienen el mismo
color. Por ejemplo, en la fgura . asignamos los colores a, r
y v a un grafo, siendo el de la izquierda un coloreo pero no el de la
derecha.
Defnir una funcin escoloreo(n, aristas, colores) que de-
cide si la lista colores es un coloreo del grafo asociado: aristas es la lista
de aristas de un grafo de vrtices , . . . , n, y colores es una lista de
longitud n + de la forma [colores[0],...,colores[n]].
Los valores que toman los elementos de la lista colores es irrele-
vante: podran ser letras, nmeros o expresiones ms complicadas.
Como no necesitamos el valor de colores[0], podemos suponer
que es None, pero no es necesario. e
Pg. z{8 Cap|rulo t8. Grafos
r
a
v
a
a
r
a
v
Figura .: Asignando colores a los vrtices de un grafo.
Ejercicio . (grado de vrtices). Dado un grafo G = (V, E), para
cada vrtice v V se defne su grado o valencia, (v), como la cantidad
de aristas que inciden en v, o equivalentemente, la cantidad de vecinos
de v (excluyendo al mismo v).
As, en el grafo del ejemplo ., los grados son () = , () =
, () = , () = , () = , () = .
a) Defnir una funcin que dado un grafo (ingresado por su can-
tidad de vrtices y una lista de aristas) calcule (v) para todo
v V.
b) Uno de los primeros teoremas que se ven en teora de grafos
dice que si U es el conjunto de vrtices de grado impar, entonces

vU
(v) es par.
Defnir una funcin para hacer este clculo y verifcar el
teorema para distintos casos (por ejemplo, el grafo de la fgu-
ra .). e
Ejercicio .. Es claro que si (u = v

, v

, . . . , v
k
= v) es un camino
uv, entonces (v
k
, v
k
, . . . , v

) es un camino vu, y lo mismo para


un ciclo.
Defnir una funcin que ingresando un grafo y una sucesin de
vrtices (v

, v

, . . . , v
k
), k :
a) decida si (v

, v

, . . . , v
k
) es un camino, es decir, si v
i
, v
i

E para i = , . . . , k, y no hay aristas repetidas,
t8.. Recorrendo un grafo Pg. z{
Atencin con u, v = v, u!
y en caso afrmativo:
b) imprima el camino inverso v
k
, . . . , v

, y
c) verifque si (v

, v

, . . . , v
k
) es un ciclo.
Comparar con el ejercicio .. e
Ejercicio .. El mdulo grgrafo (grfcos de grafos) permite hacer
ilustraciones de grafos como el de la fgura .. El comportamiento es
similar al del mdulo gracar (en el captulo ), aunque una diferencia
importante es que en grgrafo se pueden mover los vrtices y etiquetas
con el ratn.
Como otros mdulos grfcos que vemos, grgrsimple es una plan-
tilla para realizar ilustraciones, en este caso con grgrafo. Habr que
variar los parmetros del grafo (cantidad de vrtices y aristas) y de la
ilustracin.
Ejecutar el mdulo grgrsimple viendo su comportamiento movien-
do los vrtices y etiquetas, o ingresando otros grafos. e
.. Recorriendo un grafo
As como es importante recorrer una lista (por ejemplo para
encontrar el mximo o la suma), tambin es importante recorrer un
grafo, visitando todos sus vrtices en forma ordenada, evitando
visitar vrtices ya visitados, y siempre caminando por las aristas del
grafo. Exactamente qu hacer cuando se visita un vrtice depender
del problema, y en general podemos pensar que visitar es sinnimo
de procesar.
En una lista podemos considerar que los vecinos de un elemento
son su antecesor y su sucesor (excepto el primero y el ltimo), y em-
pezando desde el primer elemento podemos recorrer linealmente la
lista, mirando al sucesor de turno como hicimos repetidas veces en
Pg. zyo Cap|rulo t8. Grafos
el captulo . En cambio, en un grafo un vrtice puede tener varios
vecinos, y el recorrido es ms complicado.
No habiendo un primer vrtice como en una lista, en un grafo
elegimos un vrtice en donde empezar el recorrido, llamado raz, y
luego visitamos a los vecinos, luego a los vecinos de los vecinos, etc.,
conservando informacin sobre cules vrtices ya fueron considerados
a fn de no visitarlos nuevamente. Con este fn, normalmente usaremos
una lista padre de modo que padre[v] nos dice desde qu vrtice he-
mos venido a visitarlo. Para indicar el principio del recorrido, ponemos
padre[raiz] = raiz,
()
y cualquier otro vrtice tendr padre[v] v.
Como los vrtices se visitarn secuencialmente, uno a la vez, tene-
mos que pensar cmo organizarnos para hacerlo, para lo cual apelamos
al concepto de cola (como la del supermercado).
Inicialmente ponemos la raz en la cola. Posteriormente vamos
sacando vrtices de la cola para visitarlos y agregando los vecinos de
los que estamos visitando. En el cuadro . mostramos un esquema
informal, donde la cola se llama Q y la raz r.
Hay distintos tipos de cola:
Cola lfo (last in, first out) o pla: el ltimo elemento ingresado
(last in) es el primero en salir (frst out). Tambin la llamamos
pila porque se parece a las pilas de platos.
Cola ffo (first in, first out): el primer elemento ingresado (frst
in) es el primero en salir (frst out). Son las colas que normal-
mente llamamos... colas, como la del supermercado.
Cola con prordad: Los elementos van saliendo de la cola de
acuerdo a cierto orden de prioridad. Por ejemplo, las mams
con bebs se atienden antes que otros clientes.
Las colas tienen ciertas operaciones comunes: inicializar, agregar
un elemento y quitar un elemento:
Inicializamos la cola con:
()
Como siempre, no ponemos tildes en los identifcadores para evitar problemas.
t8.. Recorrendo un grafo Pg. zyt
Algoritmo recorrdo
Entrada: un grafo G = (V, E) y r V (la raz).
Salida: los vrtices que se pueden alcanzar des-
de r visitados.
Comienzo
Q r
mientras Q :
sea i Q
sacar i de Q
visitar i hacer algo con i
para todo j adyacente a i:
si j no est visitado y j Q:
agregar j a Q
Fin
Cuadro .: Esquema del algoritmo recorrido.
cola = [] # la cola vaca
Para simplifcar, vamos a agregar elementos siempre al fnal de
la cola:
cola.append(x)
Qu elemento sacar de la cola depende del tipo de cola:
x = cola.pop() # para colas lifo (pilas)
x = cola.pop(0) # para colas fifo
En Python es mucho ms efciente usar colas lifo, modifcan-
do el fnal con lista.append(x) y x = lista.pop(), que agre-
gar o sacar en posiciones arbitrarias usando funciones como
lista.insert o lista.pop(lugar).
Para los ejemplos del curso no hace diferencia porque las listas
no son demasiado grandes.
El mdulo estndar collections implementa listas ffo efcien-
temente en collections.deque (ver el manual de la biblioteca).
Pg. zyz Cap|rulo t8. Grafos
Nosotros no lo veremos en el curso.
Volviendo al recorrido de un grafo, una primera versin es la fun-
cin recorrido (en el mdulo grafos). Esta funcin toma como argu-
mentos la lista de vecinos (recordando que los ndices empiezan desde
) y un vrtice raz, retornando los vrtices para los cuales existe un
camino desde la raz.
Observar el uso de padre en la funcin recorrido. Inicialmente
el valor es None para todo vrtice, y al terminar el valor es None slo si
no se puede llegar al vrtice correspondiente desde la raz.
Tambin podemos ver que la cola se ha implementado como pila
pues sale el ltimo en ingresar.
Ejercicio . (recorrido de un grafo).
a) Estudiar la funcin recorrido y comprobar el comportamien-
to para el grafo del ejemplo . tomando distintos vrtices
como raz, por ejemplo , y .
Observar que si la raz es , se visitan todos los vrtices
excepto . Lo inverso sucede tomando raz : el nico vrtice
visitado es .
En la pgina del libro hay una pelcula (archivo pdf) de
cmo se va construyendo el rbol cuando la raz es . La fgu-
ra . muestra la ltima pgina de ese archivo, donde pode-
mos observar el rbol en azul, las fechas indican el sentido
hijo-padre, y en las aristas est recuadrado el orden visitados
los vrtices y aristas correspondientes, en este caso: (raz),
(usando , ), (usando , ), (usando , ) y
(usando , ).
b) Al examinar vecinos del vrtice que se visita, hay un lazo que
comienza con for v in vecinos[u]....
Sera equivalente cambiar esas instrucciones por
lista = [v for v in vecinos[u] if padre[v] == None]
cola = cola + lista
for v in lista:
t8.. Recorrendo un grafo Pg. zy
Recorrido con cola LIFO - Paso 5: rbol y cola
cola
hijo - padre
rbol
elegido
arista sacada
n orden de agregado
1
2 3
4
5 6
1
3
2
4
Figura .: Recorrido lifo del grafo del ejemplo . tomando raz .
padre[v] = u ? e
Ejercicio .. Agregar instrucciones a la funcin recorrido de mo-
do que al fnal se impriman los vrtices en el orden en que se incorpo-
raron a la cola, as como el orden en que fueron visitados (es decir,
el orden en que fueron sacados de la cola).
Por ejemplo, aplicada al grafo del ejemplo . cuando la raz es
se imprimira
Orden de incorporacin a la cola:
1 2 3 4 6
Orden de salida de la cola:
1 3 6 4 2
Sugerencia: agregar dos listas, digamos entrada y salida, e ir
incorporando a cada una los vrtices que entran o salen de la cola. e
Ejercicio . (componentes). En el ejercicio . vimos que no
siempre existen caminos desde la raz a cualquier otro vrtice. Lo que
hace exactamente la funcin recorrido es construir (y retornar) los
vrtices de la componente conexa que contiene a la raz.
Pg. zy{ Cap|rulo t8. Grafos
a) Agregar al grafo del ejemplo . las aristas , y , , de
modo que el grafo resultante es conexo. Verifcarlo corriendo la
funcin recorrido para distintas races sobre el nuevo grafo.
b) En general, para ver si un grafo es conexo basta comparar la
longitud (cardinal) de una de sus componentes con la cantidad
de vrtices. Defnir una funcin que tomando el nmero de
vrtices y la lista de aristas, decida si el grafo es conexo o no
(retornando True o False).
c) Usando la funcin recorrido, defnir una funcin que retorne
una lista de las componentes de un grafo. En el grafo original
del ejemplo . el resultado debe ser algo como [[1, 2, 3,
4, 6], [5]]. e
En la fgura . podemos ver que las aristas elegidas por la funcin
recorrido forman un rbol. Usando la raz en el grafo del ejem-
plo ., las aristas del rbol son , , , , , y , , como ya
mencionamos. En cambio, el rbol se reduce a la raz cuando sta es ,
y no hay aristas.
Ejercicio .. Agregar instrucciones a la funcin recorrido, de mo-
do que en vez de retornar los vrtices del rbol obtenido, se retorne la
lista de aristas que forman el rbol. e
Ejercicio .. Hacer sendas funciones para los siguientes apartados
dado un grafo G:
a) Ingresando la cantidad de vrtices, la lista de vecinos y los
vrtices s y t, s t, se exhiba un camino st o se imprima un
cartel diciendo que no existe tal camino.
Sugerencia: usar recorrido con raz t y si al fnalizar resulta
padre[s] None, construir el camino siguiendo padre hasta
llegar a t.
b) Ingresando la cantidad de vrtices y la lista de aristas, se impri-
ma una (y slo una) de las siguientes:
i) G no es conexo,
t8.. Recorrendo un grafo Pg. zyy
ii) G es un rbol,
iii) G es conexo y tiene al menos un ciclo.
Sugerencia: recordar el teorema . y el ejercicio ..b).
c) Dados el nmero de vrtices, la lista de aristas y la arista u, v,
se imprima si hay o no un ciclo en G que la contiene, y en caso
afrmativo, imprimir uno de esos ciclos.
Ayuda: si hay un ciclo que contiene a la arista u, v, debe
haber un camino uv en el grafo que se obtiene borrando la
arista u, v del grafo original.
d) Modifcar el apartado b.iii) de modo de adems exhibir un ciclo
de G. e
Ejercicio . (ciclo de Euler I). Un clebre teorema de Euler dice
que un grafo tiene un ciclo que pasa por todas las aristas exactamente
una vez, llamado ciclo de Euler, si y slo si el grafo es conexo y el grado
de cada vrtice es par.
Recordando el ejercicio ., defnir una funcin que tomando co-
mo datos la cantidad de vrtices y la lista de aristas, decida (retornando
True o False) si el grafo tiene o no un ciclo de Euler.
Un problema muy distinto es construir un ciclo de Euler en caso
de existir (ver el ejercicio .).
No confundir ciclo de Euler, en el que se recorren todas las aristas
una nica vez (pero pueden repetirse vrtices), con ciclo de Ha-
milton, en el que se recorren todos los vrtices exactamente una
vez (y pueden no usarse algunas aristas).
En el ejercicio . estudiamos caminos de Hamilton, que son
similares y en algn sentido equivalentes a los ciclos.
k Euler (:,o,:,8) fue uno de los mas grandes y prolfcos matema-
ticos de todos los tiempos, haciendo contribuciones en todas las
areas de las matematicas. Fue tan grande su infuencia que se uni-
fcaron notaciones que el ideo, como la de (= . . . .) (del
griego perypheria o circunferencia), i (=

) (por imaginario), y
e (= . . . .) (del aleman einhalt o unidad).
Entre otras tantas, Euler inicio el estudio de teora de grafos y
Pg. zyo Cap|rulo t8. Grafos
la topologa al resolver en :,o el famoso problema de los puentes
de Knigsberg, demostrando el teorema que mencionamos en el
ejercicio. e
Como ya observamos, la cola en la funcin recorrido es una pila.
As, si el grafo fuera ya un rbol, primero visitaremos toda una rama
hasta el fn antes de recorrer otra, lo que hace que este tipo de recorrido
se llame en profundidad o de profundidad primero. Otra forma de
pensarlo es que vamos caminando por las aristas (a partir de la raz)
hasta llegar a una hoja, luego volvemos por una arista (o las necesarias)
y bajamos hasta otra hoja, y as sucesivamente.
En algunos libros se llama recorrido en profundidad a visitar
primero todos los vecinos antes de visitar al vrtice. No veremos
esta variante ya que la programacin es bastante ms complicada
e inefciente.
El orden en que se recorren los vrtices tanto en el recorri-
do en profundidad como el recorrido a lo ancho que veremos a
continuacin est determinado tambin por la numeracin de
los vrtices. En la mayora de las aplicaciones, la numeracin dada
a los vrtices no es importante: si lo fuera, hay que sospechar del
modelo y mirarlo con cuidado.
Si en la funcin recorrido, en vez de implementar la cola como
lifo (pila) la implementamos como ffo, visitamos primero la raz, luego
sus vecinos, luego los vecinos de los vecinos, etc. Si el grafo es un rbol,
visitaremos primero la raz, despus todos sus hijos, despus todos sus
nietos, etc., por lo que se el recorrido se llama a lo ancho.
Ejercicio . (recorrido a lo ancho).
a) Modifcar la funcin recorrido de modo que la cola sea ahora
ffo.
Sugerencia: cambiar pop() a pop(0) en el lugar adecuado.
b) Repetir el ejercicio ., comparando las diferencias entre el
recorrido en profundidad y el recorrido a lo ancho.
t8.. Recorrendo un grafo Pg. zy,
Recorrido con cola FIFO - Paso 5: rbol y cola
cola
hijo - padre
rbol
elegido
arista sacada
n orden de agregado
1
2 3
4
5 6
1
2
3
4
Figura .: Recorrido ffo del grafo del ejemplo . tomando raz .
En la pgina del libro se muestra una pelcula (archivo pdf) de
cmo se va construyendo el rbol cuando la raz es . La fgura .
es la ltima pgina de ese archivo, destacando el orden en que las
aristas se incorporan. Comparar con la fgura .. e
Una forma dramtica de mostrar las diferencias de recorridos lifo
o ffo es construyendo laberintos como los de la fgura ..
Estos laberintos se construyen sobre una grilla de m n de puntos
con coordenadas enteras, donde un vrtice (i, j) es vecino del vrtice
(i

, j

) si i i

+ j j

= , es decir si uno est justo encima del otro


o al costado.
Con random.shuffle se da un orden aleatorio a cada lista de ve-
cinos (despus de construirlas), y la raz (entrada) se toma aleatoria-
mente sobre el borde inferior. Finalmente, se construyen los rboles
correspondientes usando el algoritmo recorrido.
Como se trata de rboles, sabemos que hay un nico camino entre
cualquier par de vrtices. Tomando aleatoriamente un punto de salida
sobre el borde superior, podemos construir el nico camino entre la
entrada y la salida, lo que constituye la solucin del laberinto.
En la fgura . a la izquierda mostramos el rbol obtenido para
cola lifo y a la derecha para cola ffo, para m = n = , usando una
Pg. zy8 Cap|rulo t8. Grafos
entrada
salida
entrada
salida
entrada
salida
Figura .: Laberinto (izquierda) y solucin (centro) usando pila (lifo),
y laberinto usando cola ffo (derecha).
misma semilla (con random.seed) para tener las mismas listas de
vecinos. En la parte central de la fgura mostramos la solucin del
laberinto a la izquierda (cola lifo).
Observamos una diferencia notable en la calidad de los rboles. El
recorrido con cola ffo o ancho primero produce un rbol mucho ms
regular. Por supuesto, los rboles tienen la misma cantidad de aristas,
pero los caminos obtenidos con recorrido en profundidad primero
produce caminos mucho ms largos.
.. Ejercicios Adicionales
Ejercicio.. Construir laberintos de mn como los de la fgura .
(ver descripcin correspondiente). e
Ejercicio . (ciclo de Euler II). En el ejercicio . nos hemos
referido a la existencia de ciclos de Euler, y nos preocuparemos ahora
por encontrar efectivamente uno.
Para demostrar que un grafo conexo con todos los vrtices de grado
par tiene un ciclo de Euler, se comienza a partir de un vrtice y se van
recorriendo aristas, borrndolas, hasta que volvamos al vrtice original,
formando un ciclo. Esto debe suceder porque todos los vrtices tienen
grado par. Puede ser que el ciclo no cubra a todas las aristas, pero como
t8.y. Comenraros Pg. zy
el grafo es conexo, debe haber un vrtice en el ciclo construido que
tenga una arista (an no eliminada) incidente en l, a partir del cual
podemos formar un nuevo ciclo, agregarlo al anterior y continuar con
el procedimiento hasta haber recorrido y eliminado todas las aristas.
Esta demostracin es bien constructiva, y podemos implementar
los ciclos como listas, slo hay que tener cuidado al juntarlas.
Defnir una funcin para decidir si un grafo es conexo y todos los
vrtices tienen grado par (ejercicio .), y en caso afrmativo construir
e imprimir un ciclo de Euler.
Sugerencia: para borrar una arista o un vecino de la lista de veci-
nos usar la funcin sacar del ejercicio ..b), y para pegar ciclos
podra usarse una construccin del tipo ciclo1[:i-1] + ciclo2 +
ciclo1[i+1:]. e
.. Comentarios
Las fguras de los laberintos (fgura .) se hicieron con el m-
dulo gracar. Las restantes fguras en este captulo se hicieron
con el mdulo grgrafo, as como las pelculas en la pgina del
libro para ilustrar los distintos algoritmos.
La presentacin de la funcin recorrido y del algoritmo .
estn basadas en la de Papadimitriou y Steiglitz ().

Captulo
Recursin
recursivo, va. . adj. ver recursivo.
.. Introduccin
Una forma de sumar los nmeros a

, a

, a

, . . . , es ir construyendo
las sumas parciales que llamamos acumuladas en el ejercicio .:
s

= a

, s

= s

+ a

, s

= s

+ a

, . . . , s
n
= s
n
+ a
n
, . . . ,
ecuaciones que pueden expresarse ms sencillamente como
s

= a

y s
n
= s
n
+ a
n
para n . (.)
Cuando la sucesin de nmeros es , , , . . . y cambiamos suma
por producto, obtenemos el factorial (ejercicio .):
! = , ! = ! , ! = ! , . . . , n! = (n )! n, . . . ,
y en realidad es usual defnir n! mediante
! = y n! = n (n )! para n N. (.)
t.z. Puncones defndas recursvamenre Pg. zot
Cuando se dan uno o ms valores iniciales y una frmula para
calcular los valores subsiguientes como en (.) o (.), decimos que
se ha dado una relacion de recurrencia.
Estas relaciones estn estrechamente conectadas con el concepto de
induccion en matemtica y el de recursion
()
en programacin, aunque
los conceptos no son completamente equivalentes. Por ejemplo, la
relacin (.) es la defnicin inductiva del factorial en matemtica,
mientras que en programacin es comn decir que una funcin es
recursiva si en su defnicin hay una llamada a s misma (aunque sea a
travs de otras funciones).
Para nosotros,
la idea fundamental de recursion es la resolucion
de un problema usando las soluciones del mismo
problema para tamaos mas chicos... y as
sucesivamente si fuera necesario.
h
Por ejemplo, para calcular ! primero calculamos !, para calcular
! primero calculamos !, para calcular ! primero calculamos !, y
fnalmente ! = .
.. Funciones defnidas recursivamente
Ejercicio .. En Python podemos defnir una funcin recursiva para
calcular el factorial basada en la ecuacin (.), dando el valor inicial
para n = y el valor para n mayores dependiendo del valor anterior:
def factorial(n):
"""n! usando recursin.
n debe ser entero positivo.
()
La palabra recursion no existe en castellano segn la RAE.
Pg. zoz Cap|rulo t. Recursn
"""
if n == 1: # paso base
return 1
return n
*
factorial(n-1)
a) Comparar esta funcin con la defnida en el ejercicio . para
n = , , . . . , , usando alguna tcnica del ejercicio . para
compararlas.
b) El esquema anterior no contempla el caso n = , para el cual
sabemos que ! = . Modifcar la funcin para incluir tambin
el caso n = .
Atencion: cambiar la documentacin acordemente.
c) Qu pasa si n < ?, y si n no es entero? e
Veamos otros ejemplos similares que antes resolvamos con un
lazo for o similar, y que ahora podemos resolver usando recursin.
Ejercicio .. Defnir una funcin recursiva para calcular las sumas
de Gauss,
s
n
= + + + n =
n

k=
k,
luego defnir otra funcin usando que
s
n
=
n (n + )

,
y compararlas.
Usar divisin entera para la segunda funcin.
k Segun se dice, johann Carl Friederich Gauss (:,,,:8,,) tena 8
aos cuando el maestro de la escuela le dio como tarea sumar los
numeros de a para mantenerlo ocupado (y que no molestara).
Sin embargo, hizo la suma muy rapidamente al observar que la
suma era .
t.. Nmeros de Pbonacc Pg. zo
Las contribuciones de Gauss van mucho mas alla de esta anec-
dota, sus trabajos son tan profundos y en tantas ramas de las ma-
tematicas (y la fsica) que le valieron el apodo de prncipe de los
matematicos. Para algunos, fue el mas grande matematico de todos
los tiempos. e
Las funciones recursivas pueden tener uno o varios argumentos, y
no tienen que ser nmeros. Si tienen ms de un argumento, la recur-
sin puede hacerse tanto en slo uno de ellos como en varios, como
ilustramos en los siguientes ejercicios.
Ejercicio .. Defnir una funcin recursiva para calcular el cociente
de la divisin entre a y b cuando a y b son enteros positivos, usando
que si a b entonces cociente(a, b) cociente(a - b, b) + 1.
Sugerencia: if a < b:...
Ac la funcin tiene dos argumentos, pero se hace recursin slo
sobre el primero y el segundo acta como parmetro. e
Ejercicio .. Dar una defnicin recursiva de la funcin saldo(c,
r, p, m) en el ejercicio ..c) segn las ecuaciones (.). e
Ejercicio .. Recordando la versin original del algoritmo de Eu-
clides para encontrar el mximo comn divisor entre dos enteros po-
sitivos (ver seccin .), defnir una funcin recursiva para calcular
mcd(a, b) cuando a y b son enteros positivos.
Ayuda: si a > b entonces mcd(a, b) = mcd(ab, b), anlogamente
para el caso a < b, y mcd(a, a) = a.
En este ejercicio la recursin se hace en ambos argumentos, a
diferencia del ejercicio ..
Observar que no se hace la llamada a f(n - 1). e
.. Nmeros de Fibonacci
Los nmeros de Fibonacci f
n
se defnen mediante:
f

= , f

= , y f
n
= f
n
+ f
n
para n , (.)
Pg. zo{ Cap|rulo t. Recursn

n a = f
n
b = f
n



Figura .: Ilustracin del clculo de los nmeros de Fibonacci.
obteniendo la sucesin , , , , , , . . . :
, , (= + ), (= + ), (= + ), (= + ), . . .
En la fgura . ilustramos la construccin de f
n
: en la columna de
la izquierda est el valor de n y en las otras dos estn los valores de f
n
y
f
n
. Para calcular f

necesitamos los valores de f

y f

lo que indicamos
con fechas azules, y en ese momento f
n
= f

lo que indicamos con


una fecha roja. Lo mismo sucede para valores mayores de n: f
n
se
calcula a partir de dos valores anteriores (fechas azules) y el nuevo
f
n
es el viejo f
n
(fechas rojas).
Ejercicio ..
a) Como para el clculo de f
n
con n slo necesitamos conocer
los dos valores anteriores, podemos usar un lazo for en el que
conservamos los dos ltimos encontrados. Para fjar ideas, lla-
mamos a al valor de f
n
y b al valor de f
n
, como est indicado
en la fgura ..
Llegamos a algo como
a, b = 1, 1 # los dos primeros
for i in range(n - 2): # ojo que no es n
a, b = a + b, a # i no se usa
return a
t.. Nmeros de Pbonacc Pg. zoy
Observar el uso de intercambio/asignaciones mltiples
en la construccin a, b = a + b, a.
Defnir una funcin para calcular f
n
en base a estas ideas.
b) Defnir una funcin recursiva para calcular f
n
basada en un
esquema del tipo
if n < 3:
return 1
return fibonacci(n - 1) + fibonacci(n - 2)
que sigue ms o menos literalmente a las ecuaciones (.).
Observar que en la versin recursiva se hacen dos llamadas a
la misma funcin.
c) Comparar los resultados de ambas versiones para n N, n .
d) Qu pasa con la versin recursiva si n < ?, es correcto el
resultado?, y en la versin con for?
k Leonardo Bigollo (::,o::,o) fue conocido como Leonardo de Pisa
y tambien como Fibonacci (hijo de Bonacci). En el libro Liber
Abaci propuso el famoso problema con los conejos donde aparecen
por primera vez los numeros que luego llevaron su nombre.
A pesar de la similitud de los nombres, Leonardo da Vinci (:,:
:,:) es muy posterior a Leonardo de Pisa. e
Los nmeros de Fibonacci estn ntimamente relacionados con el
numero de oro, tambin llamado proporcion aurea,
=
+

= . . . . , (.)
que aparece muchas veces en matemticas, las artes y la arquitectura.
es solucin de la ecuacin
x

= x + ,
cuya otra solucin es

.
Pg. zoo Cap|rulo t. Recursn
De la teora general de relaciones de recurrencia, se ve que
f
n
=

n
(

)
n

=
( +

)
n
(

)
n

, (.)
relacin comnmente llamada de Binet o de Euler-Binet. En particular,
esta relacin muestra que f
n
crece exponencialmente, ya que > ,

< , y f
n

n
para n grande.
El miembro derecho en (.) es un nmero entero!
k jacques Binet (:,8o:8,o) publico la ecuacion (.) para los nu-
meros de Fibonacci en :8. Leonhard Euler (:,o,:,8) la haba
publicado en :,o,, y de ah el nombre de la relacion. Sin embargo,
A. de Moivre (:oo,:,,) ya la haba publicado en :,o, y en forma
mas general!
Ejercicio . (frmula de Euler-Binet).
a) Defnir una funcin binet para calcular f
n
segn (.).
Sugerencia: usar divisin comn y no entera.
b) Comparar los valores de binet con los de la versin recursiva
defnida en el ejercicio ..b) para n = , . . . , .
c) Comparar el n-simo nmero de Fibonacci f
n
con el redondeo
(round) de

=
( +

)
n

. (.)
A partir de qu n son iguales?, podras decir por qu?
d) Construir una funcin binet2 para calcular f
n
segn (.).
e) Calcular f

de dos formas distintas: con la funcin defnida


en el ejercicio ..a) y con la funcin binet2.
Son iguales los valores encontrados?, cuntos dgitos tiene
cada uno?
Las diferencias se deben a errores numricos en el clculo de
math.sqrt y otras operaciones con decimales. e
t.{. Venrajas y desvenrajas de la recursn Pg. zo,
Ejercicio . (E. Zeckendorf ()). Todo nmero entero se puede
escribir, de forma nica, como suma de (uno o ms) nmeros de
Fibonacci no consecutivos, es decir para todo n N existe una nica
representacin de la forma
n = b

+ b

+ + b
m
f
m
, (.)
donde b
m
= , b
k
, , y b
k
b
k+
= para k = , . . . , m .
Por ejemplo, = + = f

+ f

, = + + = f

+ f

+ f

.
Defnir una funcin para calcular esa representacin (dando por
ejemplo una lista de los ndices k para los que b
k
= en la igual-
dad (.)). Comprobar con algunos ejemplos la veracidad de la sali-
da. e
.. Ventajas y desventajas de la recursin
Expliquemos un poco cmo funciona recursin.
Como sabemos, una funcin ocupa un lugar en la memoria al
momento de ejecucin, conceptualmente llamado marco o espacio o
contexto de la funcin. Ese marco contiene las instrucciones que debe
seguir y lugares para las variables locales, como se ilustra en la fgura ..
Cada vez que la funcin se llama a s misma, podemos pensar
que se genera automticamente una copia de ella (tantas como sean
necesarias), cada copia con su marco propio. Cuando termina su tarea,
la copia se borra y el espacio que ocupaba es liberado (y la copia no
existe ms).
Este espacio de memoria usado por recursin no est reservado
con anterioridad, pues no se puede saber de antemano cuntas veces
se usar la recursin. Por ejemplo, para calcular n! recursivamente
se necesitan unas n copias de la funcin: cambiando n cambiamos
el nmero de copias necesarias. Este espacio de memoria especial se
llama stack o pila de recursin. Python impone un lmite de unas
llamadas para esa pila.
Pg. zo8 Cap|rulo t. Recursn
Recursin es muy inefciente, usa mucha memoria (llamando cada
vez a la funcin) y tarda mucho tiempo. Peor, como no tiene memoria
(borra la copia de la funcin cuando ya se us) a veces debe calcular
un mismo valor varias veces.
Por ejemplo, para calcular el nmero de Fibonacci f
n
es sufciente
poner los dos primeros y construir la lista mirando a los dos anteriores
(como hicimos en el ejercicio ..a)), obteniendo un algoritmo que
tarda del orden de n pasos.
En cambio, para calcular f

recursivamente la computadora hace


los siguientes pasos, donde cada rengln es una llamada a la funcin:
f

= f

+ f

= f

+ f

= f

+ f

= f

+ f

realizando un total de llamadas (haciendo otras tantas copias) adems


de la inicial.
Una forma intuitiva de ver la inefciencia de la recursin, es cal-
cular f
n
con las dos versiones del ejercicio ., comparando a ojo
el tiempo que tarda cada una cuando n es aproximadamente o
(dependiendo de la rapidez de la mquina).
Otra forma ms cientfca es mediante el siguiente ejercicio.
Ejercicio .. Usando un contador global, defnir una funcin para
calcular el n-simo nmero de Fibonacci, imprimiendo la cantidad de
llamadas a la funcin recursiva, siguiendo un esquema del tipo:
def llamadasafibo(n):
...
global cont
t.y. Los Grandes Clscos de la Recursn Pg. zo
def fibc(n):
...
cont = 0
sol = fibc(n)
print("Se hicieron", cont, "llamadas")
return sol
donde la funcin interna es algo como:
def fibc(n):
"""Fibonacci recursivo con contador global."""
global cont
cont = cont + 1 # pas por ac: incrementar
if n < 3:
return 1
return fibc(n - 1) + fibc(n - 2)
Por supuesto que el peligro al declarar cont como global es que ha-
ya otra variable global con ese identifcador. La solucin adecuada
es usar variables no locales con nonlocal, que no veremos.
Usando llamadasafibo, encontrar la cantidad de llamadas para
calcular f

, f

y f

.
En el ejercicio . vemos lo absurdo de usar recursin para
calcular los nmeros de Fibonacci. e
.. Los Grandes Clasicos de la Recursion
La recursin nos permite hacer formulaciones que parecen ms
naturales o elegantes, como el algoritmo de Euclides, o el clculo de los
nmeros de Fibonacci, pero en los ejemplos que vimos es ms efciente
usar while o for. En esta seccin estudiamos problemas que no son
sencillos de resolver usando solamente lazos, y recursin muestra su
potencia.
Pg. z,o Cap|rulo t. Recursn
Ejercicio . (las torres de Hanoi). Segn la leyenda, en un templo
secreto de Hanoi hay agujas y discos de dimetro creciente y los
monjes pasan los discos de una aguja a la otra mediante movimientos
permitidos. Los discos tienen agujeros en sus centros de modo de
encajar en las agujas, e inicialmente todos los discos estaban en la
primera aguja con el menor en la cima, el siguiente menor debajo,
y as sucesivamente, con el mayor debajo de todos. Un movimiento
permitido es la transferencia del disco en la cima desde una aguja a
cualquier otra siempre que no se ubique sobre uno de dimetro menor.
Cuando los monjes terminen de transferir todos los discos a la segunda
aguja, ser el fn del mundo.
Nuestra intencin es defnir una funcin para realizar esta transfe-
rencia, mostrando los pasos realizados.
Supongamos que tenemos n discos, pintados de a n, de menor
a mayor, y que llamamos a las agujas a, b y c.
Para pasar los n discos de a a b, en algn momento tendremos que
pasar pasar al disco n de a a b, pero nicamente lo podemos hacer si
en a est slo el disco n y en b no hay ningn disco. Es decir, tenemos
que pasar los n discos ms chicos de a a c, luego el disco n de a a b,
y fnalmente pasar los n discos de c a b.
Ahora, para pasar n discos de a a c, debemos pasar n discos
de a a b, pasar el disco n a c, y luego pasar n discos de b a c. Y
as sucesivamente.
Esto lo podemos expresar con una funcin pasar que informal-
mente podramos poner como:
funcin pasar(n):
pasar n discos de una aguja a otra
si n = :
pasar el disco
en otro caso:
pasar(n )
pasar el disco n
pasar(n )
t.y. Los Grandes Clscos de la Recursn Pg. z,t
Tenemos que ser un poco ms especfcos, ya que las agujas en cada
caso son distintas. As, para pasar de la aguja a a b debemos usar c
como intermedia, para pasar de c a b debemos usar a como intermedia,
etc.
Si genricamente llamamos x, y y z a las agujas (que pueden ser a,
b y c en cualquier orden), podemos poner
def pasar(k, x, y, z):
"""Pasar los discos 1,..., k de x a y usando z."""
if k == 1:
print(pasar el disco 1 de, x, a, y)
else:
pasar(k - 1, x, z, y)
print(pasar el disco, k, de, x, a, y)
pasar(k - 1, z, y, x)
En la funcin hanoi (en el mdulo recursion2), pusimos a pasar
como una funcin interna, donde las agujas se indican con las letras
a, b y c.
a) Agregar un contador (global) para contar la cantidad de veces
que se transfere un disco de una aguja a otra, imprimiendo su
valor al terminar.
En base a este resultado (para n = , , , , ) conjeturar la
cantidad de movimientos necesarios para transferir n discos
de una aguja a otra, y demostrarlo.
Sugerencia:
n
= +
n
= + (
n
).
b) Suponiendo que transferen un disco por segundo de una aguja
a otra, cuntos aos tardarn los monjes en transferir los
discos de una aguja a la otra?
c) Cuntos aos tardara una computadora en calcular la solu-
cin para n = , suponiendo que tarda un nanosegundo (ns)
por movimiento
()
(nano = dividir por mil millones)?
()
Y que no hay cortes de luz!
Pg. z,z Cap|rulo t. Recursn
Un gigahercio (GHz) es

(mil millones) de ciclos por segun-


do, de modo que las computadoras comunes actuales trabajan
a unos ciclos por ns. Suponiendo que la computadora reali-
za una instruccin por ciclo y teniendo en cuenta que deben
hacerse algunos clculos por movimiento, la estimacin de
ns por movimiento nos da (a muy grandes rasgos) una idea
de lo que podra hacer hoy una computadora personal .
d) Bajo la misma suposicin sobre la velocidad de la computado-
ra del apartado anterior, cul es el valor mximo de n para
calcular los movimientos en minuto?
e) Modifcar la funcin hanoi de modo que las agujas a, b y c
se representen por listas con los nmeros que representan los
discos, y que en cada paso se imprima el nmero de paso y los
discos en cada aguja.
Inicialmente debe ser
a = |n, n , . . . , |, b = ||, c = ||,
y al terminar debe ser
a = ||, b = |n, n , . . . , |, c = ||.
Por ejemplo:
>>> hanoi(3)
Paso 0
a: [3, 2, 1]
b: []
c: []
Paso 1
a: [3, 2]
b: [1]
c: []
Paso 2
a: [3]
t.y. Los Grandes Clscos de la Recursn Pg. z,
Tapa del juego original Fotografa del juego
Figura .: Las torres de Hanoi.
b: [1]
c: [2]
...
Sugerencia: trabajar con las listas como pilas.
Python tiene una ilustracin animada del problema con discos
en el mdulo minimal_hanoi.
En MS-Windows, buscarlo en \Lib\turtledemo dentro del
directorio donde est instalado Python.
Hay muchas variantes del problema. Por ejemplo, que los discos
no estn inicialmente todos sobre una misma aguja, o que haya
ms de tres agujas.
Las imgenes de la fgura . fueron tomadas respectivamente
de
()
http://www.cs.wm.edu/~pkstoc/
http://en.wikipedia.org/wiki/Tower
_
of
_
Hanoi.
k Las torres de Hanoi es un juego inventado en :88 por el matema-
tico frances Edouard Lucas (:8::8:), quien agrego la leyenda.
El juego, ilustrado en la fgura :.:, usualmente se les da a los
chicos con entre y o discos, a veces de distintos colores. ^otable-
mente, variantes del juego se usan en tratamiento e investigacion
()
Enlaces vlidos a febrero de .
Pg. z,{ Cap|rulo t. Recursn
1
/ \
1 1
/ \ / \
1 2 1
/ \ / \ / \
1 3 3 1
/ \ / \ / \ / \
1 4 6 4 1
Figura .: Tringulo de Pascal de nivel .
de psicologa y neuro-psicologa.
Lucas es mas conocido matematicamente por su test de primali-
dad variantes del cual son muy usadas en la actualidad para
determinar si un numero es primo o no. e
.. Contando objetos combinatorios
Es posible dar una defnicin inductiva de los coefcientes bino-
miales, alternativa de la que vimos en (.):
_
n

_ = _
n
n
_ = y _
n
k
_ = _
n
k
_ + _
n
k
_ si < k < n. (.)
Recordemos que {
n
k
) representa la cantidad de subconjuntos con
exactamente k elementos si el total tiene n. As, si I
n
= , . . . , n,
(.) puede interpretarse diciendo que que slo hay un conjunto sin
elementos, slo hay un conjunto con todos los elementos, y un subcon-
junto de I
n
que tiene k elementos ( < k < n), o bien contiene a n y
sacndolo tenemos un subconjunto con k elementos de I
n
o bien
no contiene a n y entonces es un subconjunto con k elementos de I
n
.
La ltima parte de la propiedad (.) da lugar al llamado triangulo
de Pascal, que se obtiene poniendo un en la primera fla, y luego
en cada fla siguiente la suma de los elementos consecutivos de la
t.o. Conrando objeros combnaroros Pg. z,y
1 1 1 1
1
1
2
3
3
6
4
10
5
15
1 4 10 20 35
Figura .: Contando la cantidad de caminos posibles.
fla anterior, empezando y terminando con , como se muestra en la
fgura ..
Ejercicio .. Defnir una funcin recursiva para calcular {
n
k
) en
base a (.). e
Ejercicio .. Para m, n N, consideremos una cuadrcula rectan-
gular de dimensiones m n ( en la fgura .), e imaginmosnos
que se trata de un mapa, donde los segmentos son calles y los puntos
remarcados son las intersecciones.
Nos preguntamos de cuntas maneras podremos ir desde la es-
quina ms hacia el sudoeste, de coordenadas (, ), a la esquina ms
hacia el noreste, de coordenadas (m, n), si estamos limitados a reco-
rrer las calles nicamente en sentido oesteeste o surnorte, segn
corresponda.
Para resolver el problema, podemos pensar que para llegar a una
interseccin hay que hacerlo desde el oeste o desde el sur (salvo cuando
la interseccin est en el borde oeste o sur), y por lo tanto la cantidad
de caminos para llegar a la interseccin es la suma de la cantidad de
caminos llegando desde el oeste (si se puede) ms la cantidad de cami-
nos llegando desde el sur (si se puede). Los nmeros en la fgura .
Pg. z,o Cap|rulo t. Recursn
indican, para cada interseccin, la cantidad de caminos para llegar all
desde (, ) mediante movimientos permitidos.
a) Defnir una funcin recursiva para calcular la cantidad h(m, n)
de caminos para llegar desde (, ) a (m, n), donde m y n son
enteros positivos.
Sugerencia: h(m, n) = h(m, n ) + h(m , n) si m y n
son positivos (considerar tambin los casos m = o n = ).
En cursos de matemtica discreta se demuestra que h(m, n)
es el nmero combinatorio {
m+n
n
), lo que podemos apreciar
comparando el rectngulo de la fgura . con el tringulo
de Pascal de la fgura ..
b) Modifcar la funcin en a) de modo de calcular la cantidad de
caminos cuando la interseccin (r, s) est bloqueada y no se
puede pasar por all, donde < r < m y < s < n.
Sugerencia: poner h(r, s) = .
c) Supongamos ahora que, al revs del apartado anterior, para ir
de (, ) a (m, n) tenemos que pasar por (r, s) (por ejemplo,
para llevar a (m, n) la pizza que compramos en la esquina
(r, s)). Defnir una funcin para esta nueva posibilidad.
Sugerencia: puedo armar un camino de (, ) a (m, n) to-
mando cualquier camino de (, ) a (r, s) y despus cualquier
camino de (r, s) a (m, n). e
Ejercicio .. Resolver el ejercicio anterior cuando se permite tam-
bin ir en diagonales suroeste-noreste, es decir, pasar de (x, y) a (x +
, y + ) en un movimiento (cuando x < m y y < n). e
.. Las grandes listas: otro peligro de la recursin
Un problema muy distinto al de contar objetos, como hicimos con
los caminos del ejercicio ., es generarlos, por ejemplo para encontrar
alguno o todos los que satisfacen cierto criterio, y es muy comn caer
en la trampa de fabricar una gran lista de objetos innecesariamente.
t.,. Las grandes lsras Pg. z,,
Por ejemplo, supongamos que queremos obtener todos los subcon-
juntos de I
n
= , . . . , n.
Una de las formas de hacerlo es usar que o bien un subconjunto
no contiene a n, y entonces es un subconjunto de I
n
, o bien s lo
contiene, y entonces es un subconjunto de I
n
al cual se le agrega n.
Esta idea, que puede usarse para demostrar que I
n
tiene
n
subcon-
juntos, nos lleva a considerar:
def subconjuntosNO(n):
"""Lista de subconjuntos de {1,..., n}."""
if n == 0: # no hay elementos
return [[]] # slo el conjunto vaco
subs = subconjuntosNO(n-1)
return subs + [s + [n] for s in subs]
(.)
Aunque para conjuntos el orden no importa y no hay elementos re-
petidos, los representamos mediante listas como en la seccin ..
Veamos el porqu de la seal en esta construccin.
Ejercicio . (subconjuntos I). Probar la funcin en (.) para
n = , , , viendo que se obtienen los resultados esperados. Luego
comprobar que para n = , , la cantidad de subconjuntos es
n
.
Atencion: antes que dejar que en la terminal aparezcan

=
listas, es mejor hacer una asignacin del tipo s = subconjuntosNO(8)
y luego averiguar len(s), o bien poner len(subconjuntosNO(8)) di-
rectamente. e
El algoritmo para defnir subconjuntosNO en (.) es interesante
en cuanto se parece a una demostracin de matemticas, pero slo
debe usarse en condiciones extremas. Por ejemplo, si n = tendre-
mos subconjuntos y difcilmente necesitemos tener a todos
a la vez. En general querremos encontrar algunos de ellos con ciertas
propiedades, o contarlos, etc., con lo que las ms de las veces bastar
mirarlos en secuencia, uno a la vez.
Pg. z,8 Cap|rulo t. Recursn
Ejercicio .. Para entender el porqu de la insistencia de no tener
a todos los objetos en una gran lista, supongamos que a
n
es la lista
obtenida mediante subconjuntosNO(n).
a
n
tiene
n
listas, y eliminando los corchetes, en total tiene n
n
nmeros (por qu?).
()
a) Suponiendo que cada nmero en a
n
ocupa bytes ( bits),
calcular la cantidad de bytes que ocupan los nmeros en a
n
para n = , y , sin construir a
n
!
b) Si la memoria de la computadora que usamos tiene gigabytes
( GB =

bytes), cul es el valor mximo de n que nos permi-


te tener todos los nmeros de a
n
en la memoria (suponiendo
que all slo estn los nmeros de a
n
)?
Respuesta: n = .
Cuando no hay ms lugar en la memoria, los sistemas ope-
rativos en general usan espacio en disco moviendo los datos
constantemente entre la memoria central y el disco, lo que
hace que las operaciones sean mucho ms lentas.
c) Es posible que Python no use exactamente bytes por nmero,
o que la mquina tenga ms o menos memoria, por lo que el va-
lor de n obtenido en el apartado anterior es slo una estimacin
del lugar que ocupan los nmeros.
Probar subconjuntosNO(n), por ejemplo encontrando la
cantidad de subconjuntos, comenzando desde n = y luego ,
, etc., hasta que los tiempos sean muy largos,
()
comprobando
que en cada caso la cantidad de subconjuntos obtenidos es
n
.
Se podr comprobar que difcilmente se pueda llegar a n =
, ya sea por el tiempo o por la memoria. e
Como conclusin, cuando el nmero de objetos a generar es muy
()
Sugerencia: un conjunto y su complemento tienen n elementos entre los dos.
()
Tener en cuenta que al pasar de n a n + , bsicamente se duplican el tiempo que
se tarda y la memoria que se necesita.
t.8. yield Pg. z,
grande, como
n
o n!, independientemente de la efciencia del algorit-
mo que usemos para generarlos:
deben evitarse en lo posible las grandes listas
como la de la funcion subconjuntosNO en (.).

.. yield
Hay distintas tcnicas para construir los objetos uno a la vez, evi-
tando generar la gran lista. Por ejemplo, podemos poner una funcin
dentro de otra envolvente, como hicimos en la funcin hanoi del ejer-
cicio .. En esta seccin estudiaremos otra tcnica basada en la
sentencia yield de Python.
Una forma de calcular los primeros n nmeros de Fibonacci (y no
slo uno), es construyendo una lista con un lazo for:
lista = []
a, b = 0, 1
for k in range(n):
a, b = a + b, a
lista.append(a)
Si no necesitamos la lista completa, y nos basta con mirar a cada
nmero de Fibonacci individualmente, podemos usar la sentencia
yield, que en este contexto podra traducirse como producir, proveer
o dar lugar a:
()
def fibgen(n):
"""Generar n nmeros de Fibonacci."""
a, b = 0, 1
for k in range(n):
a, b = a + b, a
yield a
(.)
()
yield se pronuncia yld con la y de los cuyanos y no la de los porteos.
Pg. z8o Cap|rulo t. Recursn
Observar que en este nuevo esquema yield a reemplaza a la
instruccin lista.append(a) en el esquema anterior, evitando la
construccin de la lista. Por otra parte, no es necesario hacer un lazo
for para cada nmero de Fibonacci, a diferencia de lo que hicimos en
el ejercicio ..
Estudiemos el comportamiento y propiedades de fibgen.
Ejercicio ..
a) Defnir la funcin fibgen segn el esquema (.) en un m-
dulo, y ejecutarlo.
b) fibgen en principio es una funcin como cualquier otra. Pero
a pesar de que no tiene un return explcito, su resultado no es
None sino un objeto de tipo o clase generator (generador).
Poner en la terminal:
fibgen
type(fibgen)
fibgen(10)
type(fibgen(10))
c) Los generadores como fibgen(n) son un caso especial de ite-
radores, y su comportamiento tiene similitudes con el de las
secuencias cuando se usan con for. Evaluar:
[x for x in range(10)]
[x for x in fibgen(10)]
for x in fibgen(5):
print(x)
d) Anlogamente, pueden pasarse a lista o tupla:
list(range(5))
list(fibgen(5))
e) A diferencia de las secuencias, podemos ir generando un ele-
mento a la vez mediante la funcin next (siguiente).
Evaluar:
it = fibgen(3) # iterador
t.8. yield Pg. z8t
next(it) # primer elemento
next(it) # siguiente
next(it) # siguiente
next(it) # no hay ms
O algo as: las secuencias pueden ponerse como iteradores
con iter (que no veremos en el curso):
it = iter([mi, mama, me, mima])
next(it)
... e
Analicemos lo que acabamos de ver.
Teniendo presente la defnicin en (.), cuando ponemos it
= fibgen(n) la primera vez que llamamos a next(it) se realizan las
instrucciones a, b = 0, 1, se entra al lazo while, se ejecuta a, b =
a + b, a, y se retorna el valor de a (en este caso ), como si se tratara
de return en vez de yield.
A diferencia de una funcin con return, al ejecutarse yield los
valores locales se mantienen, de modo que al llamar por segunda vez a
next(it) se contina desde el ltimo yield ejecutado, como si no se
hubiera retornado, continuando la ejecucin de instrucciones hasta
encontrar el prximo yield, y as sucesivamente.
En la defnicin de fibgen(n) el lazo for se realiza a lo sumo n
veces, se pueden construir hasta n elementos con el iterador, y llamadas
posteriores a next(it) dan error. Sin embargo, el generador/iterador
es lo sufcientemente inteligente como para terminar cuando se lo usa
en un lazo for, como en el ejercicio ..c).
Ejercicio .. Si en la defnicin de la funcin generadora hay un
lazo infnito, podemos hacer cuantas llamadas queramos.
a) Considerar la funcin
def naturales():
"""Genera todos los naturales."""
k = 0
Pg. z8z Cap|rulo t. Recursn
while True:
k = k + 1
yield k
y evaluar:
it = naturales() # iterador
[next(it) for i in range(5)]
next(it)
[next(it) for i in range(5)]
it2 = naturales() # otro iterador
next(it2) # comienza con 1
next(it) # sigue por su lado
b) Considerar ahora la funcin
def periodico(n):
"""Repetir con perodo n."""
a = 0
while True:
if a == n: # volver al principio
a = 1
else:
a = a + 1
yield a
y evaluar:
it = periodico(7)
[next(it) for k in range(20)] e
c) Cambiar la defnicin de fibgen en (.) de modo de obtener
todos los nmeros de Fibonacci (y no slo n) con el iterador. e
.. Generando objetos combinatorios
Veamos cmo yield nos permite evitar la construccin de la gran
lista del ejercicio ..
t.. Generando objeros combnaroros Pg. z8
Ejercicio . (subconjuntos II). Para construir los subconjuntos de
I
n
podemos considerar:
def subs(n):
"""Generar los subconjuntos de {1,...,n}."""
if n == 0: # no hay elementos
yield [] # nico subconjunto
else:
for s in subs(n-1):
yield s # subconjunto de {1,...,n-1}
s.append(n) # agregar n al final
yield s # con n
s.pop() # sacar n
a) Poner la funcin en un mdulo, ejecutarlo, y evaluar:
for x in subs(3):
print(x)
Comparar el resultado cambiando for s in subs(3) por
for s in subconjuntosNO(3).
b) Para contar los elementos podemos poner:
c = 0
for x in subs(5):
c = c + 1
c
c) La variable s dentro de la funcin subs es una lista y por lo
tanto mutable, lo que puede llevar a confusin. Evaluar
it = subs(3) # hay 8 subconjuntos
x = next(it)
x # x es el primero
for k in range(4): # hacemos 4 ms
next(it)
x # ahora x es el 5to. y no el 1ro.
Pg. z8{ Cap|rulo t. Recursn
la lista s en subs es compartida por todas las llamadas
sucesivas.
Adems, s se comporta como una pila: empezando de la lista vaca,
en s vamos agregando y sacando elementos de atrs. Al terminar de
generar los elementos, s termina siendo la lista vaca.
d) Comparar con los apartados c) y d) del ejercicio .:
[x for x in subs(3)]
list(subs(3))
Si por alguna razon necesitamos conservar resultados
intermedios, tenemos que hacer copias de las listas (ver
el ejercicio .: y siguientes).
e) Otra forma de ver el comportamiento de s es eliminar el ren-
gln s.pop() en la defnicin de subs. En ese caso, qu espe-
raras? e
En el ejercicio . vimos que el iterador asociado a subs(n) usa
una nica lista que se va modifcando. Desde ya que esta lista no
ocupa ms de n lugares para guardar los nmeros, a diferencia de
la gran lista de subconjuntosNO(n) que guarda n
n
nmeros
simultneamente en la memoria. Los tiempos necesarios para recorrer
todos los subconjuntos de I
n
con una y otra funcin son bastante
comparables, ya que en defnitiva se basan en el mismo algoritmo,
aunque la versin de la gran lista en general tiene que lidiar con ms
estructuras de datos y tarda ms. La gran diferencia (exponencial!)
radica en la cantidad de memoria que necesitan ambos.
Ejercicio .. Repetir el ejercicio ..c) con subs(n) para n =
, , , . . . , comparando los resultados en uno y otro caso.
La versin con gran lista para n = cabe en la memoria prin-
cipal de mi mquina, pero tarda entre y veces lo que tarda la
versin con yield. e
t.. Generando objeros combnaroros Pg. z8y
En el mdulo recursion2 se defne la funcin subs, as como las
funciones subsnk, que genera los subconjuntos de I
n
con exactamente
k elementos, y perms, que genera todas las permutaciones de I
n
.
El algoritmo de subsnk se basa en que un subconjunto de k ele-
mentos de I
n
o bien no tiene a n, y entonces es un subconjunto de I
n
con k elementos, o bien s lo tiene, y entonces al sacarlo obtenemos un
subconjunto de I
n
con k elementos.
Es una forma de pensar la identidad {
n
k
) = {
n
k
) + {
n
k
) para
< k < n. Ver (.) y los comentarios asociados.
Para construir las permutaciones con perms, observamos que una
permutacin de I
n
se obtiene a partir de una permutacin de I
n
inser-
tando n enalguno de los n lugares disponibles (al principio, entremedio
o al fnal).
Esto da una forma de demostrar que n! = (n )! n: cada una
de las permutaciones de I
n
da lugar a n permutaciones de I
n
.
Una versin bastante menos efciente es reemplazar el intercambio
por inserciones y borrados explcitos en cada paso, debido a la
inefciencia de estas operaciones en Python (como mencionamos
otras veces, por ejemplo, en la pgina ):
...
for p in perms(n-1):
for i in range(n):
p.insert(i, n)
yield p
p.pop(i)
...
Ejercicio .. Repetir los apartados del ejercicio ., cambiando
subs por subsnk(6, 3) y perms(4) en los lugares adecuados.
En subsnk no hay una unica lista s, sino que se generan
k + listas. ||, ||, |, |, . . . , |, , . . . , k|.
En cambio, perms usa siempre la misma lista s, pero no
se comporta como una pila, ya que n se agrega al fnal y va
cambiando de posicion hasta salir por adelante. e
Pg. z8o Cap|rulo t. Recursn
Ejercicio ..
a) Defnir una funcin cadenas(m, n) para generar todas las
listas de longitud n con los elementos de , ..., m (m, n
N). Por ejemplo, si m = y n = , las posibilidades son:
|, |, |, |, |, |, |, |, |, |, |, |, |, |, |, |, |, |.
Imprimir todas las cadenas para m = y n = , y contarlas
para m = y n = (en general hay m
n
).
b) Podemos pensar que las listas del apartado anterior son los coe-
fcientes de un nmero escrito en base m (ver la seccin .).
Defnir una funcin para encontrar las listas del apartado ante-
rior recorriendo los nmeros entre y m
n
(inclusivos). e
Ejercicio . (camino de Hamilton). Un camino de Hamilton en
un grafo es un camino simple (sin vrtices repetidos) que pasa por
todos los vrtices del grafo.
No todos los grafos tienen un camino as. El grafo debe ser al menos
conexo, pero la conexin tampoco es sufciente ya que los rboles en
general (salvo que se reduzcan a un camino) no tienen estos caminos.
Siguiendo un esquema como:
para cada permutacin p de , . . . , n:
si p es camino del grafo:
retornar p y salir
reportar que no existe camino de Hamilton
defnir una funcin hamilton(n, aristas) que dado un grafo por
su cantidad de vrtices n y la lista de aristas, determine si el grafo tiene
un camino de Hamilton y en ese caso lo exhiba, considerando todas
las permutaciones de I
n
posibles y terminando en cuanto se encuentre.
Recordar el ejercicio ..
Por supuesto que el algoritmo propuesto es muy brutal, y se reduce
esencialmente a un barrido sobre todas las soluciones posibles,
slo que terminando en cuanto se pueda.
t.to. Ejerccos adconales Pg. z8,
En este sentido, vemos la importancia de no generar la gran
lista, sino generar las permutaciones de a una.
Dada la importancia del problema, existen algoritmos mucho
mas efcientes, aunque no se conocen algoritmos verdaderamente
efcientes (por ejemplo, polinomiales).
k V. R. Hamilton (:8o,:8o,) ideo un juego en el que haba que
recorrer los vertices de un dodecaedro con los nombres de capitales
del mundo, y de all el nombre del camino.
Caminos y ciclos de Hamilton son usados en cosas tan diversas
como criptografa o el problema del viajante en investigacion
operativa.
Hamilton es mucho mas conocido por sus contribuciones funda-
mentales a la fsica (en electromagnetismo y mecanica cuantica) y
matematicas (cuaterniones en algebra, principios variacionales y
ecuaciones diferenciales). e
.. Ejercicios adicionales
Ejercicio ..
a) Usando el ejercicio ., primero conjeturar y luego demostrar
la relacin de recurrencia para la cantidad de llamadas c(n)
de la versin recursiva para calcular el n-simo nmero de
Fibonacci.
Respuesta: c(n) = c(n ) + c(n ) + .
b) Ver que b(n) = c(n) + satisface la misma ecuacin de recu-
rrencia que f
n
, y por lo tanto b(n) = f
n
.
Sugerencia: sumar miembro a miembro en la relacin de
recurrencia para c(n) y observar que b() = b() = .
En conclusin: en la versin recursiva bsicamente el doble de
llamadas a la funcin interna que el valor mismo de f
n
! e
Ejercicio .. A veces queremos ordenar de todas las formas po-
sibles objetos que pueden estar repetidos. Por ejemplo, si queremos
Pg. z88 Cap|rulo t. Recursn
construir todas las cadenas de caracteres posibles que se pueden hacer
con las letras de mimamamemima usando todas las letras.
Como el orden es importante, estos objetos son un tipo de per-
mutaciones.
a) En cursos de matemtica discreta se demuestra que si hay k
objetos distintos cada uno apareciendo n
i
veces, la cantidad de
permutaciones con repeticin es el coefciente multinomial
_
n

+ n

+ + n
k
n

, n

, . . . , n
k
_ =
(n

+ n

+ + n
k
)!
n

! n

! . . . n
k
!
.
Por ejemplo, en mimamamemima la letra a aparece veces,
e aparece vez, i aparece veces, y m aparece veces,
por lo que la cantidad de permutaciones con repeticin es
( + + + )!
! ! ! !
= .
Defnir una funcin multinomial(lista) para calcular es-
tos coefcientes, donde lista es de la forma [n1, n2,...].
b) Defnir una funcin permsrep(lista) para generar todas las
permutaciones posibles de una lista dada que puede tener re-
peticiones. Por ejemplo, si la lista es [m, i, m, a],
hay permutaciones posibles, como:
[m, i, m, a], [m, i, a, m],
[m, a, i, m], [a, m, i, m],
[m, m, i, a], [m, m, a, i], etc.
Aclaracion : la lista que es argumento no debe modifcarse.
Aclaracion : no construir una gran lista.
Sugerencia: imitar la funcin perms, fnalizando el intercam-
bio en cuanto se encuentra un elemento repetido.
c) Aplicar la funcin permsrep (o variante) para encontrar todas
las palabras distintas que se pueden escribir permutando las
letras de mimama (sin espacios).
t.tt. Comenraros Pg. z8
Algunas de las palabras a obtener son: mimama, mimaam,
mimmaa, miamma, miamam, etc. (hay posibles). e
.. Comentarios
En cursos de matemtica discreta es usual estudiar las relaciones
de recurrencia lineales, homogeneas y con coefcientes constantes,
a
n
= Aa
n
+ B a
n
para n > , (.)
donde A y B son constantes. Se ve que si la ecuacin cuadrtica
caracterstica, x

= Ax + B, tiene dos races distintas r y r

(po-
dran ser complejas), entonces existen constantes c y c

de modo
que los nmeros a
n
en (.) se pueden expresar como
a
n
= c r
n
+ c

(r

)
n
.
La frmula de Binet (.) es un caso particular de esta relacin.
Los nmeros de Fibonacci aparecen en contextos muy diversos,
algunos insospechados como la forma de las fores del girasol, y
tienen aplicaciones prcticas y tericas.
Por ejemplo, han sido usados para resolver problemas de con-
fabilidad de comunicaciones y algunas bases de datos (rboles de
Fibonacci) se construyen usando propiedades de estos nmeros.
En cuanto a aplicaciones tericas, vale la pena mencionar
que en el Congreso Internacional de Matemticas de , Da-
vid Hilbert () propuso una serie de problemas que en
gran parte determinaron las investigaciones matemticas duran-
te el siglo XX. El dcimo de estos problemas pide encontrar un
algoritmo para determinar si un polinomio con coefcientes en-
teros, arbitrariamente prescripto, tiene races enteras (resolver la
ecuacin diofntica asociada). En Yuri Matijasevich (quien
entonces tena aos) demostr que el problema es irresoluble,
usando nmeros de Fibonacci!
Pg. zo Cap|rulo t. Recursn
En este captulo vimos que si bien recursin en general es inef-
ciente, se puede mejorar su desempeo con distintas tcnicas.
Tambin vimos que, de cualquier forma, siempre nos topa-
mos con la denominada explosin combinatoria: la cantidad
exponencial de objetos a examinar cuando usamos tcnicas de
barrido.
Uno de los grandes desafos de las matemticas es encontrar
algoritmos efcientes para resolver problemas asociados, aun-
que como ya mencionamos difcilmente existan algoritmos
verdaderamente efcientes: entre los problemas del milenio (re-
medando los problemas planteados por Hilbert un siglo antes)
se encuenctra justamente decidir si P ^P.
Los generadores va yield son un caso particular de corutinas,
que existen desde hace varios aos en algunos lenguajes de pro-
gramacin, estando Simula y Modula- entre los primeros en
usarlas.
Simula fue desarrollado en los extendiendo el lenguaje
Algol, del cual desciende tambin Pascal. A su vez, Modula-
fue desarrollado a fnes de los por N. Wirth como sucesor
profesional de Pascal, que es de un carcter ms pedaggico.
En el mdulo estndar itertools de Python se generan permuta-
ciones, combinaciones, y otros objetos combinatorios. Nosotros
no veremos este mdulo en el curso.

Parte III
Apndces
Apndice A
Mdulos y archivos
mencionados
dados (ejercicios . y .)
"""Simulaciones con dados usando random en Python."""
import random
def dado1():
"""Simular tirar un dado, obteniendo un entero entre 1 y 6."""
return random.randint(1, 6)
def dado2(k):
"""Veces que se tira un dado hasta que aparece k.
k debe ser entero, 1 <= k <= 6.
"""
veces = 0
while True: # repetir
veces = veces + 1
if random.randint(1, 6) == k: # hasta obtener k
break
dearchvoaconsola Pg. z
return veces
dearchivoaconsola (ejercicio .)
"""Leer un archivo de datos e imprimirlo en la consola."""
entrada = input(Ingresar el nombre del archivo a leer: )
lectura = open(entrada, r, encoding=utf-8) # abrirlo
for renglon in lectura:
print(renglon, end=)
lectura.close() # y cerrarlo
decimales (captulo )
"""Algunas propiedades de la representacin decimal en Python.
- epsmaq: psilon de mquina
- epsmin: psilon mnimo (menor potencia de 2 que es positiva).
- maxpot2: mxima potencia de 2 que se puede representar.
"""
def epsilon(inic):
"""Menor potencia de 2 que sumada a inic da mayor que inic.
- Suponemos 0 < inic < 1.0 + inic.
- epsilon(1.0) es lo que llamamos epsmaq en los apuntes.
"""
x = 1.0
while inic + x > inic:
x = x / 2
return 2
*
x # volver al valor anterior
Pg. z{ Apndce A. Mdulos y archvos menconados
epsmaq = epsilon(1.0)
# clculo de epsmin
x = 1.0
while x > 0:
x, epsmin = x / 2, x
# clculo de maxpot2
x = 1.0
while 2
*
x > x:
x, maxpot2 = 2
*
x, x
eratostenes (ejercicio .)
"""Versin sencilla de la criba de Eratstenes.
Esta es una primera versin que debe mejorarse segn los ejercicios
en el libro.
"""
def criba(n):
"""Lista de primos <= n."""
#----------------------------------------------
# inicializacin
# usamos una lista por comprensin para que todos
# los elementos tengan un mismo valor inicial
# las posiciones 0 y 1 no se usan, pero conviene ponerlas
esprimo = [True for i in range(0, n + 1)]
#----------------------------------------------
# lazo principal
for i in range(2, n+1):
if esprimo[i]:
for j in range(i
*
i, n + 1, i):
eucldesz Pg. zy
esprimo[j] = False
#----------------------------------------------
# salida
# observar el uso del filtro
return [i for i in range(2, n + 1) if esprimo[i]]
euclides2 (ejercicio .)
"""Complicaciones con Euclides usando decimales."""
# mximo nmero de iteraciones para lazos
maxit = 1000
def mcd1(a, b):
"""Clculo de la medida comn segn Euclides.
a y b deben ser positivos.
"""
for it in range(maxit):
if a > b:
a = a - b
elif b > a:
b = b - a
else:
break
print( iteraciones:, it + 1)
if it == maxit - 1:
print(
***
Mximas iteraciones alcanzadas.)
print( b:, b)
return a
def mcd2(a, b):
"""Variante usando restos, a y b positivos."""
for it in range(maxit):
if b == 0:
break
Pg. zo Apndce A. Mdulos y archvos menconados
a, b = b, a % b
print( iteraciones:, it + 1)
if it == maxit - 1:
print(
***
Mximas iteraciones alcanzadas.)
print( b:, b)
return a
# tolerancia permitida
tol = 10
**
(-7)
def mcd3(a, b):
"""Clculo de la medida comn segn Euclides, a y b positivos.
Terminamos cuando la diferencia es chica.
"""
for it in range(maxit):
if a > b + tol:
a = a - b
elif b > a + tol:
b = b - a
else:
break
print( iteraciones:, it + 1)
if it == maxit - 1:
print(
***
Mximas iteraciones alcanzadas.)
print( b:, b)
return a
def mcd4(a, b):
"""Variante usando restos, a y b positivos."""
for it in range(maxit):
if b < tol:
break
a, b = b, a % b
print( iteraciones:, it + 1)
if it == maxit - 1:
print(
***
Mximas iteraciones alcanzadas.)
fargumenro Pg. z,
print( b:, b)
return a
fargumento (ejercicio .)
"""Funcin donde uno de los argumentos es otra funcin."""
def aplicar(f, x):
"""Aplica f a x."""
return f(x)
def f(x):
"""Suma 1 al argumento."""
return x + 1
def g(x):
"""Multiplica el argumento por 2."""
return 2
*
x
ocal (ejercicio .)
"""Ejemplo de funcin definida dentro de otra."""
def fexterna():
"""Ilustracin de variables y funciones globales y locales."""
def finterna(): # funcin interna, local a fexterna
global x # variable global
x = 5 # se modifica ac
x = 2 # x es local a fexterna
print(al comenzar fexterna, x es, x)
finterna()
print(al terminar fexterna, x es, x)
gr1sobrex (ejercicio .)
Pg. z8 Apndce A. Mdulos y archvos menconados
"""Graficar la funcin discontinua 1/x entre -1 y 1.
- La discontinuidad est en x = 0.
- Separamos en partes el dominio: antes y despus de 0 con eps > 0.
- Si eps = 0 da error de divisin por 0.
"""
import graficar
# titulo de la ventana
graficar.titulo = Grfico de 1/x
# cotas
eps = 0.01 # distancia a separar, poner tambin 0
def f(x):
return 1/x
# valores extremos para x
a = -1
b = -a # intervalo simtrico
# valores extremos para y
ymax = 100
ymin = - ymax
graficar.ymax = ymax
graficar.ymin = ymin
# mismo color para ambos tramos
graficar.funcion(f, a, -eps, estilo={fill: blue})
graficar.funcion(f, eps, b, estilo={fill: blue})
# ejes coordenados
graficar.recta((0, 0), (1, 0), estilo={fill: black})
graficar.recta((0, 0), (0, 1), estilo={fill: black})
grafos Pg. z
graficar.mostrar()
grafos (captulo )
"""Funciones para grafos."""
def dearistasavecinos(ngrafo, aristas):
"""Pasar de lista de aristas a lista de vecinos."""
vecinos = [[] for v in range(ngrafo + 1)]
vecinos[0] = None
for u, v in aristas:
vecinos[u].append(v)
vecinos[v].append(u)
return vecinos
def devecinosaaristas(vecinos):
"""Pasar de lista de vecinos a lista de aristas.
Los ndices para los vrtices empiezan desde 1.
"""
ngrafo = len(vecinos) + 1 # no usamos vecinos[0]
aristas = []
for v in range(1, ngrafo):
for u in vecinos[v]:
# guardamos arista slo si v < u para no duplicar
if v < u:
aristas.append([v, u])
return aristas
def recorrido(vecinos, raiz):
"""Recorrer el grafo a partir de una raz.
- La lista de vecinos debe ser de la forma
[None, vecinos[1],..., vecinos[n]]
- Se retornan los vrtices visitados.
Pg. oo Apndce A. Mdulos y archvos menconados
- Los datos son la lista de vecinos y la raz.
- Los ndices para los vrtices empiezan desde 1.
- Se usa una cola lifo.
"""
vertices = range(len(vecinos)) # incluimos 0
padre = [None for v in vertices]
cola = [raiz]
padre[raiz] = raiz
while len(cola) > 0: # mientras la cola es no vaca
u = cola.pop() # sacar uno (el ltimo) y visitarlo
for v in vecinos[u]: # examinar vecinos de u
if padre[v] == None: # si no estuvo en la cola
cola.append(v) # agregarlo a la cola
padre[v] = u # poniendo de dnde viene
return [v for v in vertices if padre[v] != None]
grbiseccion (ejercicio .)
"""Ilustracin del mtodo de la biseccin.
Plantilla ilustrando el mtodo de la biseccin para
encontrar ceros de una funcin: cambiar apropiadamente.
Elegir (interactivamente) los extremos de un intervalo
que encierra al menos un cero de la funcin.
Se imprime genricamente f en los resultados por terminal.
"""
# mdulos de Python
# import math # si se usan funciones trascendentales
# mdulos propios
import graficar, grnumerico
grexplog Pg. ot
# funcin donde encontrar el cero
def f(x):
return x
*
(x + 1)
*
(x + 2)
*
(x - 4/3)
# intervalo
a = -3
b = 2
# constante para el mtodo
eps = 1.0e-7 # error permitido
# leyenda para la funcin en el grfico
leyendaf = f
# otras opciones grficas
graficar.titulo = Ilustracin del mtodo de la biseccin
graficar.leyendaspos = N
# limitar si no se ven bien positivos/negativos
graficar.ymin = -3
graficar.ymax = 5
# ejecucin
grnumerico.biseccion(f, a, b, eps, leyendaf)
grexplog (ejercicio .)
"""Grficos de exp, log y la identidad."""
# mdulos de Python
import math
# mdulos propios
import graficar
graficar.titulo = Comparacin de la exponencial y el logaritmo
Pg. oz Apndce A. Mdulos y archvos menconados
xmin = -2
xmax = 5
ymin = -5
ymax = xmax
graficar.xticks = list(range(xmin, xmax, 2))
graficar.yticks = list(range(ymin + 1, ymax, 2))
eps = 0.001 # log no est definida en 0
graficar.ymin = ymin
graficar.ymax = ymax
graficar.aspecto = False
graficar.funcion(math.exp, xmin, xmax, leyenda=exp(x))
graficar.funcion(math.log, eps, xmax, leyenda=log x)
# identidad para comparar
def identidad(x):
return x
graficar.funcion(identidad, xmin, xmax, leyenda=identidad)
# ejes coordenados en negro
graficar.recta((0, 0), (1, 0), estilo={fill: black})
graficar.recta((0, 0), (0, 1), estilo={fill: black})
graficar.leyendaspos = NO
graficar.mostrar()
grgrsimple (ejercicio .)
"""Ilustracin del uso del mdulo grgrafo para un grafo simple.
Recordar que se pueden mover los vrtices y etiquetas del grafo
con el ratn.
"""
grnewron Pg. o
import grgrafo
#----------------------------------------------
# descripcin del grafo, modificar a gusto
# ejemplo en los apuntes
ngrafo = 6
aristas = [[1, 2],
[1, 3],
[2, 3],
[2, 6],
[3, 4],
[3, 6],
[4, 6]]
#----------------------------------------------
grgrafo.titulo = Ejemplo de grafo en los apuntes
for i in range(1, ngrafo + 1):
grgrafo.vertice(texto=str(i))
for u, v in aristas:
grgrafo.arista(grgrafo.vertices[u], grgrafo.vertices[v])
grgrafo.mostrar()
grnewton (ejercicio .)
"""Ilustracin del mtodo de Newton.
Plantilla ilustrando el mtodo de Newton para encontrar
ceros de una funcin: cambiar apropiadamente.
Elegir (interactivamente) el punto inicial.
La derivada se estima poniendo un incremento bien pequeo.
Se imprime genricamente f en los resultados por terminal.
Pg. o{ Apndce A. Mdulos y archvos menconados
"""
# mdulos de Python
# import math # si se usan funciones trascendentales
# mdulos propios
import graficar, grnumerico
# funcin donde encontrar el cero
def f(x):
return (x + 1)
*
(x - 2)
*
(x - 3)
# intervalo
a = -2
b = 4
# constantes para el mtodo
eps = 1.0e-7 # error permitido
maxit = 20 # mximo nmero de iteraciones
# leyenda para la funcin en el grfico
leyendaf = f
# otras opciones grficas
graficar.titulo = Ilustracin del mtodo de Newton
graficar.leyendaspos = SE
# limitar si no se ven bien positivos/negativos
graficar.ymin = -20
graficar.ymax = 10
# ejecucin
grnumerico.newton(f, a, b, eps, maxit, leyendaf)
grpuntojo (ejercicio .)
"""Ilustracin de la tcnica del punto fijo.
grpunrofjo Pg. oy
Plantilla ilustrando el mtodo de punto fijo iterando una
funcin: cambiar apropiadamente.
Elegir (interactivamente) el punto inicial.
Se imprime genricamente f en los resultados por terminal.
"""
# mdulos de Python
import math # si se usan funciones trascendentes
# mdulos propios
import graficar, grnumerico
# funcin donde encontrar el punto fijo
def f(x):
return math.cos(x)
# intervalo
a = 0
b = 1.2
# constantes para el mtodo
eps = 1.0e-7 # error permitido
maxit = 20 # mximo nmero de iteraciones
# leyenda para la funcin en el grfico
leyendaf = cos
# otras opciones grficas
graficar.titulo = Ilustracin del mtodo de punto fijo
graficar.leyendaspos = S
# limitar si no se ven bien positivos/negativos
# graficar.ymin = -3
# graficar.ymax = 5
Pg. oo Apndce A. Mdulos y archvos menconados
# ejecucin
grnumerico.puntofijo(f, a, b, eps, maxit, leyendaf)
grseno (ejercicio .)
"""Grfico del seno entre 0 y pi."""
# mdulos de Python
import math
# mdulos propios
import graficar
graficar.funcion(math.sin, -math.pi, math.pi)
graficar.mostrar()
holamundo (ejercicio .)
"""Imprime Hola Mundo.
Es un mdulo sencillo para ilustrar cmo se trabaja
con mdulos propios (y tambin cmo se documentan).
"""
print(Hola Mundo)
holapepe (ejercicio .)
"""Ilustracin de ingreso interactivo en Python.
Pregunta un nombre e imprime Hola seguido del nombre.
"""
print(Cmo te llams?)
pepe = input()
print(Hola, pepe, encantada de conocerte)
fwhle Pg. o,
ifwhile (captulo y ejercicio . )
"""Ejemplos sencillos de if y while."""
def espositivo(x):
"""Decidir si el nmero es positivo o no.
El argumento debe ser un nmero.
"""
if x > 0:
print(x, es positivo)
else:
print(x, no es positivo)
def piso(x):
"""Encontrar el piso de un nmero."""
y = int(x) # int redondea hacia cero
if y < x: # x debe ser positivo
print(el piso de, x, es, y)
elif x < y: # x debe ser negativo
print(el piso de, x, es, y - 1)
else: # x es entero
print(el piso de, x, es, y)
def resto(a, b):
"""Resto de la divisin entre los enteros positivos a y b.
Usamos restas sucesivas.
"""
r = a
while r >= b:
r = r - b
print(El resto de dividir, a, por, b, es, r)
def cifras(n):
"""Cantidad de cifras del entero n (en base 10)."""
Pg. o8 Apndce A. Mdulos y archvos menconados
# inicializacin
n = abs(n) # por si n es negativo
c = 0 # contador de cifras
# lazo principal
while True: # repetir...
c = c + 1
n = n // 10
if n == 0: # ... hasta que n es 0
break
# salida
return c
def mcd2(a, b):
"""Mximo comn divisor entre los enteros a y b.
Versin usando divisiones enteras y restos.
mcd2(0, 0) = 0.
"""
# nos ponemos en el caso donde ambos son no negativos
a = abs(a)
b = abs(b)
# lazo principal
while b != 0:
r = a % b
a = b
b = r
# ac b == 0
# salida
return a
numerco Pg. o
numerico (captulo )
"""Algunos mtodos iterativos de clculo numrico."""
def puntofijo(func, xinic):
"""Encontrar punto fijo de func dando punto inicial xinic.
func debe estar definida como funcin.
Se termina por un nmero mximo de iteraciones o
alcanzando una tolerancia permitida.
"""
# algunas constantes
maxit = 200 # mximo nmero de iteraciones
tol = 10
**
(-7) # error permitido
# inicializacin y lazo
yinic = func(xinic)
x, y = float(xinic), float(yinic)
for it in range(maxit):
if abs(y - x) < tol:
break
x, y = y, func(y)
if it + 1 == maxit:
print(
***
Iteraciones mximas alcanzadas)
print( el resultado puede no ser punto fijo)
return y
def newton(func, x0):
"""Mtodo de Newton para encontrar ceros de una funcin.
func debe estar definida como funcin.
x0 es un punto inicial.
Pg. to Apndce A. Mdulos y archvos menconados
La derivada de func se estima poniendo
un incremento bien pequeo.
No se controla si la derivada es 0.
"""
# algunas constantes
dx = 1.0e-7 # incremento para la derivada
tol = 1.0e-7 # error permitido
maxit = 20 # mximo nmero de iteraciones
# estimacin de la derivada de func
def fp(x):
return (func(x + dx/2) - func(x - dx/2))/dx
# inicializacin
y0 = func(x0)
x, y = x0, y0
# lazo principal
for it in range(maxit):
if abs(y) < tol:
break
x1 = x - y/fp(x)
y1 = func(x1)
x, y = x1, y1
if it + 1 == maxit:
print(
***
Iteraciones mximas alcanzadas)
print( el resultado puede no ser raz)
return x
def biseccion(func, poco, mucho):
"""Encontrar ceros de una funcin usando biseccin.
numerco Pg. tt
func debe estar definida como funcin.
poco y mucho deben ser puntos encerrando un cero de func.
"""
# algunas constantes
eps = 1.0e-7 # error permitido
# inicializacin
fpoco = func(poco)
if abs(fpoco) < eps: # poco es raz
return poco
fmucho = func(mucho)
if abs(fmucho) < eps: # mucho es raz
return mucho
# compatibilidad para el mtodo
if fpoco
*
fmucho > 0:
print(
***
La funcin debe tener, end= )
print(signos opuestos en los extremos)
return None
# arreglamos signos de modo que fpoco < 0
if fpoco > 0:
poco, mucho = mucho, poco
# a partir de ac hay solucin si la funcin es continua
# lazo principal
while True:
medio = (poco + mucho) / 2
fmedio = func(medio)
if abs(fmedio) < eps: # tolerancia en y alcanzada
break
if abs(mucho - poco) < eps: # tolerancia en x alcanzada
break
if fmedio < 0:
Pg. tz Apndce A. Mdulos y archvos menconados
poco = medio
else:
mucho = medio
# salida
return medio
recursion1 (captulo )
"""Ejemplos sencillos de funciones recursivas."""
def factorial(n):
"""n! con recursin (n entero no negativo)."""
if n == 1:
return 1
return n
*
factorial(n-1)
def fibonacci(n):
"""n-simo mero de Fibonacci con recursin."""
if n > 2:
return fibonacci(n-1) + fibonacci(n-2)
return 1
def mcd(a, b):
"""Calcular el mximo comn divisor de a y b.
Usamos la versin original de Euclides
recursivamente.
a y b deben ser enteros positivos.
"""
if (a > b):
return mcd(a - b, b)
if (a < b):
return mcd(a, b - a)
return a
recursonz Pg. t
recursion2 (captulo )
"""Funciones recursivas avanzadas."""
def hanoi(n):
"""Solucin recursiva a las torres de Hanoi."""
# funcin interna
def pasar(k, x, y, z):
"""Pasar los discos 1,..., k de x a y usando z."""
if k == 1:
print(pasar el disco 1 de, x, a, y)
else:
pasar(k - 1, x, z, y)
print(pasar el disco, k, de, x, a, y)
pasar(k - 1, z, y, x)
# ejecucin
pasar(n, a, b, c)
def subs(n):
"""Generar los subconjuntos de {1,...,n}."""
if n == 0: # no hay elementos
yield [] # nico subconjunto
else:
for s in subs(n-1):
yield s # subconjunto de {1,...,n-1}
s.append(n) # agregar n al final
yield s # con n
s.pop() # sacar n
def subsnk(n, k):
"""Subconjuntos de {1,...,n} con k elementos."""
if k == 0: # no hay elementos
yield []
elif n == k: # estn todos
yield list(range(1, n + 1))
else:
Pg. t{ Apndce A. Mdulos y archvos menconados
for s in subsnk(n-1, k):
yield s # subconjunto de {1,...,n-1}
for s in subsnk(n-1, k-1):
s.append(n) # agregar n al final
yield s # con n
s.pop() # sacar n
def perms(n):
"""Permutaciones de {1,...,n}."""
if n == 0: # nada que permutar
yield []
else:
for p in perms(n-1):
p.append(n) # agregar n al final
yield p
i = n - 1
while i > 0: # llevar n hacia adelante
j = i - 1
p[i] = p[j]
p[j] = n
yield p
i = j
p.pop(0) # sacar n
santosvega.txt (ejercicio .)
Cuando la tarde se inclina
sollozando al occidente,
corre una sombra doliente
sobre la pampa argentina.
Y cuando el sol ilumina
con luz brillante y serena
del ancho campo la escena,
la melanclica sombra
huye besando su alfombra
con el afn de la pena.
sumardos Pg. ty
sumardos (ejercicio .)
"""Sumar dos objetos ingresados interactivamente."""
print(
__
doc
__
)
a = input(Ingresar algo: )
b = input(Ingresar otra cosa: )
print(La suma de, a, y, b, es, a + b)
tablaseno (ejercicio .)
"""Hacer una tabla del seno para ngulos entre 0 y 90 grados."""
import math
aradianes = math.pi/180
# abrir el archivo
archivo = open(tablaseno.txt, w, encoding=utf-8)
# escribir la tabla
for grados in range(0, 91):
archivo.write({0:3} {1:<15.8g}\n.format(
grados, math.sin(grados
*
aradianes)))
# cerrar el archivo
archivo.close()

Apndice B
Notaciones y smbolos
Ponemos aqu algunas notaciones, abreviaciones y expresiones usa-
das (que pueden diferir de algunas ya conocidas), slo como referencia:
deberas mirarlo rpidamente y volver cuando surja alguna duda.
B.. Lgica
implica o entonces. x > x =

x

puede leerse como si x


es positivo, entonces...
si y solo si. Signifca que las condiciones a ambos lados son
equivalentes. Por ejemplo x x = x se lee x es positivo
si y solo si...
existe. k Z tal que... se lee existe k entero tal que...
para todo. x > , x =

x

se lee para todo x positivo,...


La negacin lgica no. Si p es una proposicin lgica, p se
lee no p. p es verdadera p es falsa.
La conjuncin lgica y. Si p y q son proposiciones lgicas, pq
es verdadera tanto p como q son verdaderas.
B.z. Conjunros Pg. t,
La disyuncin lgica o. Si p y q son proposiciones lgicas, pq
es verdadera o bien p es verdadera o bien q es verdadera.
B.. Conjuntos
pertenece. x A signifca que x es un elemento de A.
no pertenece. x A signifca que x no es un elemento de A.
union de conjuntos. A B = x x A o x B.
interseccion de conjuntos. A B = x x A y x B.
diferencia de conjuntos. A B = x x A y x B.
A cardinal del conjunto A. Es la cantidad de elementos de A. No
confundir con x, el valor absoluto del numero x.
El conjunto vaco, = .
B.. Nmeros: conjuntos, relaciones, funciones
N El conjunto de nmeros naturales, N = , , , . . . . Para
nosotros N.
Z Los enteros, Z = , , , , , . . . .
Q Los racionales pq, donde p, q Z, q .
R Los reales. Son todos los racionales ms nmeros como

,
, etc., que no tienen una expresin decimal peridica.
Si x es un nmero, x representa dos nmeros: x y x.
aproximadamente. x y se lee x es aproximadamente igual a
y.
mucho menor. x y se lee x es mucho menor que y.
mucho mayor. x y se lee x es mucho mayor que y.
Pg. t8 Apndce B. Noracones y s|mbolos
m n m divide a n o tambin n es multiplo de m. Signifca que existe
k Z tal que n = km.
m y n deben ser enteros.
x El valor absoluto o modulo del nmero x.
x El piso de x, x R. Es el mayor entero que no supera a x, por
lo que x x < x + . Por ejemplo, = , = ,
z = z para todo z Z.
|x| La parte entera de x, x R, |x| = x. Nosotros usaremos la
notacin x, siguiendo la costumbre en las reas relacionadas
con la computacin.
[x El techo de x, x R. Es el primer entero que no es menor que x,
por lo que [x < x [x. Por ejemplo, [ = , [ = ,
[z = z para todo z Z.
e
x
,
exp(x) La funcin exponencial de base e = . . . .
log
b
x El logaritmo de x R en base b.
y = log
b
x b
y
= x.
x y b deben ser positivos, b .
ln x,
log x El logaritmo natural de x R, x > , o logaritmo en base e,
ln x = log
e
x. Es la inversa de la exponencial, y = ln x e
y
=
x.
Para no confundir, seguimos la convencin de Python: si
no se especifca la base, se sobreentiende que es e, es decir,
log x = ln x = log
e
x.
sen x,
sin x La funcin trigonomtrica seno, defnida para x R.
cos x La funcin trigonomtrica coseno, defnida para x R.
tan x La funcin trigonomtrica tangente, tan x = sen x cos x.
B.{. Nmeros mporranres en programacn Pg. t
arcsen x,
arccos x,
arctan x Funciones trigonomtricas inversas respectivamente de sen,
cos y tan.
En Python, se indican como asin, acos y atan (resp.).
signo(x) Las funcin signo, defnida para x R por
signo(x) =
:

'
si x > ,
si x = ,
si x < .
Algunos autores consideran que signo() no est defni-
do.

Indica suma,

n
i=
a
i
= a

+ a

+ + a
n
.

Indica producto,

n
i=
a
i
= a

a
n
.
B.. Nmeros importantes en programacin

mn
El menor nmero positivo para la computadora.

mq
El menor nmero positivo que sumado a da mayor que en
la computadora.
B.. En los apuntes
e Seala el fn de un ejercicio, resultado o ejemplo, para distin-
guirlo del resto del texto.
Notas de ndole ms bientcnica. Estn enletras ms pequeas
y en general se pueden omitir en una primera lectura.
k Comentarios histricos, curiosidades, etc. Estn en letras cur-
sivas ms pequeas, y se pueden omitir en la lectura.
Pg. zo Apndce B. Noracones y s|mbolos
Cosas que hay que evitar. En general quitan puntos en los exa-
menes.
Pasaje con conceptos que pueden llevar a confusin y que debe
leerse cuidadosamente.
Moraleja, explicacin o conclusin especialmente interesan-
te. El texto est en cursiva para distinguirlo.
h Filosofa, ideas a tener en cuenta. Estn a un nivel superior
a las moralejas, que a veces son slo aplicables a Python.
B.. Generales
Indica un espacio en blanco en entrada o salida de datos.
i. e. es decir o esto es, del latn id est.
e. g. por ejemplo, del latn exempli gratia.
RAE Real Academia Espaola.

Parte IV
lndces
Comandos de Python que
usamos
!=,
",
""" (documentacin),
,
+
concatenacin
de cadenas,
de sucesiones,
nmeros,
-,
/,
//,
<,
<=,
=,
y ==,
==,
>,
>=,
# (comentario),
%,
\,
\n,
\\,
*
,
**
,
abs,
and,
append,
bool,
break
en while,
close (archivo),
continue,
count,
def,
divmod,
__
doc
__
(documentacin),
elif,
Pg. z
else,
encoding (en open),
end,
False,
float,
for,
en fltro,
en lista,
format,
global,
help,
if,
en fltro,
import,
in,
index,
input,
insert,
int,
y math.trunc,
isinstance,
key,
keywords (en help()),
len,
cadenas,
list,
local,
math,
ceil (techo),
cos,
exp (e
x
),
e (e),
factorial,
floor (piso),
log10 (log

),
log (log, ln),
pi (),
sin (seno),
sqrt (raz cuadrada),
tan,
trunc,
max,
min,
next,
None,
not,
open (archivo),
or,
pop,
print,
r (en open),
random,
choice,
randint,
random,
sample,
seed,
shuffle,
range,
Pg. z{ Comandos de Pyrhon que usamos
read (archivo),
return,
reverse,
round,
y math.trunc,
sorted,
split,
str,
sum,
True,
tuple,
type,
utf-8 (en open),
w (en open),
while,
write (archivo),
yield,
ndice de fguras y cuadros
.. Entrada, procesamiento y salida. . . . . . . . . . . . . .
.. Transferencia de datos en la computadora. . . . . . . .
.. Un byte de bits. . . . . . . . . . . . . . . . . . . . . . .
.. Desarrollo de un programa. . . . . . . . . . . . . . . .
.. Traducciones entre matemticas y el mdulo math. . .
.. Traducciones entre matemticas y Python. . . . . . . .
.. Objetos en la memoria. . . . . . . . . . . . . . . . . . .
.. Asignaciones. . . . . . . . . . . . . . . . . . . . . . . . .
.. Espacio o marcos global y de mdulos. . . . . . . . . .
.. Variables globales y locales. . . . . . . . . . . . . . . . .
.. Prueba de escritorio. . . . . . . . . . . . . . . . . . . . .
.. Pasos de Pablito y su pap. . . . . . . . . . . . . . . . .
.. Efecto del intercambio de variables. . . . . . . . . . . .
.. Arbolito de Navidad . . . . . . . . . . . . . . . . . .
.. nmeros aleatorios entre y representados en el
plano. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Pg. zo lndce de fguras y cuadros
.. Los nmeros clasifcados. . . . . . . . . . . . . . . . . .
.. Ordenando por conteo. . . . . . . . . . . . . . . . . . .
.. Esquema de la densidad variable. . . . . . . . . . . . .
.. Grfco de cos x y x. . . . . . . . . . . . . . . . . . . . .
.. Aproximando la pendiente de la recta tangente. . . . .
.. Mtodo de Newton. . . . . . . . . . . . . . . . . . . . .
.. Funcin continua con distintos signos en los extremos.
.. Mtodo de biseccin. . . . . . . . . . . . . . . . . . . .
.. Grfco de saldo cuando r vara. . . . . . . . . . . . . .
.. Aproximaciones a sen x. . . . . . . . . . . . . . . . . .
.. Fractal asociado al mtodo de Newton. . . . . . . . . .
.. Esquema del problema de Flavio Josefo. . . . . . . . .
.. Grafo con vrtices y aristas. . . . . . . . . . . . . .
.. Asignando colores a los vrtices de un grafo. . . . . . .
.. Esquema del algoritmo recorrido. . . . . . . . . . . .
.. Recorrido lifo de un grafo. . . . . . . . . . . . . . . . .
.. Recorrido ffo de un grafo. . . . . . . . . . . . . . . . .
.. Laberintos. . . . . . . . . . . . . . . . . . . . . . . . . .
.. Clculo de los nmeros de Fibonacci. . . . . . . . . . .
.. Las torres de Hanoi. . . . . . . . . . . . . . . . . . . . .
.. Tringulo de Pascal de nivel . . . . . . . . . . . . . . .
.. Contando los caminos posibles. . . . . . . . . . . . . .
Autores mencionados
Adleman, L.,
Agrawal, M.,
Al-Khwarizmi,
Bigollo, L. (Fibonacci),
Binet, J.,
Boole, G.,
Bufon,
de la Valle-Poussin, C.,
de Moivre, A.,
Diofanto de Alejandra,
Dirichlet, J., , ,
Eratstenes de Cirene, ,
Euclides de Alejandra, , , ,
,
Euler,
Euler, L., , , , ,
Fermat, P., , ,
Fibonacci, vease L. Bigollo
Gauss, J., , ,
Goldbach, C.,
Green, B.,
Hadamard, J.,
Helfgott, H.,
Hilbert, D.,
Horner, W.,
Kayal, N.,
Lagrange, J., ,
Lucas, E.,
Matijasevich, Y.,
Mertens, F., ,
Newton, I., ,
Obligado, R.,
Pitgoras de Samos,
Rivest, R.,
Saxena, N.,
Shamir, A.,
Tao, T.,
Pg. z8 Aurores menconados
Taylor, B.,
Taylor, R.,
Ulam, S,
van Rossum, G.,
von Neumann, J., ,
Wantzel, P.,
Wiles, A.,
Wirth, N., ,
Bibliografa
A. Ecii, . Exploring Mathematics with your computer. Te
Mathematical Association of America. (pags. , y :)
E. Gi1iii, . Aritmetica elemental en la formacion matematica.
Red Olmpica. (pag. ,)
C. A. R. Ho.vi, . Algorithm: fnd. Commun. ACM, ():.
(pag. :,:)
B. W. Kivicu. v D. M. Ri1cuii, . El lenguaje de programacion
C. Prentice-Hall Hispanoamericana, .
a
ed. (pag. ,)
D. E. KU1u, a. Te art of computer programming. Vol. :, Funda-
mental Algorithms. Addison-Wesley, .
a
ed. (pags. , y 8)
D. E. KU1u, b. Te art of computer programming. Vol. :, Seminu-
merical algorithms. Addison-Wesley, .
a
ed. (pags. ,, 8 y :,)
D. E. KU1u, . Te art of computer programming. Vol. , Sorting
and searching. Addison-Wesley, .
a
ed. (pags. ,, 8 y :,,)
M. Li1vi v G. Li1vi, . Mathematics for the Digital Age and
Programming in Python. Skylight Publishing. URL http://www.
skylit.com/mathandpython.html. (pags. 8 y ,)
C. H. P.v.uimi1vioU v K. S1iicii1z, . Combinatorial Optimiza-
tion, Algorithms and Complexity. Dover. (pag. :,)
Pg. o Bblograf|a
R. Siuciwicx v K. W.vi, . Algorithms. Addison-Wesley, .
a
ed.
(pags. 8 y :,,)
N. Wiv1u, . Algoritmos y Estructuras de Datos. Prentice-Hall
Hispanoamericana. (pags. ,, 8, :oo y :,,)
S. Woiiv.m, . Mathematica - A System for Doing Mathematics by
Computer. Addison-Wesley, .
a
ed. (pag. ,)
ndice alfabtico

mq
, ,

mn
, ,
(de Euler),
acumulador,
aguja de Bufon,
algoritmo,
de la divisin, ,
rbol,
raz,
archivo de texto,
asignacin,
barrido (tcnica),
binomio,
bit,
bucle (lazo),
Bufon
aguja,
byte,
cadena (de caracteres),
clasifcacin,
concatenar,
lectura de archivo,
subcadena,
vaca,
y cifras,
camino
cantidad de,
en grafo,
cerrado,
entre vrtices,
longitud,
simple,
ciclo
de Euler, ,
en grafo,
cifra,
algoritmo, , ,
signifcativa,
y cadena,
clasifcacin,
estable,
cdigo,
seudo,
coefciente
binomial,
Pg. z lndce alfabrco
multinomial,
comentario
en cdigo,
componente
de grafo,
concatenar,
conexin
de grafo,
contexto, vease marco
copia
playa y profunda,
CPU,
criba,
de Eratstenes,
densidad (representacin)
constante,
variable,
Dirichlet
funcin,
principio,
teorema,
documentacin,
e (= .. . . ), ,
ecuacin
cuadrtica,
diofntica,
editor de textos,
espacio, vease marco
Euclides
algoritmo para mcd, , ,
,
recursivo,
primo de,
Euler
ciclo, ,
funcin ,
Euler-Binet
frmula,
exponente,
Fermat
primo,
Fibonacci
nmero, , ,
fltro
de lista,
Flavio Josefo
problema,
formato,
fractal,
funcin,
funcin
continua,
generadora,
marco, ,
piso,
signo,
techo,
fusin
de listas ordenadas,
generador
de grafo,
funcin,
nmero aleatorio,
gracar (mdulo), , ,
Pg.
grafo,
arista,
camino,
ciclo,
componente,
conexo,
dirigido,
recorrido,
simple,
vrtice,
grgrafo (mdulo), ,
Hanoi (torres),
Horner
regla, ,
identifcador,
ndice
de sucesin,
inmutable,
iterable, vease cap. ,
iterador,
lazo,
lenguaje,
link, vease referencia
lista (list), ,
como conjunto,
fltro,
fusin,
por comprensin,
longitud
de camino,
mantisa,
marco
de funcin, ,
de mdulo,
de nombre o nombrado,
math (mdulo),
mximo
comn divisor, vease mcd
de secuencia,
mcd, ,
algoritmo,
mcm,
media, vease tambien promedio
indicador estadstico,
mediana
indicador estadstico,
memoria,
mtodo
de clase,
de Monte Carlo,
para ,
de Newton (y Raphson),
mnimo
comn mltiplo, vease mcm
de secuencia,
moda
indicador estadstico,
mdulo,
gracar, , ,
grgrafo, ,
random,
estndar,
math,
propio,
Pg. { lndce alfabrco
Monte Carlo
mtodo,
multiplicacin
de nmero y cadena,
mutable,
notacin
cientfca,
nmero
combinatorio,
de Fibonacci,
decimal (float),
entero (int),
perfecto,
primo,
objeto (de Python),
palabra
clave,
reservada,
parmetro
de funcin,
formal,
real,
Pascal
tringulo,
,
Monte Carlo,
piso (funcin),
polinomio
de Lagrange,
de Taylor,
potencia (clculo de),
precedencia
de operador,
primo, ,
de Euclides,
de Fermat,
distribucin,
gemelo,
teorema,
programa,
corrida,
ejecucin,
RAE,
raz
de rbol,
random (mdulo),
rango (range), ,
referencia,
regla
de Horner, ,
de oro,
representacin
de grafo,
normal de nmero,
seccin (de sucesin),
secuencia, vease sucesin
signo (funcin),
sistema operativo,
subgrafo
de grafo,
generador,
sucesin,
suma, vease tambien cap.
Pg. y
acumulada,
promedio,
techo (funcin),
tcnica
de barrido,
teorema
Dirichlet,
nmeros primos, ,
terminal,
tipo (type)
cambio, ,
de datos,
tringulo
de Pascal,
tupla (tuple), ,
clasifcacin,
variable,
global, ,
local, ,
vrtice
aislado,
vnculo, vease referencia
von Neumann
arquitectura,

Anda mungkin juga menyukai