Está en la página 1de 72

Cmo se utiliza Python y Django en Mejorando.

la
Seguramente conoces Mejorando.la, es el proyecto web de Maestros y Cristalab. Comenz como programa online una vez por semana y ahora se ha expandido con cursos presenciales alrededor de latinoamrica y tres conferencias con alcance mundial. Leonidas Esteban, Renzo Avalos y Adan Sanchez son quienes hace unos meses estuvieron trabajando para lograr el sitio que hoy se puede disfrutar al ingresar a Mejorando.la. Para lograrlo hubo todo un proceso de rediseo y reprogramacin que fue posible gracias a varias herramientas y servicios que con la ayuda de Adan Sanchez te contar a continuacin.

Python y Django: Lenguaje y framework de la magia


Al momento de planear el rediseo y reprogramacion de un sitio es importante identificar bien sus elementos y componentes principales para crear los modelos necesarios y una buena estructura es lo primero que resalt Adn Sanchez. Y hablando especificamente de Mejorando.la hay que destacar que el componente principal son los videos. Desde ah parten todas las funciones que se van agregando al sitio. Python es el lenguaje y Django es el framework detrs del sitio de Mejorando.la. Nos cuenta Adn que gracias a la flexibilidad que ofrece, se pudo realizar la reprogramacin y rediseo del sitio en pocos das: Digamos que Django se ha vuelto prcticamente un estndar como framework para desarrollo gil. Es especialmente recomendado para un proyecto grande desarrollado por un equipo pequeo o cuando se trata de un sitio para entregar en pocos das. Al consultar por qu la eleccin de Django y no otro, nos explic que Django era la solucin principal, puesto que si bien wordpress es muy flexible, en Django hay aun mas flexibilidad.

Un framework con bateras includas


Django trae lo que en Python se conoce como bateras incluidas. Desde clases para tareas sencillas como paginacin, geolocalizacin, autentificacin y cach hasta componentes bastante completos como el mdulo de comentarios, notificaciones, administrador, internacionalizacin y feeds. Adn explica que un sitio en Django es ms limpio puesto que python tiene una estructura modular, agrega que en otros lenguajes hay que descargarse muchos archivos y el tener tantos archivos en el directorio puede hacer mas dificil manejar el sitio. Para graficar la facilidad con la que se activan estos mdulos desde el archivo de configuracin, nos mostr el cdigo correspondiente:
INSTALLED_APPS = (

'django.contrib.auth', # funciones de autentificacion 'django.contrib.comments', # funciones para agregar comentarios a los modelos 'django.contrib.admin', # administrador autogenerado )

Adems afirma que es muy fcil encontrar un mdulo en los repositorios para aquellas funcionalidades que no vienen incluidas en Django, un ejemplo de ello es el modulo Gravatar que se utiliza en Mejorando.la para los avatares de los comentarios.

Modelo-Vista-Controlador
Un punto ms a favor de Django es el patrn Modelo-Vista-Controlador que maneja, esto quiere decir que separas tu aplicacin en tres componentes, explic Adn. El modelo principal en este caso seria Video, en donde un video tiene titulo, imagen, descripcion, comentarios. Para entender mejor puedes ver el tercer capitulo de la guia Django y luego ver estos ejemplos: Modelo: son los datos, en el sitio se tiene un modelo para los Videos. Ejemplo de modelo
class Video(models.Model): titulo = models.CharField() slug = models.CharField() imagen = models.ImageField() fecha = models.DateField() descripcion = models.TextField()

Vista: sera la presentacin de este modelo, en Django entra en los templates, que reciben los datos del controlador. Hay una plantilla para cada vista: home.html, videos.html, video.html, heredando de base.html gracias al poderoso sistema de plantillas de Django. Controlador: se encarga de elegir los datos que se van a mostrar y hacer el procesamiento que haga falta en estos, validacion y condicionamientos. En Mejorando.la hay un controlador para cada pgina: home, archivo de videos y pgina de video. Ejemplo de controlador
def video(solicitud_http, video_slug): video = get_object_or_404(Video, slug=video_slug) return render_to_response('website/video.html', { 'video': video })

Unidad, cdigo limpio y filtros.


La unidad que existe en toda la plataforma es una de las caracteristicas que ms le gust a Adn: cualquier mtodo que defina en un modelo estar presente tanto en el controlador como en las plantillas.

Los modelos de Django permiten abstraer lo que tradicionalmente se hara con SQL en clases y funciones. Esto permite tener un cdigo ms limpio. Por ejemplo:
SQL SELECT titulo, descripcion, imagen FROM videos ORDER BY fecha LIMIT 10

Django
Video.objects.all().order_by(-fecha)[:10]

Nos coment tambin que en las plantillas de Django se hace uso de la rica cantidad de filtros que pone a disposicin, desde convertir a maysculas, eliminar etiquetas html y agregar saltos de lnea. Gracias a estos filtros es ms fcil tener una clara separacin entre datos, lgica y presentacin.

Slo un comienzo
Cmo te imaginars el proceso de rediseo y reprogramacin de un sitio como Mejorando.la no se puede comentar y explicar en detalle en tan slo un artculo, sin embargo en una proxima publicacin con Adn te contaremos ms funcionalidades y caracteristicas que hacen de python un lenguaje fcil de aprender y de Django el framework ideal para perfeccionistas.

Primeros pasos con Python


Python es un lenguaje interpretado
Cuando compilamos un programa escrito en C o en Fortran generamos un ejecutable. Para hacer funcionar ese ejecutable nos basta con muy poca cosa; en el caso de un hola, mundo basta con simplemente ejecutarlo. El sistema operativo lo considera ejecutable y simplemente cumple sus ordenes. Esto no sucede as en los lenguajes interpretados. El cdigo en Python nunca llega a traducirse a algo que el sistema operativo pueda entender. En Python el programa termina convertido en un ensamblador propio que una mquina virtual es capaz de entender y ejecutar. La consecuencia principal de este mtodo es que es imprescindible contar con un intrprete de Python instalado en el ordenador para poder ejecutar cdigo en Python. Esta no es hoy en da una condicin demasiado severa. El nico sistema operativo mayoritario que no cuenta con un intrprete de Python instalado por omisin es

Windows. Linux, Mac OSX, Solaris y AIX entre otros cuentan con uno, aunque algunas veces compensa instalar una versin ms actualizada que la que encontraremos en la distribucin del sistema operativo. En el caso especial de Windows bastar con descargarse un instalador, darle doble clic y decir que s a todo. Cuando ejecutamos cdigo en Python lo lanzamos a un intrprete que es capaz de entender este lenguaje. A diferencia de los lenguajes estticos como C o Fortran en el que un compilador convierte el cdigo de programa en un ejecutable que el sistema operativo es capaz de entender.

Python es un lenguaje interactivo


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

Consola de Python en la ventana de IDLE en Linux La manera de acceder a esta consola difiere en funcin del sistema operativo. En los UNIX y derivados bastar con abrir una consola de sistema y teclear en ella python. En Windows bastar con abrir el programa correspondiente que seguro que se llamar Python shell o algo parecido. Una vez estemos delante del intrprete de Python podemos empezar a jugar. En este respecto se trata de un lenguaje de programacin parecido a Matlab, de modo que podemos probar a hacer una suma sin problemas.
>>> 2+2 4

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

Python es un lenguaje dinmico


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

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

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

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

Python es un lenguaje orientado a objetos


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

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

| | | | | | | | | | |

Methods defined here: __abs__(...) x.__abs__() <==> abs(x) __add__(...) x.__add__(y) <==> x+y __coerce__(...) x.__coerce__(y) <==> coerce(x, y)

(...)

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

Son equivalentes a todos los efectos.

En Python todo est modularizado


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

Dos puntos a tener en cuenta:

Cada mdulo es en s un objeto. En este caso, despus de importar math, hemos llegado a la constante como un atributo del mdulo y a la funcin sin como un mtodo. Prcticamente la totalidad de mdulos o scripts en Python importan algn mdulo. Podemos importar mdulos prcticamente en cualquier punto de la ejecucin pero por convencin se suelen importar al principio.

Ahora podis pensar que para la funcin seno o para :math:pi, tener que arrastrar el nombre math puede ser algo tedioso; especialmente si no hay una intencin especial de agrupar las funciones de este mdulo. Si queremos importar slo sin y pi podemos hacerlo de la siguiente manera:
>>> from math import sin,pi

>>> sin(pi) 1.2246063538223773e-16

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

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

Python incluye bateras, pero no cargador


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

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

Python es tambin una calculadora


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

>>> 2**10 1024

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

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

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

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

Script para pasar cdigo Python a HTML


Hola. En este artculo vamos a crear un script para pasar cdigo fuente Python (.py) a formato HTML (y de esta manera mostrar dicho cdigo en una pgina web). Adems vamos a darle coloracin al cdigo Python. Debe de haber formas ms simples, sin duda, de resolver este tipo de problemticas, ... a m se me ha ocurrido esta. Como siempre, el fichero .py que contiene el script se puede obtener del repositorio de este blog, en: https://sites.google.com/site/elviajedelnavegante/ El fichero se llama mi_tokenize.zip, el cual contiene el script mi_tokenize.py.

En este problema no se ha utilizado programacin orientada a objetos, esto es, no se implementa ninguna clase. Todo se resuelve con programacin imperativa (mediante funciones).

Al grano...
El funcionamiento es sencillo, en trminos generales. De lo que se trata es que, a partir de un fichero de cdigo fuente Python, se genera otro (con extensin html) con cdigo HTML, que representa el cdigo Python formateado (con indentacin y coloreado de cdigo). Un ejemplo sera el siguiente:

La captura de arriba es del Stani's Python Editor. Abajo nos encontramos el mismo cdigo, formateado en HTML y coloreado, en Firefox.

Cmo enfocar el problema?


Pasar cdigo Python a html es casi trivial. nicamente hay que abrir un fichero .py, leerlo, crear otro fichero con una cabecera html, incluir dicho cdigo Python y cerrar el html. Listo, ya tenemos el cdigo en una pgina web.

El verdadero problema es el coloreado del cdigo, ya que se tiene que identificar los diferentes bloques de cdigo a los que se quieren dar color. En nuestro caso, daremos color a los comentarios, a las cadenas y a las palabras clave de la versin que utilicemos de Python.

Cmo hacerlo? Mediante los mdulos cStringIO y tokenize, que se pueden encontrar en cualquier distribucin de Python.

cStringIO sirve para crear, a partir de una cadena, un buffer de cadena. tokenize es el mdulo que nos permite analizar cdigo Python e identificar componentes del mismo (comentarios, cadenas, etc) a partir de un buffer de cadena. Mejor lo vemos con los pasos que debe de dar nuestro script:

1) Cargamos en memoria un fichero .py con el mtodo read() de open.

2) Mediante cStringIO creamos un fichero en memoria buffer de cadena, el cual es necesario para utilizar el tokenize. En realidad esto sirve para iterar, lnea a lnea sobre una cadena con varias lneas (con saltos de lnea). Por ejemplo:

import cStringIO

cadena = ''' Este es un ejemplo de la potencia del mdulo cStringIO '''

texto = cStringIO.StringIO(cadena) for i in texto: print i

Devuelve:

Este es un ejemplo de la potencia del mdulo cStringIO

3) Mediante tokenize, y a partir del buffer de cadena creado en el paso anterior, podemos obtener los token (elementos de cdigo), iterando sobre ellos, e identificando los elementos de cdigo Python.

En la documentacin de Python tenis una explicacin muy buena (en ingls) de estos dos mdulos:

http://docs.python.org/library/stringio.html#module-cStringIO

http://docs.python.org/library/tokenize.html

Puff!!! Una explicacin algo extraa. Vemoslo con un ejemplo. Imaginemos que hemos cargado mediante el mtodo read() de open un fichero con cdigo Python con el siguiente contenido:

# -*- coding: utf-8 -*# Cdigo Python. for i in range(0,5): print "Nmero ", i

Mediante los pasos anteriores vamos a identificar los elementos del cdigo, a saber, comentarios, palabras clave y cadenas. El cdigo que hara esta operacin podra ser el siguiente:

# Creamos buffer de cadena. texto = cStringIO.StringIO(cadena)

# Creamos tokens. tokens = tokenize.generate_tokens(texto.readline)

for a,b,c,d,_ in tokens: if a == tokenize.STRING: print "Cadena: %s en posicin [%s,%s]" %( b,c,d) if a == tokenize.NAME and b in keyword.kwlist: print "Palabra clave: %s en posicin [%s,%s]" % (b,c,d) if a == tokenize.COMMENT: print "Comentario: %s en posicin [%s,%s]" % (b,c,d)

Dando como resultado:

Comentario: # -*- coding: utf-8 -*- en posicin [(1, 0),(1, 23)] Comentario: # Cdigo Python. en posicin [(2, 0),(2, 17)] Palabra clave: for en posicin [(3, 0),(3, 3)] Palabra clave: in en posicin [(3, 6),(3, 8)] Palabra clave: print en posicin [(4, 2),(4, 7)] Cadena: "Nmero " en posicin [(4, 8),(4, 18)]

Por tanto, mediante el mdulo tokenize podemos identificar todos los elementos de los que se compone un cdigo Python. La idea fundamental es esta. Aparte, mediante operaciones de transformacin entre listas y cadenas, y dems operaciones se llega al resultado esperado.

Y cmo se colorea el texto? Pues mediante cdigo HTML del tipo:

As el otro hndicap es que a partir de las coordenadas de los elementos de cdigo a colorear hay que insertar cdigo HTML.

El script mi_tokenize.py
Tal como antes se ha comentado, el lector puede obtener el cdigo de este script en el repositorio de El viaje del navegante. Aqu se presentan capturas de pantalla del cdigo, debido principalmente a que se utiliza sintaxis html en el cdigo Python, y no mezclar cosas.

Mdulos que se cargan y estructuras que se definen:

Importamos los mdulos necesarios y creamos un diccionario para colorear los elementos de cdigo Python.

El cdigo principal que ejecuta el script:

Podemos observar que el script pide dos argumentos para funcionar, el primero el fichero Python y el segundo el nombre del fichero html que se generar (se le da extensin .html si esta se omite) . A continuacin llamamos a la funcin cargar_fichero que devuelve, mediante read() una cadena con el contenido del fichero. Finalmente, mediante la funcin tokenizar_codigo se crea una cadena con sintaxis html y Python, que se guarda en el fichero identificado por f_html_nombre.

Funcin para cargar el fichero .py:

Darse cuenta que reemplazamos ciertos caracteres especiales en html.

La funcin que analiza el cdigo creando una cadena con html y cdigo Python es la siguiente:

Esta funcin podra haberse escrito de otra forma, para ahorrar cdigo, pero me ha parecido ms pedaggico realizarlo de esta forma. Como se puede observar se utilizan cStringIO y tokenize. Devuelve una cadena con cdigo html. Esta ltima funcin utiliza dos funciones auxiliares, a saber:

La funcin para insertar los elementos de html:

Y la funcin para incluir la cabecera y pie del documento de la pgina web:

Pero como no es lo mismo andar el camino que conocer el camino, es mejor probar el script. El lector puede pensar que sera mucho mejor utilizar CSS para estos menesteres, y en cierta manera, es verdad, pero no es objetivo de este post hacer un tratado sobre web y CSS. Lo verdaderamente importante es el parseo de cdigo Python y el tratamiento de cadenas.

Se insta al lector a mejorar el cdigo.

//////////////////////////////////////////////////////////////////////////////////////

Programacin en Python --- Parte II Ejemplos


Author: Patricio Pez Serrato Date: 9 de Abril de 2004

ndice

1 Historia del documento 2 Introduccin o 2.1 Requisitos o 2.2 Cmo realizar los ejemplos 3 Nmeros grandes o 3.1 Agregando las comas 4 Manejo de informacin 5 Generacin de documentos HTML o 5.1 Usando funciones o 5.2 Usando una clase 6 Interfase grfica de usuario o 6.1 Introduccin o 6.2 Un editor o 6.3 Usando una clase 7 Servidor HTTP 8 Toques finales o 8.1 Documentacin o 8.2 Prueba de mdulos

1 Historia del documento


Este documento fu creado el 8 de Abril de 2004. Primera publicacin el 27 de Junio de 2004. Segunda edicin: 29 de Diciembre de 2008. Para sugerencias,correcciones o preguntas acerca de este en documento, escribir a: nospam en pp punto com punto mx El original de este documento se encuentra en http://pp.com.mx/python Derechos Reservados (c) Patricio Pez Serrato, Mxico 2004, 2006, 2008

2 Introduccin
La primera parte de este documento es una referencia del lenguaje Python, con enlaces a pginas de inters (se encuentra en http://pp.com.mx/python). Esta segunda parte recopila los ejemplos que he mostrado cuando imparto el Tutorial de Python. Empiezan por algo muy sencillo, y combinando hasta llegar a algo ms complejo. No por ser sencillos dejan de ser tiles, y como menciono durante el tutorial: los resultados de estos ejemplos pueden crecer y convertirse en sus propios conjuntos de herramientas.

2.1 Requisitos
Los ejemplos pueden realizarse tanto en una PC con MS-Windows, Unix o Linux siempre y cuando Python corra. Pueden usarse las versiones 1.5.2, y 2.0 en adelante. Los ejemplos tratan conceptos generales y procuran no usar caractersticas nicas en las versiones ms recientes. Todos los ejemplos, excepto las interfases grficas pueden hacerse en modo texto, usando preferentemente un editor que resalte la sintaxis de Python como Vim, emacs, Scite y otros. Los usuarios de MS-Windows pueden instalar algunos de estos editores del CD Gnuwin. Los ejemplos con Tkinter requieren tener el conjunto de funciones grficas Tk as como el modulo de Python Tkinter que lo accesa. Ambos vienen includos en el instalador de Python para MS-Windows y se instalan cuando se aceptan todas las opciones del instalador sin modificacin. En Linux el lector puede verificar mediante este comando:
[usuario@pc]$ rpm -qa | grep ^tk tk-8.3.3-7mdk tkinter-2.1.1-3mdk

2.2 Cmo realizar los ejemplos


Programar en Python puede hacerse de varias maneras segn la necesidad o el gusto de cada persona. Para los nefitos mi recomendacin es que utilicen el ambiente grfico interactivo llamado idle. Esta herramienta viene includa con el mdulo tkinter. Adems de resaltar la sintaxis en colores, permite editar archivos fuente y es ms amigable al inicio. El idle tiene dos ambientes: el shell interactivo con ttulo Python Shell en su ventana; muestra el prompt >>> y espera un comando, y uno o ms editores que se abren con el men File --> New Window. Cada editor empieza con el ttulo Untitled en su ventana, el cual cambia hasta que se salva a un archivo con File --> Save As (y subsecuentemente File --> Save). Cada editor nos permite ejecutar el cdigo Python que contiene. Se recomienda crear una carpeta para realizar y guardar los ejemplos. Para correr idle, cambiar primero a esa carpeta y entonces correr idle: En MS- Windows:
C:\ejemplos> C:\python22\idle\idle

En Linux:
[usuario@pc ejemplos]$ idle &

La primera vez que hacen un ejemplo, intenten hacerlo paso a paso en forma interactiva en el shell, tecleando cada comando. Es la forma en que aprendern ms que si simplemente copian y pegan. Una vez que ya teclearon y funcionaron las cosas, entonces copien del shell interactivo y peguen a una ventana de editor y salven en un archivo con terminacin .py para que conserven lo que hicieron para la posteridad.

3 Nmeros grandes
Podemos explorar los enteros largos de Python si hacemos una tabla de potencias de 2, evaluando 2^n mientras n vara de 0 a n.
>>> for n in range(60): print n, 2**n

El resultado ser:
0 1 1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024 11 2048 12 4096 13 8192 14 16384 15 32768 16 65536 17 131072 18 262144 19 524288 20 1048576 21 2097152 22 4194304 23 8388608 24 16777216 25 33554432 26 67108864 27 134217728 28 268435456 29 536870912 30 1073741824 31 2147483648 32 4294967296 33 8589934592

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

17179869184 34359738368 68719476736 137438953472 274877906944 549755813888 1099511627776 2199023255552 4398046511104 8796093022208 17592186044416 35184372088832 70368744177664 140737488355328 281474976710656 562949953421312 1125899906842624 2251799813685248 4503599627370496 9007199254740992 18014398509481984 36028797018963968 72057594037927936 144115188075855872 288230376151711744 576460752303423488

Nota: desde la versin 2.2 de Python, si el resultado de una expresin entera excede el lmite de los enteros (2^32 generalmente), ste es convertido automticamente a entero largo. (mostrado con terminacin L en el ambiente interactivo):
>>> 12345678901234 12345678901234L

En versiones 2.1 y anteriores tendremos un error:


>>> 12345678901234 OverflowError: integer literal too large

En el ejemplo anterior, lo que tendremos que hacer en este caso es agregar L al final del 2:
>>> for n in range(60): print n, 2L{*}{*}n

3.1 Agregando las comas


Los nmeros muy grandes son difciles de entender sin las comas que normalmente usamos. Vamos entonces a definir una funcin que agregue las comas. Los pasos necesarios seran:

Convertir a cadena, para poder tomar cada dgito. Recorrer la cadena de derecha a izquierda, de tres en tres dgitos. Se inserta la coma cada vez si todava quedan ms de tres dgitos a la izquierda.

Al probar la funcin en el cdigo anterior, remplazamos 2**n con poncoma(2**n) y adems formamos columnas con el operador %:
def poncoma( n ): "Regresa n como cadena con comas." s = str(n) pos = len(s) while pos > 3: pos = pos - 3 s = s[:pos] + ',' + s[pos:] return s for n in range(60): print '%3d %30s' % ( n, poncoma( 2**n ) )

Nota sobre versiones de Python: en las versiones 1.5.2 hasta 2.0, podemos utilizar la funcin rjust() del mdulo string. Necesitaremos incluir el comando import string al principio del ejemplo*,* y referir la funcin como string.rjust(str(n), 3) y string.rjust(poncoma(2**n), 30). A partir de las versin 2.1 todas las cadenas y las funciones que regresan cadena tienen la funcin rjust() includa, y podramos usar str(n).rjust(3) y poncoma(2**n).rjust(30). El resultado ser ahora ms legible:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 1 2 4 8 16 32 64 128 256 512 1,024 2,048 4,096 8,192 16,384 32,768 65,536 131,072 262,144 524,288 1,048,576 2,097,152 4,194,304 8,388,608 16,777,216 33,554,432 67,108,864 134,217,728 268,435,456 536,870,912 1,073,741,824 2,147,483,648 4,294,967,296 8,589,934,592

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

17,179,869,184 34,359,738,368 68,719,476,736 137,438,953,472 274,877,906,944 549,755,813,888 1,099,511,627,776 2,199,023,255,552 4,398,046,511,104 8,796,093,022,208 17,592,186,044,416 35,184,372,088,832 70,368,744,177,664 140,737,488,355,328 281,474,976,710,656 562,949,953,421,312 1,125,899,906,842,624 2,251,799,813,685,248 4,503,599,627,370,496 9,007,199,254,740,992 18,014,398,509,481,984 36,028,797,018,963,968 72,057,594,037,927,936 144,115,188,075,855,872 288,230,376,151,711,744 576,460,752,303,423,488

Le dejamos al lector el ejercicio de mejorar poncoma() aadiendo instrucciones para que acepte nmeros con signo negativo, y con decimales.

4 Manejo de informacin
Hace aos al Departamento de Informtica se le llamaba de Procesamiento Electrnico de Datos (Electronic Data Processing en Ingls, con las siglas EDP). El nombre antiguo era ms descriptivo de la labor que se supone deban realizar las computadoras. Aqu mostraremos cmo hacemos esto en Python, con un conjunto de datos pequeo pero real. Tenemos la siguiente informacin en el archivo capitales.txt:
Mxico,D.F. Aguascalientes,Aguascalientes Tijuana,Baja California Mexicali,Baja California Sur Campeche,Campeche Tuxtla Gutirrez,Chiapas Chihuahua,Chihuahua Saltillo,Coahuila Colima,Colima Durango,Durango Toluca,Edo. de Mxico Chilpancingo,Guerrero Guanajuato,Guanajuato Pachuca,Hidalgo Guadalajara,Jalisco Morelia,Michoacn Cuernavaca,Morelos

Tepic,Nayarit Monterrey,Nuevo Len Oaxaca,Oaxaca Puebla,Puebla Quertaro,Quertaro Chetumal,Quintana Roo Culiacn,Sinaloa Hermosillo,Sonora San Luis Potos,San Luis Potos Villa Hermosa,Tabasco Tampico,Tamaulipas Tlaxcala,Tlaxcala Jalapa,Veracruz Mrida,Yucatn Zacatecas,Zacatecas

Son los nombres de los Estados mexicanos con su ciudad capital. Primero la capital, seguida de una coma y el nombre del Estado. A continuacin vamos a leer esta pequea 'base de datos' a una cadena en Python, la vamos a convertir a una lista de registros, luego separaremos los campos de cada registro. El lector puede ir haciendo primero estos pasos en forma interactiva, revisando los resultados:
# Leemos el archivo a una cadena: f = open( 'capitales.txt' ) datos = f.read() # Partimos la cadena a una lista cuyos elementos son # los registros de nuestra 'base de datos' import string lista = string.split( datos, '\n' ) print lista # Convertimos cada elemento de la lista a una pareja, # usamos una funcin lambda: pares = map( lambda e: string.split( e, ','), lista ) print pares # Podemos crear una lista para cada campo: # una lista de capitales y otra lista de estados. # Esta es una forma de obtenerlas: capitales = [] estados = [] for capital,estado in pares: capitales.append( capital ) estados.append( estado ) # Cmo determinar los nombres nicos de ambas listas? # Usamos la concatenacin de listas. unicos = [] for nombre in capitales+estados: if nombre not in unicos:

unicos.append(nombre) else: print nombre # Cuntos elementos tenemos? print len(unicos) # Los ordenamos alfabticamente: unicos.sort() print unicos

Para concluir, definimos una funcin que lee el archivo de este ejemplo, separa en campos y registros, y nos regresa una matriz en forma de una lista:
def leedatos( nombrearchivo ): "Abre un archivo, lee y regresa un arreglo." f = open( nombrearchivo ) renglones = f.readlines() arreglo = map( lambda x: x.split(','), renglones ) return arreglo matriz = leedatos( 'capitales.txt' ) for renglon in matriz: for celda in renglon: print '%-20s' % celda, print

5 Generacin de documentos HTML


Hoy en da usar HTML es cosa del diario, cuando navegamos en internet, leemos correo, y cada vez son ms las aplicaciones que usan el navegador como punto de acceso al usuario. Muchas pginas de HTML se generan por programas, no por personas. Por esta razn vamos a practicar con Python. Un documento bsico de HTML puede ser as: System Message: ERROR/3 (ejemplos.rst, line 420) Unknown directive type "code-block".
.. code-block:: html <html> <head><title>pgina hecha a mano</title></head> <body> <h1>Hola...</h1> probando<br> </body> </html>

Si nunca habas hecho un documento HTML, puedes pegar el texto de arriba a un nuevo documento y salvarlo como estatica.html. Abre luego el documento con un navegador para que lo muestre.

5.1 Usando funciones


Vamos a dividir el documento HTML en las partes que lo forman, tomando como base la muestra anterior: System Message: ERROR/3 (ejemplos.rst, line 443) Unknown directive type "code-block".
.. code-block:: html ---------- inicio del documento ---------<html> <head><title>pgina hecha a mano</title></head> <body> ---------- cuerpo del documento <h1>Hola...</h1> probando<br> ----------

---------- final del documento </body> </html>

----------

Ahora definiremos una funcin en Python para que regrese cada parte como texto. Empezamos con las funciones inicio() y final(). Luego agregamos para el cuerpo del documento las funciones encabezado(), parrafo(), liga(), destino(), saltolinea() y horizontal(). Finalmente desarrollamos tabla() que ser muy utilizada para mostrar arreglos. No es necesario utilizar variables i, j como en otros lenguajes para recorrer el arreglo, ni saber las dimensiones. Cada rengln del arreglo puede ser de distinta longitud. Tenemos el siguiente cdigo con las funciones bsicas: System Message: ERROR/3 (ejemplos.rst, line 473) Unknown directive type "code-block".
.. code-block:: python def inicio( cadena='' ): "Inicia el documento HTML." return '''<html> <head> <title>''' + cadena + '''</title>

</head> <body>\n''' def encabezado( nivel='1', string='' ): "Regresa string con encabezado o ttulo HTML, default es H1." return '<h'+ nivel + '>'+ string + '</h'+ nivel + '>' def horizontal(): "Lnea horizontal en el documento HTML." return '<hr />' def destino( clave, texto ): "Regresa texto como destino." return '<a name="' + clave + '>' + texto + '</a>' def liga( url, texto): "Liga o hipervnculo a url con texto." return '<a href="' + url + '">' + texto + '</a>' def parrafo( texto ): "Genera un prrafo con texto." return '<p>' + texto + '</p>\n' def saltolinea(): "Genera un salto de lnea." return '<br>\n' def tabla( arreglo ): """Muestra arreglo en una tabla HTML. Las celdas pueden ser cualquier tipo, se convierten a cadena siempre.""" temp = '<table border="1">\n'

for renglon in arreglo: temp = temp + '<tr>' for celda in renglon: temp = temp + '<td>' + str(celda) + '</td>\n' temp = temp + '</tr>\n' return temp + '</table>\n' def final(): "Fin del documento HTML." return '''</body> </html>'''

Las funciones se van llamando en orden como se muestra en este ejemplo:


print print print print inicio( 'Pgina dinamica') encabezado( 'Pgina generada con Python') parrafo( 'Tenemos a continuacin una tabla:') tabla( [ ['r1c1', 'r1c2'], ['r2c1', 'r2c2'] ] ) print final()

Hemos pasado un arreglo en forma explcita, pero podemos usar una variable. Las funciones que definimos pueden anidarse. Por ejemplo:

parrafo( 'El sitio ' + liga( 'http://www.python.org,'www.python.org') + 'tiene mucha informacin sobre Python.' )

para obtener:
El sitio www.python.org tiene mucha informacin sobre Python.

Para probar nuestros experimentos necesitamos enviar la salida del programa a un archivo que podemos llamar prueba.*html*. Para hacer esto, necesitamos correr nuestro guin html.py con un comando as:
[user@host ejemplos]$ python html.py > prueba.html

En Windows:
C:\ejemplos> python html.py > prueba.html

Si Windows no tiene la ruta del ejecutable python.exe en su PATH, hay que agregarla. Generalmente es C:python22python:
C:\ejemplos> c:\python22\python html.py > prueba.html

La tabla podemos ahora construirla con una rutina, o llenarla con datos de alguna fuente, que ser lo ms usual. En el siguiente ejemplo hacemos ambas cosas. hacertabla() construye una matriz con expresiones. leedatos() es la rutina de la seccin anterior sobre manejo de datos, que lee de nuestro archivo capitales.txt y usa lo que aprendimos para separar campos y registros. Aqu est el cdigo:
def hacertabla( ren=10, col=10, operador='+'): """Construye y regresa un arreglo ren x col. Cada celda toma un valor que depende de x,y y el valor de operador. El arreglo es de 10 x 10 si no se suministran los valores de ren y col.""" array = [] for ren in range(1, ren+1): array.append( [] ) for col in range( 1, col+1): dato = calcula(ren, col, operador) array[-1].append( dato ) return array def calcula( a, b, operador): "Regresa una cadena tipo 'a operador b = resultado'." if operador == '+': return str(a) + ' + ' + str(b) + ' = ' + str( a+b) elif operador == '*': return str(a) + ' * ' + str(b) + ' = ' + str( a*b) def leedatos( nombrearchivo ): "Abre un archivo, lee y regresa un arreglo." f = open( nombrearchivo ) renglones = f.readlines()

arreglo = map( lambda x: x.split(','), renglones ) return arreglo print print print print print print print print print print inicio( 'Mi primera pgina dinamica') encabezado( 'Pgina generada con Python') parrafo( 'Algunos ejemplos de las rutinas para generar HTML') tabla( leedatos( 'capitales.txt' ) ) encabezado( 'Tabla de sumas' ) tabla ( hacertabla() ) encabezado( 'Tabla de multiplicacin' ) parrafo( 'Esta tabla usa la misma funcin con otro contenido' ) tabla ( hacertabla(12, 9, '*'), ) final()

5.2 Usando una clase


El siguiente paso es definir una clase que llamaremos buffer. Esto representa mejoras respecto a nuestro ejemplo anterior, porque ahora podremos escribir el texto HTML a un archivo desde el programa sin redireccionar la salida estndar. Esto nos permite generar ms de una pgina simultneamente. La clase buffer crea un atributo text en cada instancia que es el texto HTML que se va formando. El mtodo add() se usa para agregar texto a la instancia, mientras que el mtodo pop() es para regresar y vaciar el atributo de texto, como cuando lo vamos a escribir a un archivo. La clase tiene tambin mtodos con los mismos nombres que las funciones bsicas. Estos mtodos simplemente llaman a la funcin correspondiente y van agregando el texto regresado mediante el mtodo add().
class buffer: """Clase para generar objetos que almacenan codigo HTML que despues sera escrito a algun archivo.""" def __init__( self ): "Constructor, crea el atributo de texto." self.text = '' def add( self, texto ): "Agrega texto arbitrario al buffer." self.text = self.text + texto def pop( self ): "Regresa el texto del buffer, y borra el buffer." temp = self.text self.text = '' return temp def inicio( self, titulo ): "Inicia el documento HTML." self.add( inicio( titulo ) ) def encabezado( self, nivel, string): "Regresa string con encabezado o ttulo HTML, default es H1." self.add( encabezado( nivel, string ) ) def horizontal( self ): "Lnea horizontal en el documento HTML."

self.add( horizontal() ) def destino( self, clave, texto ): "Regresa texto como destino." self.add( destino( clave, texto) ) def liga( self, url, texto): "Liga o hipervnculo a url con texto." self.add( liga( url, texto) ) def parrafo( self, texto ): "Genera un prrafo con texto." self.add( parrafo( texto) ) def saltolinea( self ): "Genera un salto de lnea." self.add( saltolinea() ) def tabla( self, arreglo ): "Inserta arreglo en una tabla HTML." self.add( tabla( arreglo ) ) def final( self ): "Fin del documento HTML." self.add( final() )

Ahora vemos un ejemplo de cmo usamos esta clase para crear pginas HTML. Creamos dos instancias de buffer, les agregamos contenido y finalmente escribimos cada buffer a un archivo. Cada pgina lleva un enlace a la otra:
import html # Crear dos instancias de la clase buffer: pagina1 = html.buffer() pagina2 = html.buffer() # Llenar cara buffer: pagina1.inicio( 'Pgina 1' ) pagina1.encabezado( '2', 'Esta es pgina 1') pagina1.liga( 'pag2.html', 'Ir a pgina 2' ) pagina1.final() pagina2.inicio( 'Pgina 2' ) pagina2.encabezado( '2', 'Esta es Pgina 2') pagina2.liga( 'pag1.html', 'Ir a pgina 1' ) pagina2.final() # Vaciar cada buffer a un archivo: fp = open( 'pag1.html', fp.write( pagina1.pop() fp = open( 'pag2.html', fp.write( pagina2.pop() 'w' ) ) 'w' ) )

6 Interfase grfica de usuario

De los varios conjuntos de herramientas para hacer interfases grficas, veremos Tk. Tk es el conjunto de herramientas que se hizo originalmente para el lenguaje de guiones TCL. Mediante el mdulo Tkinter, Python puede utilizar Tk.

6.1 Introduccin
Para trabajar con un cualquier juego de herramientas grficas, necesitamos ir creando las ventanas o elementos (llamados tambin widgets) que usaremos, los cuales quedan en una jerarqua. En primer nivel tendremos una ventana principal, a la cual agregamos botones, un marco, un cuadro de texto, etc. Los pasos para todo programa grfico sern:

Importar las clases y constantes del mdulo Tkinter, mediante un comando import en su forma import Tkinter. Crear una instancia de la ventana raz, a partir de la clase Tkinter.Tk(). Crear una instancia de uno o ms elementos para insertar en esta ventana raz. Los elementos pueden ser widgets Label, Canvas, Frame, y otros. Un widget procesador de texto por ejemplo, se crea a partir de la clase Tkinter.Text(). Enlazar funciones o mtodos de la ventana raz o alguno de los widgets a uno o ms eventos del usuario. Los eventos son los movimientos y acciones del ratn y teclas presionadas en el teclado. Mostrar cada elemento con el mtodo pack() que tiene definido. Agregar informacin a los elementos, como puede ser texto al editor o a una etiqueta Llamar el mtodo mainloop() de nuestra ventana raz, para que se active la atencin a los eventos. Para terminar la aplicacin se llama al mtodo quit() de la ventana raz.

Ya en cdigo tendremos ms o menos el siguiente esqueleto:


import Tkinter raiz = Tkinter.Tk() w = Tkinter.Label(raiz) w.pack() w[ 'text' ] = 'Hola mundo' raiz.mainloop()

El ejemplo anterior se basa en el primer ejemplo de Fredrik Lundh en su documento An introduction to Tkinter.

6.2 Un editor
El widget de texto Text() nos da la base para hacer un editor. La clase Text() tiene los mtodos insert() y get() para escribir o leer el contenido del buffer de texto que corresponde al rea visible para el usuario. El cdigo bsico sera:
import Tkinter, sys raiz = Tkinter.Tk() editor = Tkinter.Text(raiz) editor.pack()

f = open( sys.argv[1] ) editor.insert( '1.0', f.read() ) raiz.mainloop()

Al cdigo anterior le agregamos instrucciones en el bloque principal indicar que se requiere el nombre del archivo. El bloque maneja la excepcin en caso de que el archivo no exista y se trate de un archivo nuevo a crear. Se agregan tambin las funciones quit() para terminar la aplicacin, y save() para guardar el contenido del buffer en el archivo. La aplicacin se termina mediante la combinacin de teclas Control+q y el archivo se salva con las teclas Control+s. Estos dos eventos de teclado se llaman <Control-q> y <Control-s> en Tkinter*,* y se ligan las funciones quit() y save() a estos eventos mediante el mtodo bind que tienen todos los widgets en Tk:
import Tkinter, sys def quit(event ): "Termina la aplicacin." raiz.quit() def save(event): "Salva el texto del editor." f = open( nombrearchivo, 'w' ) f.write( editor.get( '1.0', END) ) f.close() print 'archivo', nombrearchivo, 'salvado.' raiz = Tkinter.Tk() editor = Tkinter.Text(raiz) editor.pack() editor.bind( '<Control-q>', quit ) editor.bind( '<Control-s>', save ) if len(sys.argv)>1: nombrearchivo = sys.argv[1] try: f = open( nombrearchivo ) editor.insert( '1.0', f.read() ) except: print nombrearchivo, 'es archivo nuevo' else: print 'falta proporcionar nombre de archivo' sys.exit() mainloop()

Este primer ejemplo nos muestra lo fcil que es crear una aplicacin grfica directamente. Para casos de interfases ms complejas, existen herramientas como Glade que ayudan a crearla en forma grfica.

6.3 Usando una clase


El caso anterior tiene una sola ventana de texto. Para tener varios archivos abiertos no tenemos que repetir el cdigo para cada ventana. Lo que utilizamos es una clase y cada ventana es una instancia de la misma.

El cdigo base para crear un editor que ya vimos ser includo en una clase editor, especficamente en la funcin __init__() que es su funcin contructora y se ejecuta cuando se crea una instancia. Tk siempre crea una instancia de la clase Tk(), una ventana principal, que podra ser la ventana de inicio de la aplicacin. En este caso la ocultamos desde el inicio con el mtodo withdraw(). La clase editor tiene el mtodo quit() para terminar la aplicacin, y siguiente() y anterior() que son para activar otra de las ventanas de edicin utilizando las teclas pgina siguiente y pgina anterior del teclado, cuyos eventos en Tkinter se llaman <Prior> y <Next>. Usamos una lista editores inicialmente vaca, mediante un ciclo se va agregando una instancia de editor para cada parmetro que se proporcion. El cdigo es as:
class editor: "Un area de texto simple." def __init__( self, nombrearchivo ): "Construye la instancia." self.tl = Tkinter.Toplevel() self.tl.title (nombrearchivo) self.nombrearchivo = nombrearchivo self.buffer = Tkinter.Text( self.tl, height=10) self.buffer.pack() self.buffer[ 'wrap'] = Tkinter.NONE self.buffer[ 'background'] = 'white' self.buffer[ 'foreground' ] = 'black' self.buffer[ 'font'] = ( 'verdana', 14 ) self.buffer.bind( '<Prior>', self.anterior ) self.buffer.bind( '<Next>', self.siguiente) self.buffer.bind( '<Control-q>', self.quit) self.s = string.replace( open( self.nombrearchivo ).read(),'\015', '') self.buffer.insert( Tkinter.END, self.s ) if d.has_key( self.nombrearchivo ): self.tl.geometry( d[ self.nombrearchivo ] ) lineas = self.s.splitlines() self.buffer['height'] = len( lineas ) + 1 self.buffer['width'] = max( map(len, lineas) ) + 1 def anterior( self, event ): i = notas.index( self) - 1 if i < 0: i = len(notas)-1 notas[i].buffer.focus_set() notas[i].tl.lift() return 'break' def siguiente( self, event ): i = ( notas.index( self) + 1 ) % len( notas ) notas[i].buffer.focus_set() notas[i].tl.lift() return 'break' def quit( self, event ):

"Actualiza posiciones, cierra ventanas, termina." f = open( archivoconf, 'w' ) for nota in notas: d[ nota.nombrearchivo ] = nota.tl.geometry() nota.tl.withdraw() for llave, dato in sorted( d.items() ): f.write( llave + ' ' + dato + '\n') nota.tl.withdraw() root.quit() def LeeConf(): "Lee nombres y posiciones de archivoconf." lineas = [] try: f = open( archivoconf ) lineas = map( string.split, f.read().splitlines() ) except: print archivoconf, 'no existe' for llave, dato in lineas: d[llave] = dato import sys, string, Tkinter archivoconf = 'editor.conf' nombresarchivos = sys.argv[ 1:] if nombresarchivos: d = {} root = Tkinter.Tk() root.withdraw() LeeConf() notas = [] for nombrearchivo in nombresarchivos: notas.append( editor( nombrearchivo ) ) notas[0].buffer.focus_set() root.mainloop()

7 Servidor HTTP
Python nos permite hacer aplicaciones que incluyan un servidor de HTTP. Puede ser en la intranet de nuestra casa u oficina, o bien en internet. Un servidor bsico de HTTP, al cual podemos modificar si deseamos, empieza as:
import BaseHTTPServer, SimpleHTTPServer httpd = BaseHTTPServer.HTTPServer( ( '', 80), SimpleHTTPServer.SimpleHTTPRequestHandler) httpd.serve_forever()

Para aadir CGI utilizamos CGIHTTPRequestHandler en lugar de SimpleHTTPRequestHandler en nuestra instancia de servidor:
import BaseHTTPServer, CGIHTTPServer httpd = BaseHTTPServer.HTTPServer( ( '', 80), CGIHTTPServer.CGIHTTPRequestHandler) httpd.serve_forever()

Ambos casos pueden probarse en tu mquina tratando de mostrar la direccin http://localhost en un navegador. Podrs ver los archivos que estn en el directorio de trabajo al momento de correr el guin servidor. Mientras el guin corre, arroja una bitcora de los accesos. En Linux es necesario que ests como root para correr estos guiones. Roundup es un ejemplo de una aplicacin hecha en Python que crea su servidor HTTP con CGI. Ver http://roundup.sf.net para ms informacin.

8 Toques finales
8.1 Documentacin
Documentar nuestros programas, mdulos y ejemplos en Python no representa un esfuerzo adicional si hemos includo las cadenas de documentacin. Para el caso de un mdulo, podemos incluir las siguientes cadenas:
'''Cadena de descripcin del mdulo Puede tener una lnea de encabezado, y despus uno o ms prrafos de explicacin...''' __author__ = 'xxxx xxxx' __date__ = 'xxxx xxxx' __version__ = 'xxxx xxxx' __credits__ = 'xxxx xxxx' __text__ = 'xxxx xxxx' __file__ = 'xxxx xxxx'

Las funciones para generar HTML las inclumos todas en un archivo html.py, al cual agregamos al inicio las cadenas anteriores. Despus con la herramienta pydoc includa con Python, podemos generar un archivo html.*html* con la documentacin del mismo:
[usuario@pc ejemplos]$ /usr/lib/python2.1/pydoc.py -w ./html.py

Escribimos './' antes del nombre del archivo, para que pydoc sepa que es un archivo y no un mdulo predefinido.

8.2 Prueba de mdulos


Se recomienda al final de un mdulo definir una funcin prueba() que llame algunas de las funciones para validar que todo est bien. Esta funcin deber correr solamente cuando el mdulo se carga como guin principal, no cuando se importa desde otro archivo. Para lograr esto, usar el siguiente cdigo:
if __name__ == '__main__': prueba()

/////////////////////////////////////////////////////////////////////////////

como integrar python con html/css/javascript?


Estas en el tema de como integrar python con html/css/javascript? en el foro de Python en Foros del Web. Hola, comentarles que vengo haciendo las cosas con php y me interesa meterme con python. Tal es as que estuve leyendo sobre el y estoy ... #1 (permalink) 01/10/2011, 09:58 cristian_cena Colaborador como integrar python con html/css/javascript? Hola, comentarles que vengo haciendo las cosas con php y me interesa meterme con python. Tal es as que estuve leyendo sobre el y estoy muy feliz con la sintaxis, con lo simple y bonito que luce el cdigo y con lo rpido que aparenta ser el desarrollo en este lenguaje. Si bien me he encontrado numerosas y valiosas guias, no he hallado an un lugar donde expliquen como desarrollar mi primer web con python sin frameworks. No se como integrar python con html/css/javascript. Les agradezco si tienen a mano algun link/ejemplo que pueda serme til. #2 (permalink) 01/10/2011, 11:19 Fecha de Ingreso: marzo-2005 Ubicacin: Monterrey, Mxico Mensajes: 6.166 Antigedad: 8 aos, 5 meses Puntos: 1048 Fecha de Ingreso: junio-2009 Mensajes: 2.219 Antigedad: 4 aos, 2 meses Puntos: 268

razpeitia Moderador

Respuesta: como integrar python con html/css/javascript? Al igual que php, python no sirve contenido esttico esto lo debes de configurar en tu servidor web. #3 (permalink) 01/10/2011, 11:50 cristian_cena Colaborador Fecha de Ingreso: junio-2009 Mensajes: 2.219 Antigedad: 4 aos, 2 meses Puntos: 268

Respuesta: como integrar python con html/css/javascript?

gracias razpeitia, comprendo, si tienes a bien quisiera que veamos un ejemplo: supongamos que tengo esto en php: archivo.php: Cdigo HTML:
Ver original 1. <?php 2. $hola = "hola mundo"; 3. ?> 4. <!DOCTYPE HTML> 5. <html lang="en-US"> 6. <head> 7. <title>hola mundo metiendo php en codigo html</title> 8. </head> 9. <body> 10. <?php echo $hola; ?> 11. </body> 12. </html>

Como podra reescribirlo en python? #4 (permalink) 01/10/2011, 12:28 Fecha de Ingreso: marzo-2005 Ubicacin: Monterrey, Mxico Mensajes: 6.166 Antigedad: 8 aos, 5 meses Puntos: 1048

razpeitia Moderador

Respuesta: como integrar python con html/css/javascript? Depende de que ests usando para programar web con python. mod_python ? mod_wsgi ? fastcgi ? Tal vez te interesa leer este documento antes de empezar con la programacin web con python #5 (permalink) 02/10/2011, 01:13 cristian_cena Colaborador Fecha de Ingreso: junio-2009 Mensajes: 2.219 Antigedad: 4 aos, 2 meses Puntos: 268

Respuesta: como integrar python con html/css/javascript?

Muchas gracias por tu respuesta razpeitia, emm, supongo que lo mejor ser que use mod_python ya que uso apache para php. Soy super nuevo con python, solo escribi lineas en la consola pero nada ms. Gracias por el link me viene muy bien. Eternamente agradecido si tienes la amabilidad de traducir el cdigo que comparti arriba. Por simple que parezca, para m es de vital importancia. Saludos. #6 (permalink) 03/10/2011, 07:11 Fecha de Ingreso: julio-2005 Ubicacin: Canelones, Uruguay Mensajes: 7.442 Antigedad: 8 aos, 1 mes Puntos: 532

AlvaroG /bin/env python

Respuesta: como integrar python con html/css/javascript? Un ejemplo simple que te servir de base para traducir el PHP: http://www.howtoforge.com/embedding-...driva-opensuse Te recomiendo que desarrolles sobre frameworks. La facilidad de desarrollo y los sistemas integrados de cacheo hacen que valga la pena an para cosas pequeas. Saludos. __________________ blog ElCodiguero #7 (permalink) 03/10/2011, 08:16 cristian_cena Colaborador Fecha de Ingreso: junio-2009 Mensajes: 2.219 Antigedad: 4 aos, 2 meses Puntos: 268

Respuesta: como integrar python con html/css/javascript? Gracias AlvaroG, ya crea que lo mejor sera entrar con django y dejar de improvisar je. Muy tiles tus consejos, se agradece. #8 (permalink) 03/10/2011, 08:59 Fecha de Ingreso: julio-2005 Ubicacin: Canelones, Uruguay Mensajes: 7.442 Antigedad: 8 aos, 1 mes Puntos: 532

AlvaroG /bin/env python

Respuesta: como integrar python con html/css/javascript? Si, as es. No necesariamente Django, si quers pods empezar con Web2Py, CherryPy, Flesk, Pyramid, o cualquiera de los otros. El asunto es que ser mucho ms fcil y til: aunque quieras aprender lo bsico para sitios simples, a la hora de crear proyectos ms grandes seguro terminars usando algn framework. Me gustara ahondar en el asunto del cache, ya que uno a veces evita los frameworks porque los considera demasiado pesados para algunos proyectos. Si vos tens una pgina hecha a mano, simple pero sin cache, se estar ejecutando cada vez que se la solicite. Con un framework tipo Django, que incorpora un sistema de cache, la pgina se crea 1 vez y luego se sirve desde el cache. Aunque esa primera vez sea menos eficiente que una solucin a mano, las subsecuentes peticiones servidas desde el cache compensan con creces esa generacin inicial. Te cuento una ancdota personal: en su momento (hace como 5 aos ya) quise hacer mi sitio en PHP a mano. Hice algo bastante rgido basado en un solo index.php que se encargaba de procesar plantillas y URLs. Por probar, lo compar en mi servidor local, usando el comando "ab", contra el mismo sitio creado con: - Zend FW - WordPress - WordPress + WP SuperCache Ya no recuerdo exactamente los nmeros, pero la cantidad de peticiones procesadas por minuto era algo as como 10-15mil para mi sitio, 5000 para el sitio basado en Zend, 300 para WP, y 50000 para WP + SuperCache. Es decir: mi sitio era 50 veces ms rpido que WP, 2-3 veces ms rpido que Zend, pero 3-4 veces ms lento que WP con un cache apropiado. Si tomamos los nmeros como correctos, y hacemos algunas cuentas, vemos que la generacin de la pgina en WP tomaba 200 ms, y servirla del cache 1,2 ms. En mi solucin, cada peticin demoraba 4 ms, por lo que resultaba ms lenta luego de servir 72 pginas. Seguramente los nmeros hoy en da sean diferentes (y no vayas a tomar estos nmeros como indicadores de nada, son solamente un ejemplo), y para cada caso habr que estudiarlo, pero la conclusin es que un buen cache hace que un framework sea ms rpido que las soluciones a medida, y por eso vale la pena usarlos incluso para pginas relativamente estticas, por su facilidad de desarrollo. Por supuesto que para aprender uno siempre busca ir a lo bsico, pero hay que saber cundo vale la pena

Saludos. __________________ blog ElCodiguero #9 (permalink)

03/10/2011, 18:05 Carlangueitor Moderador () Fecha de Ingreso: marzo-2008 Ubicacin: Mxico Mensajes: 7.507 Antigedad: 5 aos, 5 meses Puntos: 973

Respuesta: como integrar python con html/css/javascript? Hola cristian_cena, recin veo tu MP. Has como dice Alvaro, si empiezas con Django y empiezas a leer los primeros captulos de djangobook vas a ver como te conviene hacerlo con un Framework, es toda una delicia. Yo realmente no tengo mucho tiempo programando en python (4 o 6 meses), pero si tienes buenas bases de programacin no te ser difcil. Saludos __________________ Aprender sin pensar es intil. Pensar sin aprender, peligroso. //////////////////////////////////////////////////////////////////////////////////////////////
ueno lo prometido es deuda. He aqui ejemplos de programas en Python. Espero les sirva. 1. Cmo imprimir? print "Hola usuario" cadena="Soy buena onda" print cadena

2. Cmo crear una funcin? def msgSinArgumentos(): print "Yo no tengo parmetros" def msgConArgumentos(cad): cad="Yo si tengo parmetros" print cad Ejemplos. 1. Factorial.py ''' Crear una funcin para calcular el factorial ''' def factorial(x): if x==0: return 1

else: return x * factorial(x -1) #main numero=0 continuar='n' print "Factorial de un numero"

while continuar!='s': continuar=raw_input('Desea realizar el clculo? Si->s No-n: ') while numero<=0: numero=int(raw_input('Introduce numero:')) resultado=factorial(numero)

print "El factorial de %d es %d" %(numero,resultado) 2. Sumatoria.py suma, numero, maxi=2, 4, 100 print "Inicio" print "Sumatoria del 2+..+100" while (numero<=maxi): suma=suma+numero numero=numero+2 print "Suma parcial [",suma,"] no. ",numero," \n" print "Suma total [",suma,"]" print "Fin" 3. Bucles.py from math import* vo=0 vector=[0.25,0.50,0.75,1.0] print "Inicio" print "Bucles con vectores" for i in vector: vo=vo+pow(i,2) print "Valor original= ",i," resultado= ",vo print "Fin" 4. Menu.py from math import* def Funcion_Seno(x): return cos(x)-x def Funcion_Coseno(x): return sin(x)-x MX=30

resultado=0 contador=0 opcion=0 print "*** [ Funciones matemticas en Python ] ***" print"\n\t 1. Calcular funcin seno 2. Calcular funcin coseno 3. Salir" while opcion<=0: opcion=int(raw_input('Tu opcin es:')) if opcion==1: print "Elegiste calcular funcin seno [sin(x)-x]" while contador<=MX: contador+=1 resultado=Funcion_Seno(contador) print "\nValor = ",resultado," posicin no. ",contador elif opcion==2: print "Elegiste calcular funcin coseno [cos(x)-x]" while contador<=MX: contador+=1 resultado=Funcion_Coseno(contador) print "\nValor = ",resultado," posicin no. ",contador elif opcion==3: exit() else: print "Opcin invlida"

5.Area.py #ejemplo de POO en Python class Area: def AsignaBase(self,base): self.base=base def AsignaAltura(self, altura): self.altura=altura def ObtenerBase(self): return self.base def ObtenerAltura(self): return self.altura def CalcArea(self): return self.base*self.altura/2 #main b, h=0, 0 print "**** [Clculo del rea]****" MiCalculo=Area() while b<=0: b=float(raw_input('Base: ')) while h<=0: h=float(raw_input('Altura: ')) MiCalculo.AsignaBase(b) MiCalculo. AsignaAltura(h) print "Base leida: %f"%MiCalculo.ObtenerBase() print "Altura leida: %f"%MiCalculo.ObtenerAltura()

print "rea obtenida: %f"%MiCalculo.CalcArea()

6. Uso de while, para alcular la velocidad dt,k1,k2,vo,maximo,cont=0.5,9.81,0.2,0,50,0 print "[Obtener velocidad]" while (cont<maximo): vo=vo+(k1-(k2*vo))*cont cont=cont+dt print "",vo," --> periodo:[",cont,"]"

7. Men sencillo en Python def obtenerFahrenheit(gc): return (gc*1.8)+32 def obtenerCelsius(gf): return (gf-32)/1.8 salir="s" opc=0 grados=0 while salir =="s": print "[Conversor de temperaturas]\n" print "1. Obtener grados fahrenheit" print "2. Obtener grados celsius" while opc<=0: opc=int(raw_input('Introduce opcin:')) if opc==1: print "[Obtener fahrenheit]\n" while grados<=0: grados=float(raw_input('Introduce valor: ')) print grados," celsius leidos" print "Grados fahrenheit obtenidos: ",obtenerFahrenheit(grados)

if opc==2: print "[Obtener celsius]\n" while grados<=0: grados=float(raw_input('Introduce valor: ')) print grados," fahrenheit leidos" print "Grados celsius obtenidos: ",obtenerCelsius(grados) else: print "opcin no vlida"

salir=raw_input('Deseas realizar ota operacin? (s/n):') print "" if salir=="n": print "adios" 8. Sustituir un nmero de un arreglo ''' sustituir un elemento de un arreglo ''' numeros=[1,2,3,4,5,6,7,8,9,10] i,sustituto=0,564 for i in range(len(numeros)): if numeros[i]==6: numeros[i]=sustituto print numeros[i] ////////////////////////////////////////////////////////

Ejercicios resueltos de programacin, en Python y en espaol, I.


Hola. Este es el primero de la serie de artculos que presentar estos das sobre una coleccin de ejercicios muy bsicos de programacin, para resolver con Python (o cualquier otro lenguaje). Decir que son muy sencillos y sirven para afianzar conocimientos bsicos de sintaxis y razonamiento. Si eres novel en programacin en Python, este post es para t. De lo contrario, te resultarn triviales los planteamientos expuestos. Los enunciados los he obtenido del libro Esquemas Algortmicos Fundamentales - Secuencias e Iteracin, de P.C. Scholl y J.P. Peyrin, editorial Masson.

Ejercicio 1. Escribir un algoritmo que, para cualquier nmero de segundos inferior a un milln, calcule su equivalente en das, horas, minutos y segundos. En este ejercicio tenemos que tener en cuenta que: 1 minuto = 60 segundos. 1 hora = 60 minutos = 3600 segundos. 1 dia = 24 horas = 1440 minutos = 86400 segundos. # Pedimos datos. dato = raw_input(u'Nmero de segundos: ') # Hacemos un cast, convirtiendo la cadena en un nmero largo. dato = long(dato)

# Comprobamos si el nmero introducido es menor a un milln. if dato >= 1000000: print "El nmero debe de ser menor a 1000000" else: # Das. ndias, aux = divmod(dato, 86400) # Horas. nhoras, aux = divmod(aux, 3600) # Minutos y segundos. nmin, nseg = divmod(aux, 60) # Mostramos resultado. print '%d das, %d horas, %d minutos, %d segundos' % \ (ndias, nhoras, nmin, nseg) Ejercicio 2. Escribir un algoritmo que imprima el mnimo, el mximo y la media de tres nmeros.

# Obtenemos nmeros. numeros = [] for i in ['primer', 'segundo','tercer']: texto = u'Introduce el %s nmero: ' % (i) numeros.append(float(raw_input(texto))) # Ordenamos. numeros.sort() # Obtenemos mximo y mnimo. minimo = numeros[0] maximo = numeros[2] # Obtenemos la media aritmtica. media = round((numeros[0] + numeros[1] + numeros[2]) / float(3),3) # Visualizamos resultados. cadena = u'Mnimo: %d, Mximo: %d, Media: %f' % (minimo, maximo, media) print cadena Ejercicio 3. Escribir un algoritmo que, dado el infinitivo de un verbo regular de la primera conjugacin, obtenga la conjugacin en singular y plural de presente de indicativo. Por ejemplo, para el verbo cantar el resultado es yo canto, tu cantas, el canta, nosotros cantamos, vosotros cantis, ellos cantan.

pronombre = ['yo','tu','el','nosotros','vosotros','ellos'] terminaciones = {'yo':'o', 'tu':'as', 'el':'a', 'nosotros':'amos', 'vosotros':u'is', 'ellos':'an'} # Pedimos datos. palabra = raw_input(u'Verbo regular 1ra. conjugacin: ') # Recorremos la tabla hashing (diccionario), construyendo la conjugacin verbal. for i in pronombre: print i, palabra[0:len(palabra)-2] + terminaciones[i] Ejercicio 4. Escribir un algoritmo que, para un nmero binario de 4 cifras, imprima su valor en base 10. Se estudiarn dos formas del problema segn la representacin de los datos: -forma 1: los datos son cuatro enteros (0 1). Por ejemplo: 1,1,0,1. -forma 2: el dato es un entero cuya representacin decimal con cuatro cifras no contenga ms que 0 1: Por ejemplo: 1101.

# Obtenemos datos. nbinario = raw_input(u'Nmero binario (4 cifras): ') # Obtenemos los dgitos. nbinario = nbinario.split(',') if len(nbinario) == 1: nbinario = list(nbinario[0]) # Inicializamos algunos contadores. decimal = 0 potencia = 0 # Le damos la vuelta al nmero binario. nbinario.reverse() # Calculamos el nmero decimal, a partir del nmero binario. for i in nbinario: decimal += pow(2,potencia) if i == '1' else 0 potencia += 1

# Visualizamos resultado. cadena = u'Su representacin decimal es %d' % (decimal) print cadena Ejercicio 5. Escribir un algoritmo que decodifique fechas del siglo XXI. El dato es un entero comprendido entre 10100 y 311299. El resultado es una secuencia de caracteres: nmero del da dentro del mes, del mes dentro del ao y del ao dentro del siglo. Por ejemplo, para el dato 30485, el resultado es el texto 3-4-2085.

# Obtenemos dato. dato = raw_input('Introduce dato: ') # Decodificamos ao dentro del siglo XXI. anyo = 2000 + int(dato[len(dato)-2:]) # Decodificamos mes. mes = int(dato[len(dato)-4:len(dato)-2]) # Decodificamos da. dia = int(dato[:len(dato)-4]) # Mostramos resultado. cadena = '%d-%d-%d' % (dia, mes, anyo) print cadena Ejercicio 6. Escribir un algoritmo que, para una suma de dinero dada, indique cmo descomponerla en billetes y monedas corrientes. Se desea utilizar el mnimo de billetes y monedas. No hay ninguna limitacin respecto al nmero de billetes y monedas disponibles.

# Declaramos datos bsicos (euros) con los que trabajar. billetes_y_monedas = [500,200,100,50,20,10,5, 2, 1, 0.50, 0.20, 0.10, 0.05, 0.02, 0.01] # Creamos un monedero, donde meter el dinero. monedero = [] # Pedimos la cantidad. dato = raw_input(u'Introducir importe (euros): ') # Buscamos parte decimal y entera.

dato = dato.split('.') # Decimal... try: parte_decimal = float('0.'+dato[1]) except: parte_decimal = 0.0 # Entera... parte_entera = long(dato[0]) # Algoritmo de asignacin de dinero. for i in billetes_y_monedas: # Obtenemos nmero de billetes monedas y los guardamos. unidades, resto = divmod(parte_entera, i) if unidades != 0: monedero.append((i,unidades)) # Asignamos lo que nos queda. parte_entera = resto if parte_decimal > 0: for i in billetes_y_monedas: # Obtenemos nmero de monedas y los guardamos. unidades, resto = divmod(parte_decimal, i) if unidades != 0: monedero.append((i,unidades)) # Asignamos lo que nos queda. parte_decimal = round(resto,2) # Visualizamos el resultado. cadena = '' for i in monedero: if i[0] >= 5: cadena += '%d billete/s de %d euros' % (i[1],i[0]) if i[0] < 5: cadena += '%d moneda/s de %s euros' % (i[1],i[0]) cadena += '\n' print cadena Ejercicio 7. Escribir un algoritmo que simule el funcionamiento de una calculadora. El dato es una serie de tres caracteres: una cifra, un smbolo de operacin y otra cifra. El resultado es el valor de la expresin dada. # Pedimos datos. dato = raw_input(u'Introduce operacin: ') # Inicializamos resultado.

resultado = 0 # Suma? serie = dato.split('+') if len(serie) == 2: resultado = long(serie[0]) + long(serie[1]) else: # Resta? serie = dato.split('-') if len(serie) == 2: resultado = long(serie[0]) - long(serie[1]) else: # Multiplicacin? serie = dato.split('*') if len(serie) == 2: resultado = long(serie[0]) * long(serie[1]) else: # Divisin? serie = dato.split('/') if len(serie) == 2: resultado = long(serie[0]) / long(serie[1]) # Mostramos resultado. print "El resultado es",resultado Ejercicio 8. Consideremos una hora expresada en forma de tripleta . Escribir un algoritmo que imprima la hora correspondiente al siguiente segundo. Por ejemplo, para la entrada 13,43,24 tiene que devolver 13,43,25. Se supone que lo que introducimos es una hora correcta. Darse cuenta que no se chequean los datos introducidos, por cuestin de simplicidad. # Pedimos datos. tiempo = raw_input('Introduce tiempo: ') # Obtenemos datos. aux = tiempo.split(',') horas = int(aux[0]) minutos = int(aux[1]) segundos = int(aux[2]) # Aumentamos un segundo. segundos += 1 # Casos. if segundos != 60: tiempo = (horas, minutos, segundos)

else: if minutos == 59 and horas == 23: tiempo = (0, 0, 0) else: if minutos == 59: tiempo = (horas + 1, 0, 0) else: tiempo = (horas, minutos + 1, 0) # E imprimimos resultado (una tupla). print tiempo Ejercicio 9. Escribir una funcin que determine si una letra dada es consonante. A la funcin le faltara controlar las letras con acentuacin (tildes, diresis, etc). def es_consonante(letra): if letra.lower() not in ['a','e','i','o','u']: return True else: return False Ejercicio 10. Escribir una funcin que calcule el factorial de un nmero. Por ejemplo, 5! = 5*4*3*2*1 = 120.

def factorial(numero): return 1 if numero <=0 else numero * factorial(numero -1)

Saludos. en 14:07 Enviar por correo electrnicoEscribe un blogCompartir con TwitterCompartir con Facebook Etiquetas: ejercicios, python 94 comentarios:

1. Jos Julio9 de enero de 2011 20:36

Esta es una solucin ms corta para el problema 6: #-*- coding: UTF-8 -*cifra = float(raw_input(u'Cuntos euros? ')) monedas = [500, 200, 100, 50, 20, 10, 5, 2, 1] cociente = cifra centimos = int(100 * (cifra - int(cifra))) for x in monedas: if cociente >= x: cociente, resto = divmod(cociente, x) if x > 2: print cociente, ' billete de ', x if x == 2: print cociente, ' monedas de ', x if x == 1: print cociente, ' moneda de ', x cociente = resto print centimos, u' cntimos' ////////////////////////////////////////////////////////////////////////////////////

Mi diario Python
Diario sobre el aprendizaje en python. Ejercicios paso a paso, tutoriales, traduccin de manuales en ingles y alguna cosa mas...

Ir al Inicio ejercicios , ejercicios en python , python ejercicios Ejercicios en python (Parte 1)

Ejercicios en python (Parte 1)


lunes, 27 de mayo de 2013

Voy a dejar algunos ejercicios en python. Si hay alguna dificultad no duden en

Ejercicios Python comentar. Tambin voy a crear un post con mis soluciones, ustedes pueden aportar las suyas. 1- Definir una funcin max() que tome como argumento dos nmeros y devuelva el mayor de ellos. (Es cierto que python tiene una funcin max() incorporada, pero hacerla nosotros mismos es un muy buen ejercicio. 2- Definir una funcin max_de_tres(), que tome tres nmeros como argumentos y devuelva el mayor de ellos. 3- Definir una funcin que calcule la longitud de una lista o una cadena dada. (Es cierto que python tiene la funcin len() incorporada, pero escribirla por nosotros mismos resulta un muy buen ejercicio. 4- Escribir una funcin que tome un carcter y devuelva True si es una vocal, de lo contrario devuelve False. 5- Escribir una funcion sum() y una funcin multip() que sumen y multipliquen respectivamente todos los nmeros de una lista. Por ejemplo: sum([1,2,3,4]) debera devolver 10 y multip([1,2,3,4]) debera devolver 24. 6- Definir una funcin inversa() que calcule la inversin de una cadena. Por ejemplo la cadena "estoy probando" debera devolver la cadena "odnaborp yotse" 7 - Definir una funcin es_palindromo() que reconoce palndromos (es decir, palabras que tienen el mismo aspecto escritas invertidas), ejemplo: es_palindromo ("radar") tendra que devolver True. 8- Definir una funcin superposicion() que tome dos listas y devuelva True si tienen al menos 1 miembro en comn o devuelva False de lo contrario. Escribir la funcin usando el bucle for anidado.

9- Definir una funcin generar_n_caracteres() que tome un entero n y devuelva el caracter multiplicado por n. Por ejemplo: generar_n_caracteres(5, "x") debera devolver "xxxxx". 10- Definir un histograma procedimiento() que tome una lista de nmeros enteros e imprima un histograma en la pantalla. Ejemplo: procedimiento([4, 9, 7]) debera imprimir lo siguiente: ****

Listas - Soluciones (1)


Se ofrecen a continuacin unas posibles soluciones de los ejercicios de listas (1).

Listas (1) - 1

Este programa puede incluir un bucle que se ejecute tantas veces como palabras tiene la lista. En cada iteracin del bucle, se pide un valor y se aade a la lista.

numero = int(input("Dgame cuntas palabras tiene la lista: ")) if numero < 1: print("Imposible!") else: lista = [] for i in range(numero): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() lista += [palabra] print("La lista creada es:", lista)

Listas (1) - 2

Para contar los elementos, este programa puede incluir un bucle que recorra la lista una vez creada. Puesto que no se van a modificar los valores de la lista, la lista se puede recorrer directamente (for i in lista). En cada iteracin del bucle, se compara el valor de la lista con el valor buscado y si coinciden, se aumenta el valor de un contador.

numero = int(input("Dgame cuntas palabras tiene la lista: ")) if numero < 1: print("Imposible!") else: lista = [] for i in range(numero): print("Dgame la palabra", str(i + 1) + ": ", end="")

palabra = input() lista += [palabra] print("La lista creada es:", lista) input("Dgame la palabra = 0 lista: == buscar: contador += 1; if contador == 0: print("La palabra '" + buscar elif contador == 1: print("La palabra '" + buscar lista.") else: print("La palabra '" + buscar en la lista.") buscar = contador for i in if i a buscar: ")

+ "' no aparece en la lista.") + "' aparece una vez en la + "' aparece", contador, "veces

Listas (1) - 3

Para sustituir los elementos, este programa puede incluir un bucle que recorra la lista una vez creada. Puesto que se van a modificar los valores de la lista, la lista se tiene que recorrer indirectamente (for i in range(len(lista))). En cada iteracin del bucle, se compara el valor de la lista con el valor buscado y si coinciden, se sustituye el valor de la lista.

numero = int(input("Dgame cuntas palabras tiene la lista: ")) if numero < 1: print("Imposible!") else: lista = [] for i in range(numero): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() lista += [palabra] print("La lista creada es:", lista) buscar = input("Sustituir la palabra: ") sustituir = input("por la palabra: ") for i in range(len(lista)): if lista[i] == buscar: lista[i] = sustituir print("La lista es ahora:", lista)

Listas (1) - 4

Para borrar los elementos, este programa puede incluir un bucle que recorra la lista una vez creada. Puesto que se van a modificar los valores de la lista, la lista se tiene que recorrer indirectamente (for i in range(len(lista))). En cada iteracin del bucle, se compara el valor de la lista con el valor buscado y si coinciden, se elimina el valor de la lista.

Un detalle importante es que la lista se tiene que recorrer al revs (del ltimo al primer elemento) por dos motivos: o Si la lista se recorre del primer al ltimo elemento, al eliminar un elemento la lista se acorta. Como el bucle se ejecuta tantas veces como elementos tena originalmente, al llegar a la ltima iteracin, se estara haciendo referencia a un elemento que ya no existe, lo que producira un error. Si se eliminan ms elementos, el error se producira antes. o Si la lista se recorre del primer al ltimo elemento, al eliminar un elemento los elementos siguientes avanzan una posicin. En la siguiente iteracin del bucle, se compara el elemento siguiente al borrado, por lo que el elemento que ha ocupado la posicin del elemento borrado escapa a la comprobacin. Este problema puede pasar desapercibido si la lista no contiene dos elementos seguidos a eliminar.

numero = int(input("Dgame cuntas palabras tiene la lista: ")) if numero < 1: print("Imposible!") else: lista = [] for i in range(numero): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() lista += [palabra] print("La lista creada es:", lista) eliminar = input("Palabra a eliminar: ") for i in range(len(lista)-1, -1, -1): if lista[i] == eliminar: del(lista[i]) print("La lista es ahora:", lista)

Listas (1) - 5

Este ejercicio es similar al anterior. Este programa puede incluir un bucle que recorra la lista de palabras a eliminar y en cada iteracin elimine una palabra. La lista de palabras a eliminar se puede recorrer de forma directa, mientras que la lista de palabras inicial debe recorrerse de forma indirecta y al revs por los mismos motivos que en el ejercicio anterior.

numero = int(input("Dgame cuntas palabras tiene la lista: ")) if numero < 1: print("Imposible!") else: lista = [] for i in range(numero): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() lista += [palabra] print("La lista creada es:", lista) numero2 = int(input("Dgame cuntas palabras tiene la lista de

palabras a eliminar: ")) if numero2 < 1: print("Imposible!") else: eliminar = [] for i in range(numero2): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() eliminar += [palabra] print("La lista de palabras a eliminar es:", eliminar) for i in eliminar: for j in range(len(lista)-1, -1, -1): if lista[j] == i: del(lista[j]) print("La lista es ahora:", lista)

Listas (1) - 6

Para crear la lista inversa, este programa puede incluir un bucle que recorra la lista una vez creada. Puesto que no se van a modificar los valores de la lista, la lista se puede recorrer directamente (for i in lista). En cada iteracin del bucle, se aade el elemento de la lista inicial al principio de la lista inversa.

numero = int(input("Dgame cuntas palabras tiene la lista: ")) if numero < 1: print("Imposible!") else: lista = [] for i in range(numero): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() lista += [palabra] print("La lista creada es:", lista) inversa = [] for i in lista: inversa = [i] + inversa print("La lista inversa es:", inversa)

Listas (1) - 7

Para eliminar los elementos repetidos, este programa puede incluir un bucle que recorra la lista una vez creada. Puesto que se van a eliminar los valores de la lista, la lista se debe recorrer indirectamente y al revs ( for i in range(len(lista)-1, -1, -1)). En cada iteracin del bucle, se comprueba si el elemento se encuentra en la sublista anterior a ese elemento (desde el principio hasta el elemento anterior) y si es as, se borra.

numero = int(input("Dgame cuntas palabras tiene la lista: ")) if numero < 1: print("Imposible!") else: lista = [] for i in range(numero): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() lista += [palabra] print("La lista creada es:", lista) for i in range(len(lista)-1, -1, -1): if lista[i] in lista[:i]: del(lista[i]) print("La lista sin repeticiones es:", lista)

Listas (1) - 8

El programa debe empezar pidiendo dos listas y eliminando los elementos repetidos, como en el ejercicio anterior. Puesto que se van a eliminar los valores de la lista, la lista se debe recorrer indirectamente y al revs ( for i in range(len(lista)-1, -1, -1)). En cada iteracin del bucle, se comprueba si el elemento se encuentra en la sublista anterior a ese elemento (desde el principio hasta el elemento anterior) y si es as, se borra.

numero = int(input("Dgame cuntas palabras tiene la primera lista: ")) if numero < 1: print("Imposible!") else: primera = [] for i in range(numero): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() primera += [palabra] print("La primera lista es:", primera) for i in range(len(primera)-1, -1, -1): if primera[i] in primera[:i]: del(primera[i]) # print("La primera lista sin repeticiones es:", primera) numero2 = int(input("Dgame cuntas palabras tiene la segunda lista: ")) if numero2 < 1: print("Imposible!") else: segunda = [] for i in range(numero2): print("Dgame la palabra", str(i + 1) + ": ", end="") palabra = input() segunda += [palabra] print("La segunda lista es:", segunda)

for i in range(len(segunda)-1, -1, -1): if segunda[i] in segunda[:i]: del(segunda[i]) # print("La segunda lista sin repeticiones es:", segunda) comunes = [] for i in primera: if i in segunda: comunes += [i] print("Palabras que aparecen en las dos listas:", comunes) soloPrimera = [] for i in primera: if i not in segunda: soloPrimera += [i] print("Palabras que slo aparecen en la primera lista:", soloPrimera) soloSegunda = [] for i in segunda: if i not in primera: soloSegunda += [i] print("Palabras que slo aparecen en la segunda lista:", soloSegunda) todas = comunes + soloPrimera + soloSegunda print("Todas las palabras:", todas)

///// Su pregunta

Listas - Ejercicios (1)


Estos ejercicios corresponden a lo explicado en la leccin Listas. Se pueden consultar unas posibles soluciones.

Listas (1) - 1
Escriba un programa que permita crear una lista de palabras. Para ello, el programa tiene que pedir un nmero y luego solicitar ese nmero de palabras para crear la lista. Por ltimo, el programa tiene que escribir la lista. Dgame cuntas palabras tiene la lista: 3 Dgame la palabra 1: Alberto Dgame la palabra 2: Benito Dgame la palabra 3: Carmen

La lista creada es: ['Alberto', 'Benito', 'Carmen'] Dgame cuntas palabras tiene la lista: 0 Imposible!

Listas (1) - 2
Escriba un programa que permita crear una lista de palabras y que, a continuacin, pida una palabra y diga cuntas veces aparece esa palabra en la lista. Dgame cuntas palabras tiene la lista: 4 Dgame la palabra 1: Carmen Dgame la palabra 2: Alberto Dgame la palabra 3: Benito Dgame la palabra 4: Carmen La lista creada es: ['Carmen', 'Alberto', 'Benito', 'Carmen'] Dgame la palabra a buscar: Carmen La palabra 'Carmen' aparece 2 veces en la lista. Dgame cuntas palabras tiene la lista: 4 Dgame la palabra 1: Carmen Dgame la palabra 2: Alberto Dgame la palabra 3: Benito Dgame la palabra 4: Carmen La lista creada es: ['Carmen', 'Alberto', 'Benito', 'Carmen'] Dgame la palabra a buscar: Alberto La palabra 'Alberto' aparece una vez en la lista. Dgame cuntas palabras tiene la lista: 4 Dgame la palabra 1: Carmen

Dgame la palabra 2: Alberto Dgame la palabra 3: Benito Dgame la palabra 4: Carmen La lista creada es: ['Carmen', 'Alberto', 'Benito', 'Carmen'] Dgame la palabra a buscar: David La palabra 'David' no aparece en la lista.

Listas (1) - 3
Escriba un programa que permita crear una lista de palabras y que, a continuacin, pida dos palabras y sustituya la primera por la segunda en la lista. Dgame cuntas palabras tiene la lista: 4 Dgame la palabra 1: Alberto Dgame la palabra 2: Carmen Dgame la palabra 3: Benito Dgame la palabra 4: Carmen La lista creada es: ['Alberto', 'Carmen', 'Benito', 'Carmen'] Sustituir la palabra: Carmen por la palabra: David La lista es ahora: ['Alberto', 'David', 'Benito', 'David']

Listas (1) - 4
Escriba un programa que permita crear una lista de palabras y que, a continuacin, pida una palabra y elimine esa palabra de la lista. Dgame cuntas palabras tiene la lista: 4 Dgame la palabra 1: Alberto Dgame la palabra 2: Carmen

Dgame la palabra 3: Carmen Dgame la palabra 4: Benito La lista creada es: ['Alberto', 'Carmen', 'Carmen', 'Benito'] Palabra a eliminar: Carmen La lista es ahora: ['Alberto', 'Benito']

Listas (1) - 5
Escriba un programa que permita crear dos listas de palabras y que, a continuacin, elimine de la primera lista los nombres de la segunda lista. Dgame cuntas palabras tiene la lista: 5 Dgame la palabra 1: Carmen Dgame la palabra 2: Carmen Dgame la palabra 3: Alberto Dgame la palabra 4: Benito Dgame la palabra 5: David La lista creada es: ['Carmen', 'Carmen', 'Alberto', 'Benito', 'David'] Dgame cuntas palabras tiene la lista de palabras a eliminar: 3 Dgame la palabra 1: Benito Dgame la palabra 2: Juan Dgame la palabra 3: Carmen La lista de palabras a eliminar es: ['Benito', 'Juan', 'Carmen'] La lista es ahora: ['Alberto', 'David']

Listas (1) - 6
Escriba un programa que permita crear una lista de palabras y que, a continuacin, cree una segunda lista igual a la primera, pero al revs (no se trata de escribir la lista al revs,

sino de crear una lista distinta). Dgame cuntas palabras tiene la lista: 4 Dgame la palabra 1: Alberto Dgame la palabra 2: Carmen Dgame la palabra 3: Benito Dgame la palabra 4: Daniel La lista creada es: ['Alberto', 'Carmen', 'Benito', 'Daniel'] La lista inversa es: ['Daniel', 'Benito', 'Carmen', 'Alberto']

Listas (1) - 7
Escriba un programa que permita crear una lista de palabras y que, a continuacin, elimine los elementos repetidos (dejando nicamente el primero de los elementos repetidos). Dgame cuntas palabras tiene la lista: 4 Dgame la palabra 1: Alberto Dgame la palabra 2: Carmen Dgame la palabra 3: Benito Dgame la palabra 4: Carmen La lista creada es: ['Alberto', 'Carmen', 'Benito', 'Carmen'] La lista sin repeticiones es: ['Alberto', 'Carmen', 'Benito']

Listas (1) - 8
Escriba un programa que permita crear dos listas de palabras y que, a continuacin, escriba las siguientes listas (en las que no debe haber repeticiones):

Lista de palabras que aparecen en las dos listas. Lista de palabras que aparecen en la primera lista, pero no en la segunda. Lista de palabras que aparecen en la segunda lista, pero no en la primera. Lista de palabras que aparecen en ambas listas.

Nota: Para evitar las repeticiones, el programa deber empezar eliminando los elementos repetidos en cada lista. Dgame cuntas palabras tiene la primera lista: 4 Dgame la palabra 1: Carmen Dgame la palabra 2: Alberto Dgame la palabra 3: Benito Dgame la palabra 4: Carmen La primera lista es: ['Carmen', 'Alberto', 'Benito', 'Carmen'] Dgame cuntas palabras tiene la segunda lista: 3 Dgame la palabra 1: Benito Dgame la palabra 2: Juan Dgame la palabra 3: Carmen La segunda lista es: ['Benito', 'Juan', 'Carmen'] Palabras que aparecen en las dos listas: ['Carmen', 'Benito'] Palabras que slo aparecen en la primera lista: ['Alberto'] Palabras que slo aparecen en la segunda lista: ['Juan'] Todas las palabras: ['Carmen', 'Benito', 'Alberto', 'Juan']

Bucle while - Ejercicios (1)


Estos ejercicios corresponden a lo explicado en la leccin sobre el bucle while. Se pueden consultar unas posibles soluciones.

Nota: En estos ejercicios no se debe realizar ninguna comprobacin de tipos, es decir, que si el programa pide un nmero y el usuario escribe una palabra, los programas pueden fallar e interrumpirse.

Bucle while (1) - 01


Escriba un programa que pida palabras y las guarde en una lista. Para terminar de introducir palabras, simplemente debe pulsarse Intro. El programa termina escribiendo la lista de palabras. Escriba una palabra: viaje Escriba otra palabra: aventura Escriba otra palabra: tebeo Escriba otra palabra: Las palabras que ha escrito son ['viaje', 'aventura', 'tebeo']

Bucle while (1) - 02


Escriba un programa que pida nmeros enteros y los guarde en una lista. Para terminar de introducir nmeros, simplemente debe pulsarse Intro. El programa termina escribiendo la lista de nmeros. Escriba un nmero: 14 Escriba otro nmero: 123 Escriba otro nmero: -25 Escriba otro nmero: 123 Escriba otro nmero: Los nmeros que ha escrito son [14, 123, -25, 123]

Bucle while (1) - 03


Escribe un programa que te pida notas (nmeros decimales entre 0 y 10) y las guarde en una lista. Para terminar de introducir notas, escriba una nota que no est entre 0 y 10. El programa termina escribiendo la lista de notas. La lista de notas final no debe escribirse como lista, sino como valores separados por espacios. Escriba una nota: 7.5 Escriba una nota: 0

Escriba una nota: 10 Escriba una nota: -1 Las notas que ha escrito son: 7.5 0.0 10.0

Bucle while (1) - 04


Escriba un programa que pida dos nmeros enteros, de manera que el segundo sea mayor que el primero. El programa termina escribiendo los dos nmeros. Escriba un nmero: 6 Escriba un nmero mayor que 6: 6 6 no es mayor que 6. Intntelo de nuevo: 1 1 no es mayor que 6. Intntelo de nuevo: 8 Los nmeros que ha escrito son 6 y 8.

Bucle while (1) - 05


Escriba un programa que pida nmeros enteros cada vez ms grandes y los guarde en una lista. Para terminar de escribir nmeros, escriba un nmero que no sea mayor que el anterior. El programa termina escribiendo la lista de nmeros. Escriba un nmero: 6 Escriba un nmero mayor que 6: 10 Escriba un nmero mayor que 10: 12 Escriba un nmero mayor que 12: 25 Escriba un nmero mayor que 25: 9 Los nmeros que ha escrito son [6, 10, 12, 25]

Bucle while (1) - 06


Escriba un programa que pida primero dos nmeros enteros (mnimo y mximo) y que despus pida nmeros enteros situados entre ellos. Para terminar de escribir nmeros,

escriba un nmero que no est comprendido entre los dos valores iniciales. El programa termina escribiendo la lista de nmeros. Escriba un nmero: 6 Escriba un nmero mayor que 6: 4 4 no es mayor que 6. Intntelo de nuevo: 50 Escriba un nmero entre 6 y 50: 45 Escriba otro nmero entre 6 y 50: 13 Escriba un nmero entre 6 y 50: 4 Los nmeros situados entre 6 y 50 que ha escrito son [45, 13]

Bucle while (1) - 07


Escriba un programa que pida primero un nmero entero (lmite) y despus pida nmeros enteros hasta que la suma de los nmeros introducidos supere el nmero inicial. El programa termina escribiendo la lista de nmeros. Escriba el lmite: 50 Escriba un nmero: 10 Escriba otro nmero: 25 Escriba otro nmero: 15 Escriba otro nmero: 14 El lmite a superar es 50. La lista creada es [10, 25, 15, 14]

Bucle while (1) - 08


Escriba un programa que pida primero un nmero entero y despus pida nmeros enteros hasta que la suma de los nmeros introducidos coincida con el nmero inicial. El programa termina escribiendo la lista de nmeros. Escriba el lmite: 50 Escriba un nmero: 10

Escriba otro nmero: 45 45 es demasiado grande. Escriba otro nmero: 1 Escriba otro nmero: 39 El lmite a alcanzar es 50. La lista creada es [10, 1, 39] Escriba el lmite: 50 Escriba un nmero: 60 60 es demasiado grande. Escriba otro nmero: 10 Escriba otro nmero: 45 45 es demasiado grande. Escriba otro nmero: 1 Escriba otro nmero: 39 El lmite a alcanzar es 50. La lista creada es [10, 1, 39]

Bucle while (1) - 09


Escriba un programa que pida nombres de personas y sus nmeros de telfono. Para terminar de escribir nombres y nmeros, se debe pulsar Intro cuando pida el nombre. El programa termina escribiendo todos los nombres y telfonos. Notas:

La lista en la que se guardan los nombres y telfonos puede ser [ [nombre1, telef1], [nombre2, telef2], [nombre3, telef3], etc] Una persona puede no tener nmero de telfono.

Escriba un nombre: Paco Jerte Escriba su telfono: 963141592 Escriba otro nombre: Susana Horia Escriba su telfono: Escriba otro nombre: Ulises Tropeado Escriba su telfono: 962718281 Escriba otro nombre:

Los nombres y telfonos son: Paco Jerte: 963141592 Susana Horia: Ulises Tropeado: 962718281

Bucle while (1) - 10


Escriba un programa que pida los nombres y las notas (decimales entre 0 y 10) de varios alumnos. Para terminar de escribir notas de un alumno, escriba una nota fuera del intervalo de 0 a 10. Para terminar de escribir nombres de alumnos, se debe pulsar Intro cuando pida el nombre. Notas:

La lista en la que se guardan los nombres y notas es [ [nombre1, nota1, nota2, ... ], [nombre2, nota1, nota2, ... ], [nombre3, nota1, nota2, ... ], ... ] Un alumno puede no tener notas

Escriba un nombre: Hctor Tuga Escriba una nota: 4 Escriba otra nota: 8.5 Escriba otra nota: 12 Escriba otro nombre: Diego Loso Escriba una nota: 14 Escriba otro nombre: Ins Pejo Escriba una nota: 7.5 Escriba otra nota: 1 Escriba otra nota: 2 Escriba otra nota: -5 Escriba otro nombre: Las notas de los alumnos son:

Hctor Tuga: 4.0 8.5 Diego Loso: Ins Pejo: 7.5 1.0 2.0 **********************La solucin:-------

También podría gustarte