0% encontró este documento útil (0 votos)
21 vistas

Python (Guia Rapida)

El documento es un curso rápido de Python que cubre desde la introducción al lenguaje hasta conceptos avanzados como programación orientada a objetos y manejo de excepciones. Se presentan temas como la definición de variables, estructuras condicionales, operadores matemáticos y relacionales, así como la creación de aplicaciones web utilizando Google App Engine. Además, incluye ejemplos prácticos y problemas propuestos para reforzar el aprendizaje.

Cargado por

vipij82682
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
21 vistas

Python (Guia Rapida)

El documento es un curso rápido de Python que cubre desde la introducción al lenguaje hasta conceptos avanzados como programación orientada a objetos y manejo de excepciones. Se presentan temas como la definición de variables, estructuras condicionales, operadores matemáticos y relacionales, así como la creación de aplicaciones web utilizando Google App Engine. Además, incluye ejemplos prácticos y problemas propuestos para reforzar el aprendizaje.

Cargado por

vipij82682
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 113

t: @charli3vazquez

Curso Rápido de Python

Recopilación de información: Carlos Daniel Vazquez


Twitter: @charli3vazquez
Fuente: pythonya.appspot.com
1
t: @charli3vazquez

Contenido:
1 - Introducción
2 - Definición de variables
3 - Definición de comentarios
4 - Operadores matemáticos
5 - Estructura condicional if
6 - Operadores relacionales
7 - Estructura condicional if anidada
8 - Operadores lógicos
9 - Estructura condicional if-elif
10 - Estructura repetitiva while
11 - Funciones
12 - Funciones con retorno de dato
13 - Estructura de datos tipo tupla
14 - Estructura repetitiva for in para recorrer una tupla
15 - Porciones de tuplas
16 - Estructura de datos tipo cadena de caracteres (string)
17 - Estructura de datos tipo lista
18 - Indices negativos en tuplas, listas y string
19 - Estructura de datos tipo diccionario
20 - Formato de cadenas de caracteres (string)
21 - Asignaciones múltiples
22 - Funciones con parámetros por defecto
23 - Funciones con una cantidad variable de parámetros
24 - Implementación de módulos
25 - Funciones de uso común (range - type - str - dir)
26 - Función de uso común (help)
27 - Conceptos de programación orientada a objetos
28 - Declaración de una clase y creación de objetos
29 - Atributos de una clase
30 - Metodos de una clase
31 - Metodo constructor de una clase
32 - Llamada de métodos dentro de la clase
33 - Herencia
34 - Método especial __str__
35 - Redefinición de los operadores matemáticos con objetos
36 - Redefinición de los operadores relacionales con objetos
37 - Las cadenas tratadas como objetos
38 - Las listas tratadas como objetos
39 - Los diccionarios tratados como objetos
40 - Instalación de Python en su computadora
41 - Creación, carga y lectura de archivos de texto
42 - Captura de excepciones
43 - Google App Engine utilizando Python
44 - Hola mundo con Google App Engine
45 - Subir nuestra aplicación Hola mundo a internet
46 - Recuperar el dato de un text (App Engine)
47 - Formulario HTML - control radio (App Engine)
48 - Formulario HTML - control select (App Engine)
49 - Formulario HTML - control select con selección múltiple (App Engine)
50 - Formulario HTML - control checkbox (App Engine)
51 - Formulario HTML - control textarea (App Engine)
52 - Alta y listado de una base de datos (App Engine)
53 - Consulta de datos (App Engine)
54 - Borrado de datos (App Engine)
55 - Modificación de datos (App Engine)
56 - Listado, Alta, Baja y Modificación (App Engine)

2
t: @charli3vazquez

1. Introducción
Python es un lenguaje de script desarrollado por Guido van Rossum.Podemos codificar
empleando programación lineal, estructurada y orientada a objetos (tengamos en cuenta
que esta última es la que se ha impuesto en la actualidad)
Se cuenta con intérpretes de Python en múltiples plataformas: Windows, Linux, Mac etc.
Se pueden desarrollar aplicaciones de escritorio como aplicaciones web. Empresas como
Google, Yahoo, Nasa etc. utilizan este lenguaje para sus desarrollos (actualmente el
creador de Python Guido van Rossum trabaja para Google.)
Se puede ejecutar instrucciones de Python desde la línea de comando o creando archivos
con extensión *.py. Cuando uno comienza a aprender este lenguaje la línea de comandos
nos provee una retroalimentación del resultado en forma inmediata.
El objetivo de este tutorial es presentar en forma progresiva los conceptos fundamentales
de este lenguaje y poder analizar los problemas resueltos y codificar los problemas
propuestos en este mismo sitio, sin tener que instalar en un principio el Python en su
equipo (o luego de instalado poder avanzar con el tutorial en cualquier máquina
conectada a internet)
Que podemos hacer con Python una vez que aprendamos su sintaxis y filosofía de
programación?

Aplicaciones que se ejecutan en un servidor web (equivalentes a lo que se puede hacer


con PHP, ASP.Net, JSP, Ruby) Más adelante cuando este más avanzado con el lenguaje
Python le será muy útil solicitar una cuenta en Google App Engine y crear un sitio
empleando como lenguaje de servidor el Python. También existen otras empresas de
hosting que proveen como lenguaje de servidor el Python. Y cuando necesitemos ser más
productivos en el desarrollo de sitios no podrá faltar el framework Django.

Aplicaciones de escritorio con interfaces visuales accediendo a componentes escritos


en .Net (Microsoft), Qt, GTK, MFC, Swing (Java) etc.

Programas no visuales que tengan como objetivo sistematizar procesos de administración


del equipo (backup periódicos, borrado de archivos recursivos, búsquedad de archivos o
contenidos de los mismos etc.)

Aplicaciones para celulares.

No podemos terminar con la introducción de este lenguaje sin codificar el famoso


problema que muestra el 'Hola Mundo':
print 'Hola Mundo'

Problema resuelto
Imprimir el mensaje 'Hola Mundo'
print 'Hola Mundo'

3
t: @charli3vazquez

2. Definicion de variables:
Una variable almacena un valor de cierto tipo. En Python podemos definir variables de
tipo:
Numérica (entera)
Numérica (flotante)
Numérica (complejo)
Cadena de caracteres
Booleano
Para definir una variable en Python solo debemos asignarle el valor, en dicho momento se
define el tipo de variable según el valor asignado (Python es un lenguaje sensible a
mayúsculas y minúsculas, por lo que debemos respetar esta característica):

Variable entera:
edad=21

Variable flotante:
altura=1.92

Variable compleja:
valor=5+3j

Cadena de caracteres (puede estar encerrada entre simples o dobles comillas):


nombre="Mario"

Booleano:
encontrado=False

Problema resuelto
Definir una variable de cada tipo y luego imprimirlas empleando la función print (como las
estamos mostrando en una página HTML podemos imprimir el elemento HTML br luego
de cada variable):
edad=21
altura=1.92
valor=5+3j
nombre="Mario"
encontrado=False
print edad
print "<br>"
print altura
print "<br>"
print valor
print "<br>"
print nombre
print "<br>"
print encontrado
print "<br>"

Problema Propuesto
Definir una variable donde almacenar su nombre y en otra su edad, mostrar luego los
valores almacenados con la leyenda previa que indique que representa:
nombre="ana"
edad=25
print "Nombre:"
print nombre
print "<br>"
print "Edad:"
print edad

4
t: @charli3vazquez

3. Definición de comentarios
En Python utilizamos el caracter # para indicar al intérprete que dicha línea es un
comentario y no la debe procesar como una instrucción de Python.
Es muy común utilizar comentarios para informar el objetivo del programa, su
desarrollador, la lógica de los algorítmos empleados etc.

Veamos un progrma que utiliza comentarios:


# Definición de tres variables enteras y una de tipo string
edad1=10
edad2=4
edad3=21
nombre="pedro"

Podemos en la misma línea de código agregar comentarios:


edad3=23 #mayor de edad

Problema resuelto
Confeccionar una pantalla de presentación. Definir tres líneas de comentarios.
#Definición de tres títulos.
#Los títulos deben ser de nivel h1.
#Cada uno en una línea distinta.
print '<h1>Primer titulo</h1>'
print '<h1>Segundo titulo</h1>'
print '<h1>Tercer titulo</h1>'

Problema Propuesto
Confeccionar una pantalla de presentación de un sitio. Definir varias líneas de
comentarios indicando el nombre del programa, el programador y la fecha de la última
modificación.
#Programa: Foro Movil
#Programador: Rodriguez Pablo
#Fecha de última modificación: 22/07/2008
print '<h1>Pantalla principal</h1>'

5
t: @charli3vazquez

4. Operadores matemáticos
Python nos suministra los siguientes operadores matemáticos para trabajar con números
enteros y flotantes:

+ suma
- resta
* multiplicación
/ división de flotantes
// división de enteros
% resto de una división
** exponenciación
Hay que tener en cuenta que si dividimos dos enteros con el símbolo / el resultado es un
entero. Debe ser alguno de los dos números flotantes para que el resultado sea float.

Problema resuelto
Definir dos variables enteras e inicializarlas con los valores 7 y 2.5 respectivamente.
Luego imprimir la suma, resta, multiplicación, resto de la división y el resultado de la
división como entero y como flotante.
valor1=7
valor2=2.5
suma=valor1+valor2
print 'La suma es:'
print suma
print '<br>'
resta=valor1-valor2
print 'La resta es:'
print resta
print '<br>'
multiplicacion=valor1*valor2
print 'El producto es:'
print multiplicacion
print '<br>'
div1=valor1/valor2
print 'La división con resultado entero:'
print div1
print '<br>'
div2=valor1//valor2
print 'La división con resultado float:'
print div2
print '<br>'
resto=valor1%valor2
print 'El resto:'
print resto
print '<br>'

Problema Propuesto
Mostrar el resultado de elevar el número 2 al cuadrado y al cubo.
cuadrado=2**2
print 'Cuadrado:'
print cuadrado
print '<br>'
cubo=2**3
print 'Cubo:'
print cubo

6
t: @charli3vazquez

5. Estructura condicional if
Igual que otros lenguajes cuando tenemos que tomar una decisión en nuestro programa
debemos utilizar la estructura if.
Algo muy importante en el lenguaje Python que no lo tienen otros lenguajes es que la
indentación es obligatoria e indica las intrucciones contenidas en un if.

Analicemos el siguiente ejemplo:


nombre='juan'
edad=15
if edad<18:
print nombre
print ' es menor de edad.<br>'
print 'Fin del programa'

La estructura if contiene una condición, si dicha condición se verifica verdadera luego se


ejecutan todas las instrucciones que se encuentran indentadas (es decir corridas a
derecha) Es muy común utilizar una indentación de 4 espacios.
En nuestro ejemplo la instrucción:
print 'Fin del programa'

se encuentra fuera de la estructura if.


Si la condición se verifica verdadera luego se ejecutan las intrucciones:
print nombre
print ' es menor de edad.<br>'

Es obligatorio luego de la condición del if disponer los dos puntos


if edad<18:

También similar a otros lenguajes la estructura condicional if tiene una segunda parte que
es el else, dicha sección se ejecuta si la condición se verifica falsa.
nombre='juan'
edad=15
print nombre
if edad<18:
print ' es menor de edad.<br>'
else:
print ' es mayor de edad.<br>'
print 'Fin del programa'

Nuevamente tener en cuenta que las instrucciones que se indiquen por el else deben
estar corridas a derecha (indentadas).
La palabra clave else requiere también los dos puntos
else:

Problema resuelto
Generar un número aleatorio comprendido entre 1 y 20. Luego mostrar si el valor
generado tiene uno o dos dígitos.
Para generar un valor aleatorio hay una librería que debemos importar (veremos más
adelante el concepto de módulos)
import random

Luego podemos llamar la función randint de dicho módulo, esta función requiere dos
valores enteros y nos devuelve otro valor entero comprendido entre ellos (lo selecciona de
forma aleatoria, es decir al azar)
x=random.randint(1,20)

7
t: @charli3vazquez

Ejemplo:
import random

x=random.randint(1,20)
print x
print '<br>'
if x<10:
print 'El valor generado tiene un digito'
else:
print 'El valor generado tiene dos digitos'

Problema Propuesto
Inicializar una variable con un valor entero comprendido entre 1 y 100. Generar luego un
valor aleatorio también comprendido entre 1 y 100. Mostrar un mensaje si el valor
generado coincide con el valor de la variable (en Python para ver si dos variable
almacenan el mismo valor se utiliza el operador relacional == )
import random

elegido=25
x=random.randint(1,100)
print x
print '<br>'
if elegido==x:
print 'El valor generado coincide con la variable'
else:
print 'El valor generado no coincide con la variable'

8
t: @charli3vazquez

6. Operadores relacionales
En Python contamos con los siguientes operadores relacionales:
== Igualdad

!= Desigualdad
< menor
<= menor o igual
> mayor
>=mayor o igual
Cuando disponemos una condición en una estructura condicional debemos utilizar alguno
de estos seis operadores relacionales.
Toda condición debe tener un operando o valor, luego un operador relacional y finalmente
otro operando o valor.

Todas estas condiciones son válidas:


if edad==18:
if edad<=18:
if edad!=50:
if edad>=18:
if valor1<valor2:
if valor1>valor2:

Problema resuelto
Inicialzar dos variables con valores aleatorios comprendidos entre 1 y 10.
Mostrar un mensaje si los dos valores generados son iguales.
Mostrar un mensaje si el primer valor es menor a 5.
Mostrar otro mensaje si el segundo valor es mayor a 5.

import random

valor1=random.randint(1,10)
valor2=random.randint(1,10)
print 'Primer valor:'
print valor1
print '<br>'
print 'Segundo valor:'
print valor2
print '<br>'
if valor1==valor2:
print 'Los dos valores son iguales.<br>'
if valor1<5:
print 'El primer valor es inferior a 5.<br>'
if valor2>5:
print 'El segundo valor es superior a 5.<br>'

9
t: @charli3vazquez

7. Estructura condicional if anidada


En ocaciones cuando hay más de dos caminos posibles es necesario implementar
estructuras condicionales anidadas, es decir por la rama del verdadero o falso (else:)
disponemos otras estructuras condicionales.
Debemos tener cuidado con la indentación del código para evitar errores.
Veamos un ejemplo que requiere utilizar estructuras condicionales anidadas.
Generaremos tres números aleatorios y luego imprimiremos el mayor de los tres:

import random

x1=random.randint(1,100)
x2=random.randint(1,100)
x3=random.randint(1,100)
print x1
print '-'
print x2
print '-'
print x3
print '<br>'
print 'El mayor es:'
if x1>x2:
if x1>x3:
print x1
else:
print x3
else:
if x2>x3:
print x2
else:
print x3

Como podemos observar por el bloque del verdadero del primer if tenemos otra estructura
condicional (debemos indentar cada estructura condicional):
if x1>x2:
if x1>x3:
print x1
else:
print x3

Problema resuelto
Generar un valor aleatorio entre 1 y 1000. Luego imprimir un mensaje indicando cuantos
dígitos tiene.
import random

x1=random.randint(1,1000)
print x1
print '<br>'
if x1<10:
print 'Tiene 1 dígito'
else:
if x1<100:
print 'Tiene 2 dígitos'
else:
if x1<1000:
print 'Tiene 3 dígitos'
else:
print 'Tiene 4 dígitos'

10
t: @charli3vazquez

Problema Propuesto
Generar un valor aleatorio entre -10 y 10. Mostrar un mensaje si el valor generado es
negativo, nulo o positivo.
Para generar un valor aleatorio en ese rango debemos plantear la siguiente expresión:
x=-10+random.randint(0,20)

Ejemplo:
import random

x=-10+random.randint(0,20)
print x
print '<br>'
if x<0:
print 'Numero negativo'
else:
if x==0:
print 'Numero nulo'
else:
print 'Numero positivo'

11
t: @charli3vazquez

8. Operadores lógicos
En Python contamos con los siguientes operadores lógicos:
and (y)
or (o)
not (no)
Los operadores lógicos nos permiten agrupar condiciones simples en una estructura
condicional, esto nos facilita la implementación de algoritmos más compactos y
comprensibles.
Cuando unimos dos condiciones simples con el operador lógico 'and' ambas condiciones
deben verificarse como verdaderas para que la condición compuesta se verifique
verdadera. Por ejempo si tenemos que mostrar un mensaje si la edad de una persona
está comprendida entre 12 y 18 años podemos plantearla con una única estructura
condicional:
if edad>=12 and edad<=18:
print 'Edad comprendida entre 12 y 18'

Estamos diciendo si la variable 'edad' tiene un valor mayor o igual a 12 y además la


variable edad tiene un valor menor o igual a 18 luego ejecutar la rama del verdadero.
La condición anterior nos evita tener que implementar dos estructuras condicionales:
if edad>=12:
if edad<=18:
print 'Edad comprendida entre 12 y 18'

El operador lógico 'or' hace que con que alguna de las condiciones sea verdadera luego
ejecute el bloque del verdadero.
if x1<5 or x2<5:

Se ejecuta la rama del verdadero si al menos una de las dos variables es menor a 5.
El operador not invierte el valor de una condición:
if not x1>x2:

Si x1 no es mayor a x2 luego ejecuta la rama del verdadero de la estructura condicional.


Podemos plantear condiciones con más de dos condiciones simples:
if x1<0 or x2<0 or x3<0:

Si x1 o x2 o x3 tienen un valor inferior a cero luego se ejecuta la rama del verdadero del if.

12
t: @charli3vazquez

Problema resuelto
Generar tres números aleatorios y luego imprimir el mayor de los tres. Emplear
condiciones compuestas donde sea posible.

import random

x1=random.randint(1,100)
x2=random.randint(1,100)
x3=random.randint(1,100)
print x1
print '-'
print x2
print '-'
print x3
print '<br>'
print 'El mayor es:'
if x1>x2 and x1>x3:
print x1
else:
if x2>x3:
print x2
else:
print x3

Problema Propuesto
Generar 3 números aleatorios entre 1 y 100. Mostrar un mensaje si todos son superiores
a 10.
import random

x1=random.randint(1,100)
x2=random.randint(1,100)
x3=random.randint(1,100)
print x1
print '-'
print x2
print '-'
print x3
print ' '
if x1>10 and x2>10 and x3>10:
print 'Todos los valores son superiores a 10'

13
t: @charli3vazquez

9. Estructura condicional if-elif


Esta estructura condicional es una forma más elegante de disponer estructuras
condicionales anidadas.
Veamos como lo hacemos con estructuras condicionales anidadas y luego utilizando la
sintaxis if/elif:
(problema: generar un número aleatorio entre 1 y 1000, luego imprimir la cantidad de
dígitos del número generado)
import random

x=random.randint(1,1000)
print x
print '<br>'
if x<10:
print 'Tiene 1 dígito'
else:
if x<100:
print 'Tiene 2 dígitos'
else:
if x<1000:
print 'Tiene 3 dígitos'
else:
print 'Tiene 4 dígitos'
Luego con la estructura condicional if/elif:
import random

x=random.randint(1,1000)
print x
print '<br>'
if x<10:
print 'Tiene 1 dígito'
elif x<100:
print 'Tiene 2 dígitos'
elif x<1000:
print 'Tiene 3 dígitos'
else:
print 'Tiene 4 dígitos'

Problema resuelto
Almacenar en una variable entera la nota de un alumno, luego mostrar un mensaje si está
promocionado (nota>=9), regular (nota>=4) o reprobado (nota<4)
nota=7
print 'Nota:'
print nota
print '<br>'
if nota>=9:
print 'Promocionado'
elif nota>=4:
print 'Regular'
else:
print 'Reprobado'

14
t: @charli3vazquez

Problema Propuesto
Generar un valor aleatorio comprendido entre 1 y 5. Luego mostrar en castellano el valor
generado.
import random

x=random.randint(1,5)
if x==1:
print 'uno'
elif x==2:
print 'dos'
elif x==3:
print 'tres'
elif x==4:
print 'cuatro'
elif x==5:
print 'cinco'

15
t: @charli3vazquez

10. Estructura repetitiva while


Las estructuras repetitivas nos permiten ejecutar un bloque de instrucciones varias veces,
dependiendo de una condición.
La estructura while repite el bloque de instrucciones mientras la condición se verifique
verdadera.
Si queremos mostrar los números del 1 al 100 con estructuras secuenciales el proceso es
largo y engorroso, utilizando una estructura repetitiva el algoritmo es muy compacto:
print 'Números del 1 al 100:'
x=1
while x<=100:
print x
print '-'
x=x+1
print 'Fin'

Es importante recordar y remarcar que las instrucciones que se ejecutan en la estructura


repetitiva while son todas las que se encuentran indentadas a derecha (cuatro espacios
más a la derecha de la instrucción while)
La variable x se inicializa previo a la estructura while con el valor 1. La primera vez que se
ejecuta la condición del while se verifica verdadera, ya que 1 es menor o igual a 100.
Dentro de la estructura repetitiva mostramos el contenido de la variable x, luego
imprimimos un guión y finalmente incrementamos la variable x con el valor actual más
uno.
La impresión de la cadena 'Fin' se ejecuta una vez finalizada la estructura repetitiva while.

Problema resuelto
Mostrar la tabla de multiplicar del 2 (del 2 al 20) empleando una estructura repetitiva while.
x=2
print 'Tabla del 2:'
while x<=20:
print x
print '<br>'
x=x+2

Problema Propuesto
Generar un valor aleatorio entre 100 y 200. Luego mostrar los números comprendidos
entre 1 y el valor generado.
import random
x=random.randint(100,200)
print 'Número final:'
print x
print '<br>'
cont=1
while cont<=x:
print cont
print '-'
cont=cont+1

16
t: @charli3vazquez

11. Funciones
La estructura fundamental de programación de los lenguajes estructurados son las
funciones. Una función es un conjunto de instrucciones que se la invoca mediante un
nombre y que luego de ejecutado el algoritmo puede retornar un valor.
Un programa estructurado no es más que un conjunto de funciones que en conjunto
resuelven un problema complejo.
Veamos la sintaxis en Python para definir y llamar a una función:
def presentacion():
print 'Primer mensaje.<br>'
print 'Segundo mensaje.<br>'

def fin():
print 'Ultimo mensaje.'

presentacion()
fin()

Para definir una función utilizamos la palabra clave 'def' seguida por el nombre de la
función, luego si no tiene parámetros como este caso debe ir paréntesis abiertos y
cerrados y dos puntos. Seguidamente las instrucciones de la función se indentan a
derecha.
def presentacion():
print 'Primer mensaje.<br>'
print 'Segundo mensaje.<br>'

Una función se ejecuta cuando se la llama por su nombre:


presentacion()

Es importante notar que primero debemos declarar la función y luego llamarla.


Una función puede tener parámetros de entrada, por ejemplo si queremos una función
que reciba dos enteros y luego nos imprima el mayor, el algoritmo es el siguiente:
def imprimirmayor(valor1,valor2):
if valor1>valor2:
print valor1
else:
print valor2

imprimirmayor(4,5)
print '<br>'
x1=20
x2=30
imprimirmayor(x1,x2)

Los parámetros de la función se indican en la cabecera de la función separados por


comas.
Cuando llamamos a la función estamos obligados a enviarle datos a los dos parámetros.
Podemos enviarle directamente los valores:
imprimirmayor(4,5)
O podemos enviarle variables previamente inicializadas:
x1=20
x2=30
imprimirmayor(x1,x2)

Como podemos notar con este ejemplo una función puede ser llamada más de una vez
(en este caso la llamamos dos veces)

17
t: @charli3vazquez

Problema resuelto
Confeccionar una función que reciba un entero y luego imprima la tabla de multiplicar de
dicho valor (por ejemplo si recibe un 3 luego debe mostrar del 3 hasta el 30 de 3 en 3)
def mostrartabla(num):
inicio=num
fin=num*10
while inicio<=fin:
print inicio
print '-'
inicio=inicio+num
mostrartabla(3)

Problema Propuesto
Desarrollar una función que reciba dos enteros y nos muestre todos los valores
comprendidos entre ellos (el segundo parámetro siempre debe ser mayor al primero)
def rangovalores(v1,v2):
inicio=v1
while inicio<=v2:
print inicio
print '<br>'
inicio=inicio+1
rangovalores(2,20)

18
t: @charli3vazquez

12. Funciones con retorno de dato


Hay muchas situaciones donde queremos que la función luego de ejecutarse retorne un
valor y se almacene en una variable desde donde la llamamos.
Por ejemplo si necesitamos una función que reciba tres enteros y nos retorne el mayor la
sintaxis será la siguiente:
def retornarmayor(x1,x2,x3):
if x1<x2 and x1<x3:
return x1
elif x2<x3:
return x2
else:
return x3
may=retornarmayor(4,5,3)
print may

Como podemos observar la instrucción return indica el valor devuelto por la función.
El valor retornado se almacena en una variable:
may=retornarmayor(4,5,3)

Podemos inclusive mostrar directamente el valor retornado por la función:


print retornarmayor(40,5,3)

O utilizarlo en una condición:


if retornarmayor(40,5,3)<20:
print 'El valor devuelto es mayor a 20'

Problema resuelto
Confeccionar una función que reciba tres enteros y nos retorne la suma de dichos valores.
def sumar(x1,x2,x3):
su=x1+x2+x3
return su
total=sumar(10,30,42)
print total

Problema Propuesto
Desarrollar una función que reciba tres enteros y nos retorne la suma de los dos más
grandes.
def sumarmayores(x1,x2,x3):
if x1>x2 and x1>x3:
if x2>x3:
return x1+x2
else:
return x1+x3
elif x2>x3:
if x3>x1:
return x2+x3
else:
return x2+x1
else:
if x2>x1:
return x3+x2
else:
return x3+x1
print sumarmayores(100,200,30)

19
t: @charli3vazquez

13. Estructura de datos tipo tupla


Hasta ahora hemos empleado variables que permiten almacenar un único valor. En
Python existen varias estructuras de datos que permiten almacenar un conjunto de datos.
La primera que presentaremos es la tupla:
Una tupla es una colección de datos no necesariamente del mismo tipo que se los accede
por medio de subíndices.
Definición de una tupla:
tupla1=('juan',18,1.92)

Hemos definido una tupla de tres elementos. El primer elemento es de tipo cadena de
caracteres, el segundo un entero y finalmente un valor flotante.
Cada elemento de una tupla se los separa por una coma.
Para acceder a los elementos lo hacemos por medio del nombre de la tupla y un
subíndice numérico:
print tupla1[0]

Los elementos de la tupla comienzan a numerarse a partir de cero y utilizamos los


corchetes para hacer referencia al subíndice.
Si queremos en algún momento saber la cantidad de elementos de una tupla debemos
llamar la función len:
print len(tupla1) #imprime un 3

con dicha función podemos disponer una estructura repetitiva para imprimir todas las
componentes de la tupla con el siguiente algoritmo:
tupla1=('juan',18,1.92)
indice=0
while indice<len(tupla1):
print tupla1[indice]
indice=indice+1

Veremos en el próximo concepto que hay una estructura repetitiva que nos facilita recorrer
los elementos de una tupla.
Una vez definida la tupla no se pueden modificar los valores almacenados.
La función print puede recibir como parámetro una tupla y se encarga de mostrarla en
forma completa:
print tupla1

De todos modos cuando tenemos que acceder a algún elemento de la tupla debemos
hacerlo mediante un subíndice entre corchetes.
La característica fundamental de una tupla es que una vez creada no podemos modificar
sus elementos, ni tampoco agregar o eliminar.

Problema resuelto
Definir dos tuplas que almacenen en una los nombres de los meses y en otra la cantidad
de días que tiene cada mes del año. Luego mostrar el contenido almacenado en las
mismas.
meses=('enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre')
cantidaddias=(31,28,31,30,31,30,31,31,30,31,30,31)
indice=0
while indice<len(meses):
print meses[indice]
print ':'
print cantidaddias[indice]
print '<br>'
indice=indice+1

20
t: @charli3vazquez

Problema Propuesto
Definir una tupla que almacene 5 enteros. Implementar un algoritmo que imprima la suma
de todos los elementos.
tupla1=(6,33,56,3,45)
suma=0
indice=0
while indice<len(tupla1):
suma=suma+tupla1[indice]
indice=indice+1
print 'El contenido de la tupla es:'
print tupla1
print '<br>'
print 'La suma es:'
print suma

21
t: @charli3vazquez

14. Estructura repetitiva for in para recorrer una tupla


Para recorrer una tupla es muy común utilizar la estructura repetitiva for.
Veamos con un ejemplo la sintaxis de esta estructura repetitiva:
tupla1=('juan',23,1.92)
for elemento in tupla1:
print elemento
print '<br>'

Como podemos ver la instrucción for requiere una variable (en este ejemplo llamada
elemento), luego la palabra clave in y por último la tupla. El bloque del for se ejecuta
tantas veces como elementos tenga la tupla, y en cada vuelta del for la variable elemento
almacena un valor de la tupla1.
Esta estructura repetitiva se adapta mucho mejor que el while para recorrer este tipo de
estructuras de datos.
Problema resuelto
Definir una tupla con 5 valores enteros. Imprimir los valores mayores o iguales a 18.
tupla1=(45,34,2,56,1)
for elemento in tupla1:
if elemento>=18:
print elemento
print '<br>'

Problema Propuesto
Definir una tupla con 10 edades de personas. Imprimir la cantidad de personas con
edades superiores a 20.
tupla1=(45,78,3,56,3,45,34,2,56,1)
cantidad=0
for elemento in tupla1:
if elemento>20:
cantidad=cantidad+1
print 'Cantidad de personas con edades superiores a 20:'
print cantidad

22
t: @charli3vazquez

15. Porciones de tuplas


El lenguaje Python nos permite rescatar una "porción" de una tupla, es decir un trozo de la
misma.
Si tenemos la siguiente tupla:
tupla1=(1,7,20,40,51,3)
tupla2=tupla1[0:4]
print tupla2

El resultado es una tupla con cuatro valores:


(1,7,20,40)

Es decir indicamos como subíndice un rango de valores, en este caso desde la posición 0
hasta la posición 4 sin incluirla.
Podemos no indicar alguno de los dos rangos:
tupla1=(1,7,20,40,51,3)
tupla2=tupla1[3:]
print tupla2

El resultado es una tupla con tres valores, desde la posición 3 hasta el final de la tupla:
(40, 51, 3)

En caso de no indicar el primer rango:


tupla1=(1,7,20,40,51,3)
tupla2=tupla1[:2]
print tupla2

El resultado es una tupla con dos valores, desde el principio de la tupla hasta la posición 2
sin incluirla:
(1, 7)

Problema resuelto
Definir una tupla con los nombres de los meses. Generar dos tuplas que almacenen los
primeros 6 meses la primera y los siguientes 6 meses la segunda.
meses=('enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre')
tupla1=meses[:6]
tupla2=meses[6:]
print tupla1
print '<br>'
print tupla2

Problema Propuesto
Almacenar en una tupla 5 nombres. Luego generar un valor aleatorio entre 2 y 4. Copiar a
una tupla el nombre de la posición indicada por el valor aleatorio y los nombres que se
encuentran en la posición anterior y posterior.
import random

nombre=('juan','ana','luis','carlos','roman')
ale=random.randint(1,3)
tresnombres=nombre[ale-1:ale+2]
print tresnombres

23
t: @charli3vazquez

16. Estructura de datos tipo cadena de caracteres (string)


Una cadena de caracteres permite almacenar un conjunto de caracteres. Su
funcionamiento es similar a una tupla.
Para inicializar un string utilizamos el operador de asignación.
nombre='Juan Pablo'

Podemos utilizar las comillas simples o dobles para su inicialización:


mail='[email protected]'
o
mail="[email protected]"

Para conocer el largo de un string podemos utilizar la función len:


print len(mail)

Para acceder a un caracter particular del string lo hacemos indicando un subíndice entre
corchetes:
print mail[0] #Imprimimos el primer caracter

El lenguaje Python nos permite rescatar una "porción" de un string con la misma sintaxis
que trabajamos las tuplas:
nombre='Jose Maria'
print nombre[1:4] #ose
print nombre[:4] #Jose
print nombre[5:] #Maria

Los string son inmutables, es decir que no podemos modificar su contenido luego de ser
inicializados:
titulo='Administracion'
titulo[0]='X' # Esto produce un error

Esto no significa que no podemos utilizar la variable para que referencie a otro string:
nombre='Jose'
print nombre
nombre='Ana'
print nombre

Para concatenar string Python permite utilizar el operador +.


Si tenemos tres string y queremos almacenar sus contenidos en un cuarto string podemos
codificarlo de la siguiente manera:
cadena1='uno'
cadena2='dos'
cadena3='tres'
total=cadena1+cadena2+cadena3
print total #unodostres

También Python define el operador * para los string. El resultado de multiplicar un string
por un entero es otro string que repite el string original tantas veces como indica el
número.
#si queremos un string con 80 caracteres de subrayado, la forma más sencilla es utilizar
la siguiente expresión:
separador='_'*80
print separador

24
t: @charli3vazquez

Los operadores relacionales definidos para los string son:


> Mayor
>= Mayor o igual
< Menor
<= Menor o igual
== Igual
!= Distinto

Si queremos saber si un string es mayor alfabéticamente que otro utilizamos el operador >
nombre1='CARLOS'
nombre2='ANABEL'
if nombre1>nombre2:
print nombre1+' es mayor alfabéticamente que '+nombre2

si queremos saber si dos variables tienes en mismo contenido:


nombre1='CARLOS'
nombre2='CARLOS'
if nombre1==nombre2:
print 'Las dos variables tienen el mismo contenido:'+nombre1

Problema resuelto
Elaborar una función que reciba un string y retorne la cantidad de vocales que tiene.
def cantidadvocales(cadena):
cant=0
for letra in cadena:
if letra=='a':
cant=cant+1
if letra=='e':
cant=cant+1
if letra=='i':
cant=cant+1
if letra=='o':
cant=cant+1
if letra=='u':
cant=cant+1
if letra=='A':
cant=cant+1
if letra=='E':
cant=cant+1
if letra=='I':
cant=cant+1
if letra=='O':
cant=cant+1
if letra=='U':
cant=cant+1
return cant

print 'Cantidad de vocales en la palabra Hola:'


print cantidadvocales('Hola')
print '<br>'
print 'Cantidad de vocales en la palabra Computadora:'
print cantidadvocales('Computadora')

25
t: @charli3vazquez

Problema Propuesto
Elaborar las siguientes funciones:
- Una función que reciba un string y nos retorne el primer caracter.
- Una función que reciba un apellido y un nombre, y nos retorne un único string con el
apellido y nombre concatenados y separados por una coma.
- Una función que reciba dos string y nos retorne el que tiene menos caracteres.
def primercaracter(cadena):
return cadena[0]

def concatenar(apellido,nombre):
return apellido+','+nombre

def menor(cadena1,cadena2):
if len(cadena1)<len(cadena2):
return cadena1
else:
return cadena2

cad='Hola Mundo'
print 'Primer caracter de '+cad+' es '+primercaracter(cad)
print '<br>'
nom='juan'
ape='rodriguez'
print 'Apellido y nombre concatenados:'+concatenar(ape,nom)
cad1='Hola'
cad2='Fin'
print '<br>'
print 'De: '+cad1+' y '+cad2+' tiene menos caracteres '+menor(cad1,cad2)

26
t: @charli3vazquez

17. Estructura de datos tipo lista


Una lista es una colección de datos no necesariamente del mismo tipo que se los accede
por medio de subíndices. La diferencia fundamental de una lista con una tupla es que
podemos modificar la estructura luego de haberla creado.
Hay varias formas de crear una lista, la primera y más sencilla es enumerar sus
elementos entre corchetes y separados por coma:
lista1=['juan','ana','luis']

Para acceder a sus elementos lo hacemos indicando un subíndice subíndice:


print lista1[0]

Como decíamos la diferencia con una tupla (son inmutables) es que podemos modificar la
lista luego de creada:
lista1=[10,15,20]
print lista1
print '<br>'
lista1[0]=700 # modificamos el valor almacenado en la primer componente de la lista.
print lista1

De forma similar a las tuplas y string la función len nos informa de la cantidad de
elementos que contiene la lista:
lista1=[10,15,20]
print len(lista1) # imprime un 3

Es muy común emplear la estructura for in para recorrer y rescatar cada elemento de la
lista, la variable elemento almacena en cada ciclo del for un elemento de la lista1,
comenzando por el primer valor:
lista1=['juan',23,1.92]
for elemento in lista1:
print elemento
print '<br>'

Si queremos saber si un valor se encuentra en una lista existe un operador llamado in:
lista1=[12,45,1,2,5,4,3,55]
if 1 in lista1:
print 'El valor 1 está contenido en la lista '
else:
print 'El valor 1 no está contenido en la lista '
print lista1

Python define los operadores + y * para listas, el primero genera otra lista con la suma de
elementos de la primer y segunda lista. El operador * genera una lista que repite tantas
veces los elementos de la lista como indica el valor entero seguido al operador *.
lista1=[2,4,6,8]
lista2=[10,12,14,16]
listatotal=lista1+lista2
print listatotal

Luego empleando el operador *:


lista1=['juan','carlos']
producto=lista1*3
print producto

El resultado de este algoritmo es:


['juan', 'carlos', 'juan', 'carlos', 'juan', 'carlos']

27
t: @charli3vazquez

También con listas podemos utilizar el concepto de porciones que nos brinda el lenguaje
Python:
lista=[2,4,6,8,10]
print lista[2,4] #[6, 8]
print lista[:3] #[2, 4, 6]
print lista[3:] #[8, 10]

Como vimos podemos modificar el contenido de elementos de la lista asignándole otro


valor:
lista=[2,4,6]
lista[1]=10
print lista #[2, 10, 6]

Podemos borrar elementos de la lista utilizando la función del:


lista=[2,4,6]
del(lista[1])
print lista #[2, 6]

Además podemos utilizar porciones para borrar un conjunto de elementos de la lista:


lista=[2,4,6]
del(lista[1:])
print lista #[2]

También podemos añadir elementos a una lista:


lista=[5,10,11,12]
lista[1:1]=[6,7,8,9]
print lista #[5,6,7,8,9,10,11,12]

Problema resuelto
Definir una lista con edades de personas, luego borrar todos los elementos que sean
menores a 18.
edades=[23,5,67,21,12,4,34]
indice=0
while indice<len(edades):
if edades[indice]<18:
del(edades[indice])
else:
indice=indice+1
print edades

Problema Propuesto
Definir una lista con un conjunto de nombres, imprimir la cantidad de comienzan con la
letra a:
nombres=['ariel','marcos','ana','luis','pedro','andres']
cant=0
for nom in nombres:
if nom[0]=='a':
cant=cant+1
print nombres
print '<br>'
print 'Cantidad de nombres que comienzan con a es:'
print cant

28
t: @charli3vazquez

18. Indices negativos en tuplas, listas y string


Hemos visto que en Python accedemos a los elementos de una lista, tupla y string
mediante un subíndice que comienza a numerarse a partir de cero:
tupla=(2,4,6,8,10)
print tupla[0] # 2
lista=[2,4,6,8,10]
print lista[0] # 2
cadena='hola'
print cadena[0] # h

Si queremos acceder a la última componente podemos hacerlo:


tupla=(2,4,6,8,10)
print tupla[len(tupla)-1] # 10

Pero Pyton tiene integrado en el lenguaje el acceso de los elementos de la secuencia


mediante índices negativos, por ejemplo si queremos acceder a la última componente
luego podemos hacerlo con la siguiente sintaxis:
tupla=(2,4,6,8,10)
print tupla[-1] # 10
lista=[2,4,6,8,10]
print lista[-1] # 10
cadena='hola'
print cadena[-1] # a

Es mucho más cómodo utilizar esta segunda forma para acceder a los elementos de una
lista, tupla o cadena de caracteres.
Si queremos imprimir los elementos de una tupla en forma inversa (es decir desde el
último elemento hasta el primero) podemos hacerlo con el siguiente algoritmo:
tupla=(2,4,6,8,10)
indice=-1
for x in range(0,len(tupla)):
print tupla[indice] # 10 8 6 4 2
indice=indice-1

Problema resuelto
Inicializar una variable con un valor aleatorio comprendido entre 1 y 1000000, verificar si
es capicúa, es decir si se lee igual de izquierda a derecha como de derecha a izquierda.
import random

valor=random.randint(1,1000000)
print valor
print '<br>'
cadena=str(valor)
indice=-1
iguales=0
for x in range(0,len(cadena)/2):
if cadena[x]==cadena[indice]:
iguales=iguales+1
indice=indice-1
if iguales==(len(cadena)/2):
print 'Es capicua'
else:
print 'No es capicua'

29
t: @charli3vazquez

Problema Propuesto
Definir una lista con una serie de elementos. Intercambiar la información del primero con
el último de la lista.
lista=['juan','ana','luis','pedro']
print lista
print '<br>'
aux=lista[0]
lista[0]=lista[-1]
lista[-1]=aux
print lista

30
t: @charli3vazquez

19. Estructura de datos tipo diccionario


Las estructuras de datos vistas hasta ahora (tuplas y listas) utilizan un entero como
subíndice. La estructura de datos tipo diccionario utiliza una clave para acceder a un
valor. El subíndice puede ser un entero, un string etc.
Un diccionario vincula una clave y un valor.
Si queremos almacenar la cantidad de productos que tenemos en stock podemos
implementar un diccionario donde utilizamos como clave el nombre del producto y como
valor la cantidad de productos disponibles.
Podemos definir un diccionario con la siguiente sintaxis:
productos={'manzanas':23,'peras':50,'papas':120}

Luego si queremos acceder a la cantidad de productos en stock utilizamos como


subíndice el nombre del producto:
print productos['manzanas']

La línea anterior produce como resultado el valor 23.


Mediante un diccionario asociamos para toda clave un valor.
Podemos borrar cualquier entrada dentro del diccionario empleando la siguiente sintaxis:
del(productos['manzana'])

Luego si imprimimos el diccionario en forma completa tenemos como resultado que ya no


contiene la entrada 'manzana':
print propductos
{'peras': 50, 'papas': 120}

Podemos modificar el valor asociado a una clave mediante una simple asignación:
productos['papas']=5

Luego si imprimimos el diccionario obtenemos como resultado:


{'peras': 50, 'papas': 5}

Podemos conocer en cualquier momento la cantidad de pares clave-valor que contiene


nuestro diccionario mediante la función len:
print len(productos)

Con nuestro problema tenemos como resultado que nuestro diccionario tiene 2
elementos.

Problema resuelto
Crear un diccionario cuyas claves sean palabras en inglés y su valor almacena la palabra
traducida al castellano.
diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
print diccionario['house']
print '<br>'
print diccionario['red']

Problema Propuesto
Crear un diccionario asociando nombres de paises y cantidades de habitantes. Imprimir
luego el diccionario.
paises={'argentina':40000000,'españa':46000000,'brasil':190000000}
print paises

31
t: @charli3vazquez

20. Formato de cadenas de caracteres (string)


Cuando tenemos que combinar cadenas de caracteres e incorporarle valores
almacenados en otras variables el lenguaje Python nos suministra una técnica para
incrustar valores dentro de la cadena.
Veamos mediante ejemplos cual es la sintaxis para plantear estos formatos de cadenas:
x1=10
x2=5
x3=20
print 'El contenido de la primer variable es %d, de la segunda %d y la tercera %d' % (x1,x2,x3)

Si bien podemos utilizar el operador + para ir concatenando cadenas y variables esta


técnica hace que nuestro programa sea más legible sobre todo cuando tenemos que
sustituir varias variables dentro de una cadena.
Primero indicamos entre comillas la cadena y utilizamos el símbolo % para indicar el lugar
donde se sustituirá el valor, debemos indicar luego del caracter % el tipo de dato (en
nuestro ejemplo un valor decimal (d))
Luego de la cadena debemos indicar una tupla con los valores o variables de donde se
obtendrán los datos. Entre la cadena de formato y la tupla debemos disponer el caracter
% (aquí el caracter porcentaje tiene un objetivo distinto que dentro de la cadena de
formato)
Se especifican distintos caracteres para cada tipo de dato a sustituir:
x=10
g=10.2
cadena='juan'
print 'El valor entero %d el valor real %f y la cadena %s' % (x,g,cadena)

En el ejemplo propuesto vemos que podemos utilizar los caracteres de formato d


(decimal), f (float) y s (string).
Es importante el orden de los valores de la tupla ya que el lenguaje procesa los datos en
forma secuencia, es decir cada vez que debe sustituir un valor en la cadena extrae de la
tupla el siguiente valor.
Cuando damos formato a una variable real (con coma) podemos disponer dos valores
previos al caracter f:
g=20.5498
print 'El valor real es %10.2f' % (g)

El primer valor indica el largo total a reservar y el segundo la cantidad de decimales.


Podemos convertir el valor decimal a tipo octal o hexadecimal:
x=255
print 'Decimal %d en hexadecimal es %x y en octal %o' % (x,x,x)
#Decimal 255 en hexadecimal es ff y en octal 377

No es obligatorio que el formato de cadena se utilice siempre en un print, podemos


almacenar el resultado del formato en otra variable string (que podemos eventualmente
almacenarla en una base de datos por ejemplo).
vx=10
vy=90
resultado='(%d,%d)' % (vx,vy)
print resultado # (10,90)

32
t: @charli3vazquez

También podemos indicar un valor entero en el formato para los tipos de datos enteros y
string:
x1=100
x2=1500
x3=5
print '<pre>'
print '%5d' % (x1)
print '%5d' % (x2)
print '%5d' % (x3)
print '</pre>'
El resultado por pantalla es:
100
1500
5

Es decir reserva en este caso 5 espacios para el entero y hace la alineación a derecha.
Si indicamos un valor negativo los datos se alínean a izquierda:
animales=['perro','elefante','pez']
print '<pre>'
for elemento in animales:
print '%20s' % elemento
for elemento in animales:
print '%-20s' % elemento
print '</pre>'
El resultado de ejecutar el programa es:
perro
elefante
pez
perro
elefante
pez

Problema resuelto
Imprimir todos los números desde el 1 hasta el 255 en decimal, octal y hexadecimal.
print '<pre>'
for num in range(1,256):
print '%3d %3o %3x' % (num,num,num)
print '</pre>'

Problema Propuesto
Almacenar en una lista los nombres de personas y en otra los sueldos que cobran cada
uno. Hacer que para el índice cero de cada componente representen los datos de una
persona y así sucesivamente.
Imprimir un nombre por línea de la pantalla y hacer que los sueldos aparezcan
correctamente alineados las columnas de unidades, decenas, centenas etc.
nombres=['juan','ana','luis']
sueldos=[1500.55,2700.00,910.66]
print '<pre>'
for indice in range(0,len(nombres)):
print '%-20s %10.2f' % (nombres[indice],sueldos[indice])
print '</pre>'

33
t: @charli3vazquez

21. Asignaciones múltiples


Python permite asignaciones múltiples:
x1,x2,x3=1,2,3
print x1 # 1
print x2 # 2
print x3 # 3

Para entenderlo mejor podemos también utilizar esta sintaxis:


x1,x2,x3=(1,2,3)
print x1 # 1
print x2 # 2
print x3 # 3

Es decir lo que estamos haciendo inicializar cada una de las variables de la izquierda con
las componentes homólogas (de la misma posición) de la tupla.
Esta característica es útil si tenemos que recuperar por ejemplo de una lista que contiene
tuplas de dos elementos que representan puntos en el plano (x,y):
puntos=[(10,2),(4,2),(9,3)]
for x,y in puntos:
print 'Coordenada x:%d y:%d' % (x,y)
print '<br>'

Cada vuelta del for se almacena en x e y los valores de la tupla a procesar.


Otra aplicación muy útil es si queremos intercambiar el valor de dos variables la forma
más simple es:
x=10
y=20
print x # 10
print y # 20
x,y = y,x
print x # 20
print y # 10

En una asignación pueden intervenir valores de distinto tipo (enteros, reales, string etc.):
nombre,edad,sueldo=('juan',32,1500.30)
print 'Nombre:%s Edad:%d Sueldo%10.2f' % (nombre,edad,sueldo)
# Nombre:juan Edad:32 Sueldo 1500.30

Podemos con esto hacer que una función retorne más de un dato (por lo menos en
apariencia), esto lo logramos retornando una tupla:
def sumadiferencia(x1,x2):
suma=x1+x2
diferencia=x1-x2
return (suma,diferencia)

su,di=sumadiferencia(10,4)
print su # 14
print di # 6

Como vemos llamamos a una función y le asignamos el valor devuelto a dos variables.
Si queremos inicializar tres variables con el mismo valor la sintaxis que podemos utilizar
es:
x1=x2=x3=10
print x1 # 10
print x2 # 10
print x3 # 10

34
t: @charli3vazquez

Problema resuelto
En una lista se almacenan tuplas con el nombre de una persona y su edad. Mostrar el
nombre de la persona de mayor edad.
personas=[('juan',22),('ana',40),('carlos',15)]

may=-1
for nombre,edad in personas:
if edad>may:
nom=nombre
may=edad
print '%s tiene la edad mayor y es de %d' % (nom,may)

35
t: @charli3vazquez

22. Funciones con parámetros por defecto


Como habíamos visto una función es una estructura de programación que agrupa un
conjunto de instrucciones y resuelve un problema particular. Una función puede tener
parámetros, los mismos almacenan los valores que se le pasan cuando la llamamos.
En algunos casos si queremos que la función sea mas flexible podemos definir
parámetros con valores por defecto. Esto nos permite llamar a la función pudiendo o no
pasar datos a dichos parámetros.
Veamos con un ejemplo este concepto, vamos a desarrollar una función que reciba un
dato a imprimir, con la posibilidad de indicarle el color de fuente y el color de fondo, en
caso de no indicarle dichos valores la función muestra el dato con color negro y fondo
blanco.
def mostrartitulo(dato,colorletra='#000',colorfondo='#fff'):
print '<h1 style="color:'+colorletra+';background-color:'+colorfondo+'">'+dato+'</h1>'

mostrartitulo('Primer titulo')
mostrartitulo('Segundo titulo','#f00')
mostrartitulo('Tercer titulo','#f00','#000')

Como podemos ver para indicar a Python que un parámetro es por defecto debemos
utilizar el operador de asignación en la declaración de la cabecera de la función junto al
valor que tomará dicho parámetro en caso de no pasarlo desde donde la llamamos:
def mostrartitulo(dato,colorletra='#000',colorfondo='#fff'):

Cuando llamamos la función mostrartitulo podemos hacerlo de diferentes maneras:


mostrartitulo('Primer titulo')
mostrartitulo('Segundo titulo','#f00')
mostrartitulo('Tercer titulo','#f00','#000')

La primer llamada es pasando un único dato, es decir solo el título que debe mostrar, en
este caso el segundo y tercer parámetro toman como valor el indicado en el declaración:
colorletra='#000',colorfondo='#fff'

Podemos llamar a la función mostrartitulo pasando el primer parámetro y el segundo, lo


que hace que el tercer parámetro se inicialice con el indicado en la declaración de la
función:
mostrartitulo('Segundo titulo','#f00')

En el ejemplo la tercer llamada a la función se hace pasando tres parámetros:


mostrartitulo('Tercer titulo','#f00','#000')

Como podemos ver los parámetros por defecto nos permiten implementar funciones más
generales, con esto podemos hacer que las funciones sean útiles para mayor cantidad de
situaciones.
Que pasa si queremos llamar la función indicando el primer y último parámetro, esto solo
se puede hacer si al llamar la función indicamos que dato se le pasa a cada parámetro:
def mostrartitulo(dato,colorletra='#000',colorfondo='#fff'):
print '<h1 style="color:'+colorletra+';background-color:'+colorfondo+'">'+dato+'</h1>'
mostrartitulo(dato='Primer titulo',colorfondo='#00f')

Si bien se hace más engorroso la llamada a la función al tener que indicar el nombre de
cada parámetro junto al valor, nos trae como beneficio que sea aún más flexible.

36
t: @charli3vazquez

Problema resuelto
Confeccionar una función que reciba un dato a imprimir, con la posibilidad de indicarle el
color de fuente y el color de fondo, en caso de no indicarle dichos valores la función
muestra el dato con color negro y fondo blanco.
def mostrartitulo(dato,colorletra='#000',colorfondo='#fff'):
print '<h1 style="color:'+colorletra+';background-color:'+colorfondo+'">'+dato+'</h1>'

mostrartitulo('Primer titulo')
mostrartitulo('Segundo titulo','#f00')
mostrartitulo('Tercer titulo','#f00','#000')

Problema Propuesto
Confeccionar una función que reciba entre 2 y 5 enteros. La misma nos debe retornar la suma de dichos valores.
def sumar(v1,v2,v3=0,v4=0,v5=0):
s=v1+v2+v3+v4+v5
return s

print sumar(5,6)
print '<br>'
print sumar(1,2,3)
print '<br>'
x=sumar(1,2,3,4,5)
print x

37
t: @charli3vazquez

23. Funciones con una cantidad variable de parámetros


Otra posibilidad en la declaración de una función en Python es la definición de una
cantidad variable de parámetros.
Para definir una cantidad variante de parámetros debemos antecederle el caracter
asterísco (*) al último parámetro de la función.
Supongamos que necesitemos implementar una función que le enviemos una serie de
enteros y nos retorne la suma de todos ellos (como mínimo le enviamos 2 y no hay un
máximo de valores):
def sumar(x1,x2,*xn):
s=x1+x2
for valor in xn:
s=s+valor
return s

print sumar(1,2)
print '<br>'
print sumar(1,2,3,4)
print '<br>'
print sumar(1,2,3,4,5,6,7,8,9,10)

Lo que en realidad el lenguaje Python hace es una tupla con todos los valores de los
parámetros a partir del tercero.
Luego nuestro algoritmo debe recorrer la tupla para procesar los elementos propiamente
dichos, en nuestro caso con un for in y los sumamos junto al primer y segundo parámetro.
Luego cuando hacemos la llamada a la función:
print sumar(1,2)

Si pasamos solo dos parámetros la tupla se inicializa vacía, por lo que el for in no ejecuta
el bloque contenido.
Si llamamos la función con 10 parámetros:
print sumar(1,2,3,4,5,6,7,8,9,10)

Luego la tupla se crea con 7 elementos.

Problema resuelto
Implementar una función que le enviemos una serie de enteros y nos retorne la suma de
todos ellos (como mínimo le enviamos 2 y no hay un máximo de valores):
def sumar(x1,x2,*xn):
s=x1+x2
for valor in xn:
s=s+valor
return s
print sumar(1,2)
print '<br>'
print sumar(1,2,3,4)
print '<br>'
print sumar(1,2,3,4,5,6,7,8,9,10)

38
t: @charli3vazquez

Problema Propuesto
Confeccionar una función que le envíe una serie de edades y me retorne la cantidad que
son mayores a 18 (como mínimo se envía un entero a la función)
def cantidadmayor18(ed1,*edades):
cant=0
if ed1>18:
cant=cant+1
for e in edades:
if e>18:
cant=cant+1
return cant
print 'Cantidad de personas mayores a 18:'
cant=cantidadmayor18(4,56,14,67,32,21)
print cant

39
t: @charli3vazquez

24. Implementación de módulos


Cuando uno codifica un programa en Python lo almacena en un archivo con extensión
*.py
Una vez instalado el Python en forma local podemos llamar un programa desde la línea
de comando del sistema operativo.
Si tenemos un programa mínimo llamado: programa1.py
def holamundo():
print('Hola Mundo')
holamundo();

Luego desde la carpeta donde hemos instalado el Python debemos ejecutarlo con la
siguiente sintaxis:
c:\Python25>python c:\pruebaspython\programa1.py

Luego de esto veremos en pantalla el mensaje 'Hola Mundo'


Este archivo en Python se lo llama módulo.
Un programa pequeño puede estar formado por un único módulo, pero programas de
mayor tamaño deben dividirse en distintos módulos para facilitar su mantenimiento. Cada
módulo normalmente almacena un conjunto de funciones relacionadas.
La sintaxis para llamar a una función que se encuentra en otro módulo es la siguiente:
modulo1.py
def funcion1():
print 'Función 1'
modulo2.py
import modulo1

def funcion2():
modulo1.funcion1()
print 'Función 2'

funcion2()

Luego desde la línea de comandos ejecutamos el modulo2.py:


c:\Python25>python c:\pruebaspython\modulo2.py

Y como resultado tenemos en pantalla


Función 1
Función 2

Veremos más adelante que Python nos provee de una gran biblioteca de módulos.
Recordemos que ya hemos estado utilizando la función randint que se encuentra en el
módulo random:
import random

x=random.randint(1,1000)
print x

40
t: @charli3vazquez

25. Funciones de uso común (range - type - str - dir)


Como hemos visto en el punto anterior Python agrupa las funciones en módulos que
serán importados en el caso que nuestro programa los necesite. Pero hay un pequeño
grupo de funciones que Python las importa de forma automática, esto quiere decir que
podemos hacer uso sin tener que hacer un import.
Funciones incorporadas en Python
• range([inicio],fin,[paso])

• La función range devuelve una lista de valores enteros, comienza con el valor
pasado al parámetro [inicio], en caso de omitir este parámetro comienza en cero y
finaliza con el valor indicado en el parámetro 'fin' sin incluirlo. En caso de indicar el
parámetro [paso] la lista de valores crece según dicho número, sino se incrementa
de a uno.
• lista1=range(5,10)
print lista1 # [5, 6, 7, 8, 9]
lista2=range(10)
print lista2 # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lista3=range(-5,5)
print lista3 # [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
lista4=range(1,10,3)
print lista4 # [1, 4, 7]

• Es muy común utilizar esta función para generar un contador con la estructura for
in, por ejemplo si queremos mostrar los números del 1 al 10:
• for x in range(1,11):
print x
print '-'
• str(variable)

• Convierte el contenido del parámetro a cadena y lo retorna. Funciona para


cualquier tipo de dato como puede ser un entero, real, tupla, lista etc.
• Muy útil cuando tenemos que generar un string a partir de un conjunto de variables
heterogeneas.
• x=10
y=2.5
fin=False
edades=(40,50)
print str(x) + str(y) + str(fin) + str(edades)

• En el ejemplo concatenamos el contenido de cuatro variables de distinto tipo, para


ello debemos llevarlas a todas a tipo string.
• type(variable)

• Retorna el tipo de una variable.


• x=10
print type(x) # <type 'int'>
y=2.5
print type(y) # <type 'float'>
fin=False
print type(fin) # <type 'bool'>
edades=(40,50)
print type(edades) # <type 'tuple'>

• dir(variable)
• Si pasamos como parámetro a la función dir un objeto luego nos devuelve todos los
métodos que tiene definidos la clase de dicho objeto (veremos más adelante en
profundidad cada uno de los métodos de la clase lista y diccionario):

41
t: @charli3vazquez
• lista1=[2,4,6]
print dir(lista1) #['__add__', '__class__', '__contains__', '__delattr__',
# '__delitem__', '__delslice__', '__doc__', '__eq__', '__ge__',
# '__getattribute__', '__getitem__', '__getslice__', '__gt__',
# '__hash__', '__iadd__', '__imul__', '__init__', '__iter__',
# '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
# '__reduce__', '__reduce_ex__', '__repr__', '__reversed__',
# '__rmul__', '__setattr__', '__setitem__', '__setslice__',
# '__str__', 'append', 'count', 'extend', 'index', 'insert',
# 'pop', 'remove', 'reverse', 'sort']

dic1={'juan':44,'ana':3}
print dir(dic1) # ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__',
# '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__gt__',
# '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__',
# '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__',
# '__str__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems',
# 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

• Si le pasamos como parámetro el nombre de un módulo la función dir nos retorna


todas las funciones definidas entre otros datos (recordemos que hemos estado
utilizando la función randint para generar un valor aleatorio y como podemos ver se
encuentra listado al llamar a la función dir):
• import random

print dir(random) # ['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST',


# 'SystemRandom', 'TWOPI', 'WichmannHill', '_BuiltinMethodType', '_MethodType',
# '__all__', '__builtins__', '__doc__', '__file__', '__name__', '_acos', '_ceil',
# '_cos', '_e', '_exp', '_hexlify', '_inst', '_log', '_pi', '_random', '_sin',
# '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate',
# 'choice', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate',
# 'jumpahead', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint',
# 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'uniform',
# 'vonmisesvariate', 'weibullvariate']

Problema resuelto
Mediante la función dir obtener el contenido del módulo zlib.
import zlib
print dir(zlib)

Problema Propuesto
Mostrar la tabla de multiplicar 5 (desde el 5 al 50), emplear la función range
for valor in range(5,55,5):
print str(valor)+'-'

42
t: @charli3vazquez

26. Función de uso común (help)


La función help tiene por objetivo ayudar al programador dando información de
documentación definidas en módulos, funciones, clases etc.
Veamos que nos devuelve la función help si le pasamos como parámetro la función randint:
import random

help(random.randint) # Help on method randint in module random: randint(self, a, b)


# method of random.Random instance Return random integer in
# range [a, b], including both end points.

Podemos observar que nos informa el módulo donde se almacena, sus parámetros y el
objetivo de la misma.
Nosotros podemos crear cadenas de documentación para nuestras funciones con la
siguiente sintaxis:
def sumar(v1,v2):
"""El objetivo de esta funcion es realizar la
suma de los dos valores que recibe como
parametro y retornarlo."""
su=v1+v2
return su

help(sumar) # Help on function sumar in module __main__: sumar(v1, v2)


# El objetivo de esta funcion es realizar la suma de los
# dos valores que recibe como parametro y retornarlo.

El string que definamos inmediatamente después de la cabecera se tomará como cadena


de documentación de la función. Como en este caso nuestra cadena de documentación
ocupa varias líneas en Python podemos encerrarla entre triples comillas y no deberemos
indicar el caracter de continuación de línea (Si la cadena de documentación es una sola
línea podemos emplear una sola comillas al principio y al final)
Si utilizamos una sola comillas debemos indicar al final de cada línea que continúa:
def sumar(v1,v2):
"El objetivo de esta funcion es realizar la \
suma de los dos valores que recibe como \
parametro y retornarlo."
su=v1+v2
return su

Podemos crear cadenas de documentación para definir objetivos del mismo.


Si tenemos un módulo mínimo llamado: modulo1.py, podemos definir las siguientes
cadenas de documentación "cadena de documentacion del modulo"
def holamundo():
"cadena de documentacion de funcion"
print('Hola Mundo')

Problema resuelto
Llamar la función help para mostrar las cadenas de documentación del módulo random,
de la función randint, de una variable de tipo entera y de una variable de tipo lista.
import random

help(random)
print '<hr>'
help(random.randint)
print '<hr>'
x=4
help(x)
print '<hr>'
lista1=[1,2,3];
help(lista1)

43
t: @charli3vazquez

27. Conceptos de programación orientada a objetos


Habíamos dicho que Python nos permite combinar las metodologías de programación
Lineal, Estructurada y Orientada a Objetos. A partir de este concepto mostraremos en
forma sencilla la metodología de Programación Orientada a Objetos.
Se irán introduciendo conceptos de objeto, clase, atributo, método etc. y de todos estos
temas se irán planteando problemas resueltos.
Prácticamente todos los lenguajes desarrollados en los últimos 15 años implementan la
posibilidad de trabajar con POO (Programación Orientada a Objetos)
El lenguaje Python tiene la característica de permitir programar con las siguientes
metodologías:
• Programación Lineal: Es cuando desarrollamos todo el código sin emplear
funciones.
• Programación Estructurada: Es cuando planteamos funciones que agrupan
actividades a desarrollar y luego dentro del programa llamamos a dichas funciones
que pueden estar dentro del mismo archivo o en una librería separada.
• Programación Orientada a Objetos: Es cuando planteamos clases y definimos
objetos de las mismas (Este es el objetivo de los próximos conceptos, aprender la
metodología de programación orientada a objetos y la sintaxis particular de Python
para la POO)
Conceptos básicos de Objetos
Un objeto es una entidad independiente con sus propios datos y programación. Las
ventanas, menúes, carpetas de archivos pueden ser identificados como objetos; el motor
de un auto también es considerado un objeto, en este caso, sus datos (atributos)
describen sus características físicas y su programación (métodos) describen el
funcionamiento interno y su interrelación con otras partes del automóvil (también objetos).
El concepto renovador de la tecnología Orientación a Objetos es la suma de funciones a
elementos de datos, a esta unión se le llama encapsulamiento. Por ejemplo, un objeto
página contiene las dimensiones físicas de la página (ancho, alto), el color, el estilo del
borde, etc, llamados atributos. Encapsulados con estos datos se encuentran los métodos
para modificar el tamaño de la página, cambiar el color, mostrar texto, etc. La
responsabilidad de un objeto pagina consiste en realizar las acciones apropiadas y
mantener actualizados sus datos internos. Cuando otra parte del programa (otros objetos)
necesitan que la pagina realice alguna de estas tareas (por ejemplo, cambiar de color) le
envía un mensaje. A estos objetos que envían mensajes no les interesa la manera en que
el objeto página lleva a cabo sus tareas ni las estructuras de datos que maneja, por ello,
están ocultos. Entonces, un objeto contiene información pública, lo que necesitan los
otros objetos para interactuar con él e información privada, interna, lo que necesita el
objeto para operar y que es irrelevante para los otros objetos de la aplicación.
28. Declaración de una clase y creación de objetos
La programación orientada a objetos se basa en la programación de clases; a diferencia
de la programación estructurada, que está centrada en las funciones.
Una clase es un molde del que luego se pueden crear múltiples objetos, con similares
características.
Un poco más abajo se define una clase Persona y luego se crean dos objetos de dicha
clase.
Una clase es una plantilla (molde), que define atributos (lo que conocemos como
variables) y métodos (lo que conocemos como funciones).
La clase define los atributos y métodos comunes a los objetos de ese tipo, pero luego,
cada objeto tendrá sus propios valores y compartirán las mismas funciones.

44
t: @charli3vazquez

Debemos crear una clase antes de poder crear objetos (instancias) de esa clase. Al crear
un objeto de una clase, se dice que se crea una instancia de la clase o un objeto
propiamente dicho.
Confeccionaremos nuestra primer clase para conocer la sintaxis en el lenguaje Python,
luego definiremos dos objetos de dicha clase.
Implementaremos una clase llamada Persona que tendrá como atributo (variable) su
nombre y dos métodos (funciones), uno de dichos métodos inicializará el atributo nombre
y el siguiente método mostrará en la página el contenido del mismo.
class Persona:
def inicializar(self,nom):
self.nombre=nom

def imprimir(self):
print 'Nombre:'
print self.nombre
print '<br>'

persona1=Persona()
persona1.inicializar('Juan')
persona1.imprimir()

persona2=Persona()
persona2.inicializar('Ana')
persona2.imprimir()

Siempre conviene buscar un nombre de clase lo más próximo a lo que representa. La


palabra clave para declarar la clase es class, seguidamente el nombre de la clase y luego
dos puntos.
Los métodos de una clase se definen utilizando la misma sintaxis que para la definición
de funciones.
Como veremos todo método tiene como primer parámetro el identificador self que tiene la
referencia del objeto que llamó al método.
Luego dentro del método diferenciamos los atributos del objeto antecediendo el
identificador self:
self.nombre=nom

Con la asignación previa almacenamos en el atributo nombre el parámetro nom, los


atributos siguen existiendo cuando finaliza la ejecución del método. Por ello cuando se
ejecuta el método imprimir podemos mostrar el nombre que cargamos en el primer
método.
Decíamos que una clase es un molde que nos permite definir objetos. Ahora veamos cual
es la sintaxis para la definición de objetos de la clase Persona:
persona1=Persona()
persona1.inicializar('Juan')
persona1.imprimir()

Definimos un objeto llamado persona1 y lo creamos asignándole el nombre de la clase.


Luego para llamar a los métodos debemos anteceder el nombre del objeto el operador . y
por último el nombre del método.
En el caso que tenga parámetros se los enviamos (salvo el primer parámetro (self) que el
mismo Python se encarga de enviar la referencia del objeto que se creó):
persona1.inicializar('Juan')

45
t: @charli3vazquez

También podemos definir tantos objetos de la clase Persona como sean necesarios para
nuestro algoritmo:
persona2=Persona()
persona2.inicializar('Ana')
persona2.imprimir()
Esto nos da una idea que si en una página WEB tenemos 2 menúes, seguramente
definiremos una clase Menu y luego crearemos dos objetos de dicha clase.
Esto es una de las ventajas fundamentales de la Programación Orientada a Objetos
(POO), es decir reutilización de código (gracias a que está encapsulada en clases) es
muy sencilla.

Problema resuelto
Confeccionar una clase llamada Persona. Definir un atributo donde se almacene su
nombre. Luego definir dos métodos, uno que cargue el nombre y otro que lo imprima.
class Persona:
def inicializar(self,nom):
self.nombre=nom

def imprimir(self):
print 'Nombre:'
print self.nombre
print '<br>'

persona1=Persona()
persona1.inicializar('Juan')
persona1.imprimir()

persona2=Persona()
persona2.inicializar('Ana')
persona2.imprimir()

Problema Propuesto
Confeccionar una clase Empleado, definir como atributos su nombre y sueldo.
Definir un método inicializar que lleguen como dato el nombre y sueldo. Plantear un
segundo método que imprima el nombre, sueldo y un mensaje si debe o no pagar
impuestos (si el sueldo supera a 3000 paga impuestos)
class Empleado:
def inicializar(self,nom,suel):
self.nombre=nom
self.sueldo=suel

def pagaimpuestos(self):
print 'Nombre:'
print self.nombre
print '<br>'
print 'Sueldo:'
print self.sueldo
print '<br>'
if self.sueldo>300:
print 'Debe pagar impuestos'

emp1=Empleado()
emp1.inicializar('Juan',3500)
emp1.pagaimpuestos()

46
t: @charli3vazquez

29. Atributos de una clase


Ahora trataremos de concentrarnos en los atributos de una clase. Los atributos son las
características, cualidades, propiedades distintivas de cada clase. Contienen información
sobre el objeto. Determinan la apariencia, estado y demás particularidades de la clase.
Varios objetos de una misma clase tendrán los mismos atributos pero con valores
diferentes.
Cuando creamos un objeto de una clase determinada, los atributos declarados por la
clase son localizadas en memoria y pueden ser modificados mediante los métodos.
Plantearemos un nuevo problema para analizar detenidamente la definición, sintaxis y
acceso a los atributos.
Problema: Implementar una clase que muestre una lista de hipervínculos en forma
horizontal (básicamente un menú de opciones)
Lo primero que debemos pensar es que valores almacenará la clase, en este caso
debemos cargar una lista de direcciones web y los títulos de los enlaces. Podemos definir
dos listas paralelas que almacenen las direcciones y los títulos respectivamente.
Definiremos dos métodos: cargaropcion y mostrar.
class Menu:
enlaces=[]
titulos=[]
def cargaropcion(self,en,tit):
self.enlaces.append(en)
self.titulos.append(tit)

def mostrar(self):
for indice in range(0,len(self.enlaces)):
print '<a href="'+self.enlaces[indice]+'">'+self.titulos[indice]+'</a>'

menu1=Menu()
menu1.cargaropcion('http://www.google.com.ar','Google')
menu1.cargaropcion('http://www.yahoo.com.ar','Yahoo')
menu1.cargaropcion('http://www.live.com.ar','Msn')
menu1.mostrar()

En este caso los atributos son de tipo listas y estamos obligados a definirlos dentro de la
clase y previo a la declaración de los métodos:
enlaces=[]
titulos=[]

Estamos definiendo dos listas vacías.

El método cargaropcion recibe el enlace y el título y los almacena al final de cada lista
empleando el método append de la lista (tengamos en cuenta que Python administra las
listas como objetos)
self.enlaces.append(en)
self.titulos.append(tit)

El método que imprime todos los enlaces utiliza un for para recorrer las listas y acceder a
cada elemento de las listas y mostrarlos dentro de la página:
for indice in range(0,len(self.enlaces)):
print '<a href="'+self.enlaces[indice]+'">'+self.titulos[indice]+'</a>'

47
t: @charli3vazquez

Luego creamos un objeto de la clase Menu y llamamos tantas veces al método


cargaropcion como opciones tenga nuestro menú:
menu1=Menu()
menu1.cargaropcion('http://www.google.com.ar','Google')
menu1.cargaropcion('http://www.yahoo.com.ar','Yahoo')
menu1.cargaropcion('http://www.live.com.ar','Msn')
Finalmente llamamos al método mostrar que imprime cada hipervínculo en la página:
menu1.mostrar()
Problema resuelto
Implementar una clase que muestre una lista de hipervínculos en forma horizontal (básicamente un menú de opciones)
class Menu:
enlaces=[]
titulos=[]
def cargaropcion(self,en,tit):
self.enlaces.append(en)
self.titulos.append(tit)

def mostrar(self):
for indice in range(0,len(self.enlaces)):
print '<a href="'+self.enlaces[indice]+'">'+self.titulos[indice]+'</a>'

menu1=Menu()
menu1.cargaropcion('http://www.google.com.ar','Google')
menu1.cargaropcion('http://www.yahoo.com.ar','Yahoo')
menu1.cargaropcion('http://www.live.com.ar','Msn')
menu1.mostrar()

Problema Propuesto
Confeccionar una clase Menu. Permitir añadir la cantidad de opciones que necesitemos.
Mostrar el menú en forma horizontal o vertical (según que método llamemos)
class Menu:
enlaces=[]
titulos=[]
def cargaropcion(self,en,tit):
self.enlaces.append(en)
self.titulos.append(tit)

def mostrarhorizontal(self):
for indice in range(0,len(self.enlaces)):
print '<a href="'+self.enlaces[indice]+'">'+self.titulos[indice]+'</a>'

def mostrarvertical(self):
for indice in range(0,len(self.enlaces)):
print '<a href="'+self.enlaces[indice]+'">'+self.titulos[indice]+'</a><br>'

menu1=Menu()
menu1.cargaropcion('http://www.google.com.ar','Google')
menu1.cargaropcion('http://www.yahoo.com.ar','Yahoo')
menu1.cargaropcion('http://www.live.com.ar','Msn')
menu1.mostrarvertical()

48
t: @charli3vazquez

30. Metodos de una clase


Los métodos son como las funciones en los lenguajes estructurados, pero están definidos
dentro de una clase y operan sobre los atributos de dicha clase.
Los métodos también son llamados las responsabilidades de la clase. Para encontrar las
responsabilidades de una clase hay que preguntarse qué puede hacer la clase.
El objetivo de un método es ejecutar las actividades que tiene encomendada la clase a la
cual pertenece.
Los atributos de un objeto se modifican mediante llamadas a sus métodos.
Confeccionaremos un nuevo problema para concentrarnos en la definición y llamada a
métodos.
Problema:Confeccionar una clase CabeceraPagina que permita mostrar un título, indicarle
si queremos que aparezca centrado, a derecha o izquierda.
Definiremos dos atributos, uno donde almacenar el título y otro donde almacenar la
ubicación.
Ahora pensemos que métodos o responsabilidades debe tener esta clase para poder
mostrar la cabecera de la página. Seguramente deberá tener un método que pueda
inicializar los atributos y otro método que muestre la cabecera dentro de la página.
Veamos el código de la clase CabeceraPagina
class CabeceraPagina:
def inicializar(self,tit,ubi):
self.titulo=tit
self.ubicacion=ubi

def graficar(self):
print '<div style="font-size:40px;text-align:'+self.ubicacion+'">'
print self.titulo
print '</div>'

cabecera=CabeceraPagina()
cabecera.inicializar('El blog del programador','center')
cabecera.graficar()

La clase CabeceraPagina tiene dos atributos donde almacenamos el texto que debe
mostrar y la ubicación del mismo ('center', 'left' o 'right'), nos valemos de CSS para ubicar
el texto en la página.
No es obligatorio en Python definir previo a los métodos todos los atributos. Como vemos
se definen e inicializan al llamar al método inicializar.
Ahora analicemos lo que más nos importa en el concepto que estamos concentrados
(métodos de una clase):
def inicializar(self,tit,ubi):
self.titulo=tit
self.ubicacion=ubi

Un método tiene un nombre, conviene utilizar verbos para la definición de métodos


(mostrar, inicializar, graficar etc.) y sustantivos para la definición de atributos (color,
enlace, titulo etc.)
Un método debe tener como primer parámetro el identificador self, el mismo nos permite
acceder a los atributos de la clase, además puede tener otros parámetros que inicializan
atributos del objeto:
self.titulo=tit
self.ubicacion=ubi

49
t: @charli3vazquez

Luego para llamar a los métodos debemos crear un objeto de dicha clase:
cabecera=CabeceraPagina()
cabecera.inicializar('El blog del programador','center')
cabecera.graficar()

Es importante notar que siempre que llamamos a un método le antecedemos el nombre


del objeto. El orden de llamada a los métodos es importante, no va a funcionar si primero
llamamos a graficar y luego llamamos al método inicializar.

Problema resuelto
Confeccionar una clase CabeceraPagina que permita mostrar un título, indicarle si
queremos que aparezca centrado, a derecha o izquierda.
class CabeceraPagina:
def inicializar(self,tit,ubi):
self.titulo=tit
self.ubicacion=ubi

def graficar(self):
print '<div style="font-size:40px;text-align:'+self.ubicacion+'">'
print self.titulo
print '</div>'

cabecera=CabeceraPagina()
cabecera.inicializar('El blog del programador','center')
cabecera.graficar()

Problema Propuesto
Confeccionar una clase CabeceraPagina que permita mostrar un título, indicarle si
queremos que aparezca centrado, a derecha o izquierda, además permitir definir el color
de fondo y de la fuente.
class CabeceraPagina:
def inicializar(self,tit,ubi,colfondo,colfuente):
self.titulo=tit
self.ubicacion=ubi
self.colorfondo=colfondo
self.colorfuente=colfuente

def graficar(self):
print '<div style="font-size:40px;text-align:'+self.ubicacion+';background-color:'+self.colorfondo
+';color:'+self.colorfuente+'">'
print self.titulo
print '</div>'

cabecera=CabeceraPagina()
cabecera.inicializar('El blog del programador','center','#FF1A00','#CDEB8B')
cabecera.graficar()

50
t: @charli3vazquez

31. Metodo constructor de una clase


El constructor es un método especial de una clase. El objetivo fundamental del constructor
es inicializar los atributos del objeto que creamos.
Básicamente el constructor remplaza al método inicializar que habíamos hecho en el
concepto anterior.
Las ventajas de implementar un constructor en lugar del método inicializar son:
1. El constructor es el primer método que se ejecuta cuando se crea un objeto.
2. El constructor se llama automáticamente. Es decir es imposible de olvidarse de
llamarlo ya que se llamará automáticamente.
3. Quien utiliza POO (Programación Orientada a Objetos) conoce el objetivo de este
método.
Otras características de los constructores son:
• El constructor se ejecuta inmediatamente luego de crear un objeto y no puede ser
llamado nuevamente.
• Un constructor no puede retornar dato.
• Un constructor puede recibir parámetros que se utilizan normalmente para
inicializar atributos.
• El constructor es un método opcional, de todos modos es muy común definirlo.
Veamos la sintaxis del constructor:
def __init__([parámetros]):
[algoritmo]
Debemos definir un método llamado __init__ (es decir utilizamos dos caracteres de
subrayado, la palabra init y seguidamente otros dos caracteres de subrayado).
Confeccionaremos el mismo problema del concepto anterior para ver el cambio que
debemos hacer de ahora en más.
Problema:Confeccionar una clase CabeceraPagina que permita mostrar un título, indicarle
si queremos que aparezca centrado, a derecha o izquierda.
class CabeceraPagina:
def __init__(self,tit,ubi):
self.titulo=tit
self.ubicacion=ubi

def graficar(self):
print '<div style="font-size:40px;text-align:'+self.ubicacion+'">'
print self.titulo
print '</div>'

cabecera=CabeceraPagina('El blog del programador','center')


cabecera.graficar()
Ahora podemos ver como cambió la sintaxis para la definición del constructor:
def __init__(self,tit,ubi):
self.titulo=tit
self.ubicacion=ubi

Veamos como se modifica la llamada al constructor cuando se crea un objeto:


cabecera=CabeceraPagina('El blog del programador','center')
cabecera.graficar()

Es decir el constructor se llama en la misma línea donde creamos el objeto, por eso
disponemos después del nombre de la clase los parámetros:
cabecera=CabeceraPagina('El blog del programador','center')

51
t: @charli3vazquez

Generalmente todo aquello que es de vital importancia para el funcionamiento inicial del
objeto se lo pasamos mediante el constructor.

Problema resuelto
Confeccionar una clase CabeceraPagina que permita mostrar un título, indicarle si
queremos que aparezca centrada, a derecha o izquierda. Utilizar un constructor para
inicializar los dos atributos.
class CabeceraPagina:
def __init__(self,tit,ubi):
self.titulo=tit
self.ubicacion=ubi

def graficar(self):
print '<div style="font-size:40px;text-align:'+self.ubicacion+'">'
print self.titulo
print '</div>'

cabecera=CabeceraPagina('El blog del programador','center')


cabecera.graficar()

Problema Propuesto
Confeccionar una clase CabeceraPagina que permita mostrar un título, indicarle si
queremos que aparezca centrado, a derecha o izquierda, además permitir definir el color
de fondo y de la fuente. Pasar los valores que cargaran los atributos mediante un
constructor.
class CabeceraPagina:
def __init__(self,tit,ubi,colfondo,colfuente):
self.titulo=tit
self.ubicacion=ubi
self.colorfondo=colfondo
self.colorfuente=colfuente

def graficar(self):
print '<div style="font-size:40px;text-align:'+self.ubicacion+';background-color:'+self.colorfondo
+';color:'+self.colorfuente+'">'
print self.titulo
print '</div>'

cabecera=CabeceraPagina('El blog del programador','center','#FF1A00','#CDEB8B')


cabecera.graficar()

52
t: @charli3vazquez

32. Llamada de métodos dentro de la clase


Hasta ahora todos los problemas planteados hemos llamado a los métodos desde donde
definimos un objeto de dicha clase, por ejemplo:
cabecera=CabeceraPagina('El blog del programador','center')
cabecera.graficar()

Utilizamos la sintaxis:
[nombre del objeto].[nombre del método]

Es decir antecedemos al nombre del método el nombre del objeto y el operador punto
Ahora bien que pasa si queremos llamar dentro de la clase a otro método que pertenece a
la misma clase, la sintaxis es la siguiente:
self.[nombre del método]

Es importante tener en cuenta que esto solo se puede hacer cuando estamos dentro de la
misma clase.
Confeccionaremos un problema que haga llamadas entre métodos de la misma clase.
Problema:Confeccionar una clase Tabla que permita indicarle en el constructor la cantidad
de filas y columnas. Definir otra responsabilidad que podamos cargar un dato en una
determinada fila y columna. Finalmente debe mostrar los datos en una tabla HTML.
class Tabla:
mat=[]
cantfilas=0
cantcolumnas=0

def __init__(self,fi,co):
self.cantfilas=fi
self.cantcolumnas=co
for f in range(0,fi):
self.mat.append([])
for c in range(0,co):
self.mat[f].append('')

def cargar(self,fi,col,valor):
self.mat[fi][col]=valor

def iniciotabla(self):
print '<table border="1">'

def iniciofila(self):
print '<tr>'

def mostrar(self,fi,co):
print '<td>'
print self.mat[fi][co]
print '</td>'

def finfila(self):
print '</tr>'

def fintabla(self):
print '</table>'

def graficar(self):
self.iniciotabla()
for f in range(0,self.cantfilas):
self.iniciofila()
for c in range(0,self.cantcolumnas):
self.mostrar(f,c)
self.finfila()
self.fintabla()

53
t: @charli3vazquez

tabla1=Tabla(3,4)
tabla1.cargar(0,0,1)
tabla1.cargar(0,1,2)
tabla1.cargar(0,2,3)
tabla1.cargar(0,3,4)
tabla1.cargar(1,0,5)
tabla1.cargar(1,1,6)
tabla1.cargar(1,2,7)
tabla1.cargar(1,3,8)
tabla1.cargar(2,0,9)
tabla1.cargar(2,1,10)
tabla1.cargar(2,2,11)
tabla1.cargar(2,3,12)
tabla1.graficar()

Vamos por parte, primero veamos los tres atributos definidos,el primero se trata de una
lista donde almacenaremos todos los valores que contendrá la tabla HTML y otros dos
atributos que indican la dimensión de la tabla HTML (cantidad de filas y columnas):
mat=[]
cantfilas=0
cantcolumnas=0

El constructor recibe como parámetros la cantidad de filas y columnas que tendrá la tabla,
además creamos la lista con tantas filas como indica el parámetro fi e insertamos una lista
en cada componente (es decir que cada componente de la lista es una lista que
representa los elementos de la fila respectiva) Dentro de un for interno agregamos string
vacíos a cada elemento de la lista interna:
self.cantfilas=fi
self.cantcolumnas=co
for f in range(0,fi):
self.mat.append([])
for c in range(0,co):
self.mat[f].append('')

Otro método de vital importancia es el de cargar datos. Llegan como parámetro la fila,
columna y dato a almacenar:
def cargar(self,fi,col,valor):
self.mat[fi][col]=valor

Otro método muy importante es el graficar:


def graficar(self):
self.iniciotabla()
for f in range(0,self.cantfilas):
self.iniciofila()
for c in range(0,self.cantcolumnas):
self.mostrar(f,c)
self.finfila()
self.fintabla()

El método graficar debe hacer las salidas de datos dentro de una tabla HTML. Para
simplificar el algoritmo definimos otros cinco métodos que tienen por objetivo hacer la
generación del código HTML propiamente dicho. Así tenemos el método iniciotabla que
hace la salida de la marca table e inicialización del atributo border:
def iniciotabla(self):
print '<table border="1">'

54
t: @charli3vazquez

De forma similar los otros métodos son:


def iniciofila(self):
print '<tr>'

def mostrar(self,fi,co):
print '<td>'
print self.mat[fi][co]
print '</td>'

def finfila(self):
print '</tr>'

def fintabla(self):
print '</table>'

Si bien podíamos hacer todo esto en el método graficar y no hacer estos cinco métodos,
la simplicidad del código aumenta a medida que subdividimos los algoritmos. Esto es de
fundamental importancia con algoritmos más complejos./p>
Lo que nos importa ahora ver es como llamamos a métodos que pertenecen a la misma
clase:
def graficar(self):
self.iniciotabla()
for f in range(0,self.cantfilas):
self.iniciofila()
for c in range(0,self.cantcolumnas):
self.mostrar(f,c)
self.finfila()
self.fintabla()

Es decir le antecedemos la palabra self al nombre del método a llamar. De forma similar a
como accedemos a los atributos de la clase.
Por último debemos definir un objeto de la clase Tabla y llamar a los métodos respectivos:

tabla1=Tabla(3,4)
tabla1.cargar(0,0,1)
tabla1.cargar(0,1,2)
tabla1.cargar(0,2,3)
tabla1.cargar(0,3,4)
tabla1.cargar(1,0,5)
tabla1.cargar(1,1,6)
tabla1.cargar(1,2,7)
tabla1.cargar(1,3,8)
tabla1.cargar(2,0,9)
tabla1.cargar(2,1,10)
tabla1.cargar(2,2,11)
tabla1.cargar(2,3,12)
tabla1.graficar()

Es importante notar que donde definimos un objeto de la clase Tabla no llamamos a los
métodos iniciotabla(), iniciofila(), etc.

55
t: @charli3vazquez

Problema resuelto
Confeccionar una clase Tabla que permita indicarle en el constructor la cantidad de filas y
columnas. Definir otra responsabilidad que podamos cargar un dato en una determinada
fila y columna. Finalmente debe mostrar los datos en una tabla HTML.
class Tabla:
mat=[]
cantfilas=0
cantcolumnas=0

def __init__(self,fi,co):
self.cantfilas=fi
self.cantcolumnas=co
for f in range(0,fi):
self.mat.append([])
for c in range(0,co):
self.mat[f].append('')

def cargar(self,fi,col,valor):
self.mat[fi][col]=valor

def iniciotabla(self):
print '<table border="1">'

def iniciofila(self):
print '<tr>'

def mostrar(self,fi,co):
print '<td>'
print self.mat[fi][co]
print '</td>'

def finfila(self):
print '</tr>'

def fintabla(self):
print '</table>'

def graficar(self):
self.iniciotabla()
for f in range(0,self.cantfilas):
self.iniciofila()
for c in range(0,self.cantcolumnas):
self.mostrar(f,c)
self.finfila()
self.fintabla()

tabla1=Tabla(3,4)
tabla1.cargar(0,0,1)
tabla1.cargar(0,1,2)
tabla1.cargar(0,2,3)
tabla1.cargar(0,3,4)
tabla1.cargar(1,0,5)
tabla1.cargar(1,1,6)
tabla1.cargar(1,2,7)
tabla1.cargar(1,3,8)
tabla1.cargar(2,0,9)
tabla1.cargar(2,1,10)
tabla1.cargar(2,2,11)
tabla1.cargar(2,3,12)
tabla1.graficar()

56
t: @charli3vazquez

Problema Propuesto
Confeccionar una clase Tabla que permita indicarle en el constructor la cantidad de filas y
columnas. Definir otra responsabilidad que podamos cargar un dato en una determinada
fila y columna además de definir su color de fuente. Finalmente debe mostrar los datos en
una tabla HTML.
class Tabla:
mat=[]
color=[]
cantfilas=0
cantcolumnas=0

def __init__(self,fi,co):
self.cantfilas=fi
self.cantcolumnas=co
for f in range(0,fi):
self.mat.append([])
self.color.append([])
for c in range(0,co):
self.mat[f].append('')
self.color[f].append('')

def cargar(self,fi,col,valor,colorletra):
self.mat[fi][col]=valor
self.color[fi][col]=colorletra

def iniciotabla(self):
print '<table border="1">'

def iniciofila(self):
print '<tr>'
def mostrar(self,fi,co):
print '<td style="color:'+self.color[fi][co]+'">'
print self.mat[fi][co]
print '</td>'

def finfila(self):
print '</tr>'

def fintabla(self):
print '</table>'

def graficar(self):
self.iniciotabla()
for f in range(0,self.cantfilas):
self.iniciofila()
for c in range(0,self.cantcolumnas):
self.mostrar(f,c)
self.finfila()
self.fintabla()

tabla1=Tabla(3,4)
tabla1.cargar(0,0,1,'#ff0000')
tabla1.cargar(0,1,2,'#ff0000')
tabla1.cargar(0,2,3,'#ff0000')
tabla1.cargar(0,3,4,'#ff0000')
tabla1.cargar(1,0,5,'#00ff00')
tabla1.cargar(1,1,6,'#00ff00')
tabla1.cargar(1,2,7,'#00ff00')
tabla1.cargar(1,3,8,'#00ff00')
tabla1.cargar(2,0,9,'#0000ff')
tabla1.cargar(2,1,10,'#0000ff')
tabla1.cargar(2,2,11,'#0000ff')
tabla1.cargar(2,3,12,'#0000ff')
tabla1.graficar()

57
t: @charli3vazquez

33. Herencia
Otra característica que tiene que tener un lenguaje para considerarse orientado a objetos
es la HERENCIA.
La herencia significa que se pueden crear nuevas clases partiendo de clases existentes,
que tendrá todas los atributos y los métodos de su 'superclase' o 'clase padre' y además
se le podrán añadir otros atributos y métodos propios.
En Python, a diferencia de otros lenguajes orientados a objetos (Java, C#), una clase
puede derivar de varias clases, es decir, Python permite la herencia múltiple.
Superclase o clase padre
Clase de la que desciende o deriva una clase. Las clases hijas (descendientes) heredan
(incorporan) automáticamente los atributos y métodos de la la clase padre.
Subclase
Clase desciendiente de otra. Hereda automáticamente los atributos y métodos de su
superclase. Es una especialización de otra clase. Admiten la definición de nuevos
atributos y métodos para aumentar la especialización de la clase.
Veamos algunos ejemplos teóricos de herencia:
1) Imaginemos la clase Vehículo. Qué clases podrían derivar de ella?
Vehiculo

Colectivo Moto Auto

FordK Renault 9
Siempre hacia abajo en la jerarquía hay una especialización (las subclases añaden
nuevos atributos y métodos)

2) Imaginemos la clase Software. Qué clases podrían derivar de ella?


Software

DeAplicacion DeBase

ProcesadorTexto PlanillaDeCalculo SistemaOperativo

Word WordPerfect Excel Lotus123 Linux Windows

Si vemos que dos clase responden a la pregunta ClaseA "..es un.." ClaseB es posible que
haya una relación de herencia.
Por ejemplo:
Auto "es un" Vehiculo
Circulo "es una" Figura
Mouse "es un" DispositivoEntrada
Suma "es una" Operacion
Ahora plantearemos el primer problema utilizando herencia en Python. Supongamos que
necesitamos implementar dos clases que llamaremos Suma y Resta. Cada clase tiene
como atributo valor1, valor2 y resultado. Los métodos a definir son cargar1 (que inicializa
el atributo valor1), carga2 (que inicializa el atributo valor2), operar (que en el caso de la
clase "Suma" suma los dos atributos y en el caso de la clase "Resta" hace la diferencia
entre valor1 y valor2, y otro método mostrarresultado.
Si analizamos ambas clases encontramos que muchos atributos y métodos son idénticos.
En estos casos es bueno definir una clase padre que agrupe dichos atributos y
responsabilidades comunes.

58
t: @charli3vazquez

La relación de herencia que podemos disponer para este problema es:


Operacion

Suma Resta
Solamente el método operar es distinto para las clases Suma y Resta (esto hace que no
lo podamos disponer en la clase Operacion), luego los métodos cargar1, cargar2 y
mostrarresultado son idénticos a las dos clases, esto hace que podamos disponerlos en la
clase Operacion. Lo mismo los atributos valor1, valor2 y resultado se definirán en la clase
padre Operacion.

En Pyton la codificación de estas tres clases es la siguiente:


class Operacion:
def cargar1(self,v1):
self.valor1=v1
def cargar2(self,v2):
self.valor2=v2
def imprimir(self):
print self.resultado
print '<br>'

class Suma(Operacion):
def operar(self):
self.resultado=self.valor1+self.valor2

class Resta(Operacion):
def operar(self):
self.resultado=self.valor1-self.valor2

s=Suma()
s.cargar1(10)
s.cargar2(20)
s.operar()
print 'La suma es:'
s.imprimir()
r=Resta()
r.cargar1(10)
r.cargar2(2)
r.operar()
print 'La resta es:'
r.imprimir()
Veamos como es la sintaxis para indicar que una clase hereda de otra:
class Suma(Operacion):

Indicamos entre paréntesis el nombre de la clase padre (con esto estamos indicando que
todos los métodos y atributos de la clase Operación son también métodos de la clase
Suma.
Luego la característica que añade la clase Suma es el siguiente método:
def operar(self):
self.resultado=self.valor1+self.valor2

El método operar puede acceder a los atributos heredados.


Ahora podemos decir que la clase Suma tiene cuatro métodos (tres heredados y uno
propio) y 3 atributos, Si creamos un objeto de la clase Suma tenemos:
s=Suma()
s.cargar1(10)
s.cargar2(20)
s.operar()
print 'La suma es:'
s.imprimir()

59
t: @charli3vazquez

Podemos llamar tanto al método propio de la clase Suma "operar()" como a los métodos
heredados. Quien utilice la clase Suma solo debe conocer que métodos tiene
(independientemente que pertenezcan a la clase Suma o a una clase superior)
La lógica es similar para declarar la clase Resta:
class Resta(Operacion):
def operar(self):
self.resultado=self.valor1-self.valor2
y la definición de un objeto de dicha clase:
r=Resta()
r.cargar1(10)
r.cargar2(2)
r.operar()
print 'La resta es:'
r.imprimir()

La clase Operación agrupa en este caso un conjunto de atributos y métodos comunes a


un conjunto de subclases (Suma, Resta). No tiene sentido definir objetos de la clase
Operacion.
El planteo de jerarquías de clases es una tarea compleja que requiere un perfecto
entendimiento de todas las clases que intervienen en un problema, cuales son sus
atributos y responsabilidades.

Problema resuelto
Declarar una clase Operacion que defina los metodos para cargar dos valores y muestre
el resultado. Luego heredar de esta clase para definir los conceptos de suma y resta.
class Operacion:
def cargar1(self,v1):
self.valor1=v1
def cargar2(self,v2):
self.valor2=v2
def imprimir(self):
print self.resultado
print '<br>'

class Suma(Operacion):
def operar(self):
self.resultado=self.valor1+self.valor2

class Resta(Operacion):
def operar(self):
self.resultado=self.valor1-self.valor2

s=Suma()
s.cargar1(10)
s.cargar2(20)
s.operar()
print 'La suma es:'
s.imprimir()
r=Resta()
r.cargar1(10)
r.cargar2(2)
r.operar()
print 'La resta es:'
r.imprimir()

60
t: @charli3vazquez

34. Método especial __str__


Podemos hacer que se ejecute un método definido por nosotros cuando pasamos un
objeto a la función print o cuando llamamos a la función str.
Que sucede cuando llamamos a la función print y le pasamos como parámetro un objeto?
class Persona:
def __init__(self,nom,ape):
self.nombre=nom
self.apellido=ape

per=Persona('Jose','Rodriguez')
print per
Nos muestra algo parecido a esto:
<__main__.Persona instance at 0xf9e0a60ec5872050>

Python nos permite redefinir el método que se debe ejecutar. Esto se hace definiendo en
la clase el método especial __str__
En el ejemplo anterior si queremos que se muestre el nombre y apellido separados por
coma cuando llamemos a la función print el código que debemos implementar es el
siguiente:
class Persona:
def __init__(self,nom,ape):
self.nombre=nom
self.apellido=ape
def __str__(self):
cadena=self.nombre+','+self.apellido
return cadena

per=Persona('Jose','Rodriguez')
print per

Como vemos debemos implementar el método __str__ y retornar un string, este luego
será el que imprime la función print:
def __str__(self):
cadena=self.nombre+','+self.apellido
return cadena

Esta característica definida en Python nos permite crear programas muy legibles y
flexibles.
El método __str__ también se ejecuta si llamamos a la función str y pasamos como
parámetro un objeto que tiene definido dicho método:
class Persona:
def __init__(self,nom,ape):
self.nombre=nom
self.apellido=ape
def __str__(self):
cadena=self.nombre+','+self.apellido
return cadena

per1=Persona('Jose','Rodriguez')
per2=Persona('Ana','Martinez')
print str(per1)+'-'+str(per2) # Jose,Rodriguez-Ana,Martinez

61
t: @charli3vazquez

Problema resuelto
Crear una clase URL que permita inicializar la dirección que apunta y el texto que debe
mostrar. Definir el método __str__ que genere un string con el elemento HTML de
hipervínculo.
class URL:
def __init__(self,dir,men):
self.direccion=dir
self.mensaje=men
def __str__(self):
cadena='<a href="%s">%s</a>' % (self.direccion,self.mensaje)
return cadena

url1=URL('http://www.google.com.ar','Google')
url2=URL('http://www.yahoo.com.ar','Yahoo')
url3=URL('http://www.live.com','Live')
print url1
print url2
print url3

62
t: @charli3vazquez

35. Redefinición de los operadores matemáticos con


objetos
Python nos permite redefinir los operadores matemáticos cuando planteamos una clase.
Los métodos especiales que debemos implementar son los siguientes:
Para el operador +:
__add__(self,objeto2)
Para el operador -:
__sub__(self,objeto2)
Para el operador *:
__mul__(self,objeto2)
Para el operador /:
__div__(self,objeto2)

Veamos con un ejemplo la sintaxis para redefinir el operador +. Crearemos una clase
Cliente de un banco y redefiniremos el operador + para que nos retorne la suma de los
depósitos de los dos clientes que estamos sumando.
class Cliente:
def __init__(self,nom,mon):
self.nombre=nom
self.monto=mon
def __add__(self,objeto2):
s=self.monto+objeto2.monto
return s

cli1=Cliente('Ana',1200)
cli2=Cliente('Luis',1500)
print 'El total depositado es '
print cli1+cli2

Es muy importante tener en cuenta que debemos redefinir un operador matemático


siempre y cuando haga nuestro programa más legible.
Debemos redefinir los operadores +,-,*,/ etc. solo para las clases que con solo leer su
nombre el programador intuya que operación implementaría dicho operador.
Problema resuelto
Crear una clase Cliente de un banco y redefinir el operador + para que nos retorne la
suma de los depósitos de los dos clientes que estamos sumando.

class Cliente:
def __init__(self,nom,mon):
self.nombre=nom
self.monto=mon
def __add__(self,objeto2):
s=self.monto+objeto2.monto
return s

cli1=Cliente('Ana',1200)
cli2=Cliente('Luis',1500)
print 'El total depositado es '
print cli1+cli2

63
t: @charli3vazquez

36. Redefinición de los operadores relacionales con objetos


Python también nos permite redefinir los operadores relacionales cuando planteamos una
clase.
Los métodos especiales que podemos implementar son los siguientes:
Para el operador ==:
__eq__(self,objeto2)
Para el operador !=:
__ne__(self,objeto2)
Para el operador >:
__gt__(self,objeto2)
Para el operador >=:
__ge__(self,objeto2)
Para el operador <:
__lt__(self,objeto2)
Para el operador <=:
__le__(self,objeto2)

Es importante recordar que una redefinición de un operador tiene sentido si ayuda y hace
más claro nuestro algoritmo.
Veamos con un ejemplo la sintaxis para redefinir todos estos operadores relacionales.
Crearemos una clase Persona que tiene como atributo el nombre y la edad. El operador
== retornará verdadero si las dos personas tienen la misma edad, el operador > retornará
True si la edad del objeto de la izquierda tiene una edad mayor a la edad del objeto de la
derecha del operador >, y así sucesivamente:
class Persona:
def __init__(self,nom,ed):
self.nombre=nom
self.edad=ed
def __eq__(self,objeto2):
if self.edad==objeto2.edad:
return True
else:
return False
def __ne__(self,objeto2):
if self.edad!=objeto2.edad:
return True
else:
return False
def __gt__(self,objeto2):
if self.edad>objeto2.edad:
return True
else:
return False
def __ge__(self,objeto2):
if self.edad>=objeto2.edad:
return True
else:
return False
def __lt__(self,objeto2):
if self.edad<objeto2.edad:
return True
else:
return False
def __le__(self,objeto2):
if self.edad<=objeto2.edad:
return True
else:
return False

per1=Persona('juan',22)

64
t: @charli3vazquez
per2=Persona('ana',22)
if per1==per2:
print 'Las dos personas tienen la misma edad.'
else:
print 'No tienen la misma edad.'
Como pedemos observar planteamos un método por cada operdor relacional:
def __eq__(self,objeto2):
if self.edad==objeto2.edad:
return True
else:
return False

El método recibe como referencia (self) la dirección del objeto ubicado a la izquierda del
operador relacionar y como parámetro (objeto2) la referencia del objeto ubicado a la
derecha del operador. Solo nos queda analizar el atributo edad de cada objeto y retornar
True si los dos almacenan el mismo valor, en caso contrario retornar False.
Problema resuelto
Crear una clase Persona que tenga como atributo el nombre y la edad. El operador ==
retornará verdadero si las dos personas tienen la misma edad, el operador > retornará
True si la edad del objeto de la izquierda tiene una edad mayor a la edad del objeto de la
derecha del operador >, y así sucesivamente:
class Persona:
def __init__(self,nom,ed):
self.nombre=nom
self.edad=ed
def __eq__(self,objeto2):
if self.edad==objeto2.edad:
return True
else:
return False
def __ne__(self,objeto2):
if self.edad!=objeto2.edad:
return True
else:
return False
def __gt__(self,objeto2):
if self.edad>objeto2.edad:
return True
else:
return False
def __ge__(self,objeto2):
if self.edad>=objeto2.edad:
return True
else:
return False
def __lt__(self,objeto2):
if self.edad<objeto2.edad:
return True
else:
return False
def __le__(self,objeto2):
if self.edad<=objeto2.edad:
return True
else:
return False

per1=Persona('juan',22)
per2=Persona('ana',22)
if per1==per2:
print 'Las dos personas tienen la misma edad.'
else:
print 'No tienen la misma edad.'

65
t: @charli3vazquez

Problema Propuesto
Plantear una clase Rectangulo. Definir dos atributos (ladomenor y ladomayor). Redefinir el
operador == de tal forma que tengan en cuenta la superficie del rectángulo.
class Rectangulo:
def __init__(self,lmen,lmay):
self.lmenor=lmen
self.lmayor=lmay
def retornarsuperficie(self):
return self.lmenor*self.lmayor
def __eq__(self,objeto2):
if self.retornarsuperficie()==objeto2.retornarsuperficie():
return True
else:
return False

rectangulo1=Rectangulo(10,10)
rectangulo2=Rectangulo(5,20)
if rectangulo1==rectangulo2:
print 'Los rectangulos tienen la misma superficie'
else:
print 'Los rectangulos no tienen la misma superficie'

66
t: @charli3vazquez

37. Las cadenas tratadas como objetos


Ahora que hemos introducido los conceptos básicos de objetos veamos más profundo el
concepto de cadenas (string) en Python.
En Python todo es un objetos, por lo que cuando definimos una cadena estamos
definiendo un objeto.
Como hemos visto toda clase tiene una serie de métodos, veremos los métodos
principales que tiene la clase que en Python administra una cadena.
Los métodos:
• capitalize()
• Retorna otra cadena con el primer caracter en mayúsculas.
• cadena='ana'
print cadena.capitalize() #Ana
print cadena #ana
• Es importante notar que no se modifica el contenido de la variable 'cadena'. El
método capitalize() retorna otra cadena con el primero en mayúsculas.
• upper()
• Retorna otra cadena con todos los caracteres convertidos a mayúscula.
• cadena1='ana'
cadena2=cadena1.upper()
print cadena2 #ANA
• lower()
• Retorna otra cadena con todos los caracteres convertidos a minúsculas.
• cadena1='Ana'
cadena2=cadena1.lower()
print cadena2 #ana
• isupper()
• Retorna True si todos los caracteres de la cadena están en mayúsculas.
• cadena='ANA'
if cadena.isupper():
print 'La cadena '+cadena+' esta toda en mayusculas'
• islower()
• Retorna True si todos los caracteres de la cadena están en minúsculas.
• cadena1='ana'
if cadena.islower():
print 'La cadena '+cadena+' esta toda en minusculas'
• isdigit()
• Retorna verdadero si todos los caracteres de la cadena son dígitos.
• cadena='120'
if cadena.isdigit():
print 'Todos los caracteres de la cadena son numeros'
• Si al menos uno de los caracteres es distinto a un dígito retorna False. Inclusive si
tiene el caracter punto.
• isalpha()
• Retorna True si todos los caracteres son alfabéticos.
• cadena='Hola Mundo'
if cadena.isalpha():
print 'Todos los caracteres de la cadena son del alfabeticos'
else:
print 'No todos los caracteres de la cadena son del alfabeticos'
• En el ejemplo superior ejecuta el bloque del else ya que la cadena contiene un
caracter de espacio.
• isspace()
• Retorna verdadero si todos los caracteres de la cadena son espacios en blanco
• cadena=' '
if cadena.isspace():
print 'Todos los caracteres de la cadena son espacios en blanco'
• isalnum()

67
t: @charli3vazquez

• Retorna True si todos los caracteres de la cadena son números o caracteres


alfabéticos.
• cadena='cordoba2008'
if cadena.isalnum():
print 'Todos los caracteres son numeros o alfabeticos'
• find('cadena',[inicio],[fin])
• Retorna la posición donde se encuentra el valor del primer parámetro en el string.
Si no se encuentra retorna -1. Podemos indicar como segundo y tercer parámetro a
partir de que posición y hasta que posición de la cadena hacer la búsqueda.
• cadena='esto es una prueba y es solo eso'
pos=cadena.find('es')
print pos #0
• Retorna 0 ya que los dos primeros caracteres son la cadena 'es', es decir retorna la
primera aparición del string.
• cadena='esto es una prueba y es solo eso'
pos=cadena.find('es',5)
print pos #5
• En este otro ejemplo comenzamos la búsqueda a partir de la posición 5. Si no
indicamos el tercer parámetro la búsqueda la hace hasta el final de la cadena
• rfind('cadena',[inicio],[fin])
• Igual al método find con la diferencia que la búsqueda comienza desde el final.
• cadena='esto es una prueba y es solo eso'
pos=cadena.rfind('es')
print pos #29
• count('cadena',[inicio],[fin])
• Retorna la cantidad de veces que la cadena se repite en el string.
• cadena='esto es una prueba y es solo eso'
cant=cadena.count('es')
print cant #4
• replace('cadena1','cadena2',[maximo])
• Retorna un string remplazando todas las ocurrencias de cadena1 por cadena2.
Podemos eventuamente indicar la cantidad máxima de remplazos.
• cadena1='esto es una prueba y es solo eso'
cadena2=cadena1.replace('es','ES')
print cadena2 #ESto ES una prueba y ES solo ESo
• split('caracter separador',[maximo])
• El método split retorna una lista dividiendo el string por el caracter indicado en el
primer parámetro. Podemos pasar un segundo parámetro indicando la cantidad de
trozos a general, el último elemento de la lista almacena el resto del string.
• cadena='esto es una prueba y es solo eso'
lista=cadena.split(' ')
print lista #['esto', 'es', 'una', 'prueba', 'y', 'es', 'solo', 'eso']
print len(lista) #8
lista=cadena.split(' ',2)
print lista #['esto', 'es', 'una prueba y es solo eso']
print len(lista) #3
• rsplit('caracter separador',[maximo])
• Semejante a split pero procesando desde el final del string. En caso de indicar
maximo el primer elemento de la lista almacena el trozo restante.
• cadena='esto es una prueba y es solo eso'
lista=cadena.rsplit(' ')
print lista #['esto', 'es', 'una', 'prueba', 'y', 'es', 'solo', 'eso']
print len(lista) #8
lista=cadena.rsplit(' ',2)
print lista #['esto es una prueba y es', 'solo', 'eso']
print len(lista) #3
• splitlines()
• Retorna una lista dividiendo el string con los retornos de carro contenidos en el
mismo.

68
t: @charli3vazquez
• mensaje="""Primer linea
Segunda linea
Tercer linea
Cuarta linea"""
lista=mensaje.splitlines()
print lista #['Primer linea', ' Segunda linea', ' Tercer linea', ' Cuarta linea']
• swapcase()
• Retorna un string transformando los caracteres minúsculas a mayúsculas y los
mayúsculas a minúsculas.
• cadena1='Sistema de Facturacion'
cadena2=cadena1.swapcase()
print cadena2 #sISTEMA DE fACTURACION
• rjust(ancho,caracter de relleno)
• Retorna un string justificado a derecha y rellenando el lado izquierdo con
caracteres según el segundo parámetro. La nueva cadena toma un largo indicado
según el valor del primer parámetro.
• cadena='200'
cadena2=cadena.rjust(5,'$')
print cadena2 #$$200
• ljust(ancho,caracter de relleno)
• Similar a rjust con la salvedad que se justifica a derecha el string.
• cadena='200'
cadena2=cadena.ljust(5,'$')
print cadena2 #200$$
• center(ancho,caracter de relleno)
• El string original se centra.
• cadena='200'
cadena2=cadena.center(5,'$')
print cadena2 #$200$

Problema resuelto
Confeccionar una función que reciba una lista de valores y los muestre en columna y
justificados a derecha.
def mostrar(lista):
print '<pre>'
for v in lista:
print v.rjust(10,' ')
print '<br>'
print '<pre>'

l=['234','12','345534','234','1','45']
mostrar(l)

Problema Propuesto
Confeccionar una función que reciba una oración y retorne la palabra mayor
alfabéticamente.
def mayoralfa(cadena):
lista=cadena.split(' ')
mayor=lista[0]
for pa in lista:
if pa>mayor:
mayor=pa
return mayor

oracion='esto es una prueba y es'


print mayoralfa(oracion)

69
t: @charli3vazquez

38. Las listas tratadas como objetos


Ahora veremos más profundamente el concepto de listas en Python y los métodos que
provee su clase.
Los métodos:
• append(elemento)
• El método append añade un elemento al final de la lista.
• lista=['juan','ana','luis']
lista.append('carlos')
print lista #['juan', 'ana', 'luis', 'carlos']
• extend(elementos)
• El método extend procesa la secuencia de elementos del parámetro y los añade
uno a uno a la lista. La diferencia con el método append es que append siempre
añade un único elemento a la lista y extend añade tantos elementos como tenga la
secuencia.
• lista=['juan','ana','luis']
lista.extend(['uno','dos'])
print lista #['juan', 'ana', 'luis', 'uno', 'dos']
• Ahora la lista tiene 5 elementos, es decir se añadieron 2 nuevas componentes a la
lista.
• En cambio si utilizamos append el resultado es:
• lista=['juan','ana','luis']
lista.append(['uno','dos'])
print lista #['juan', 'ana', 'luis', ['uno', 'dos']]
Ahora la lista tiene cuatro elementos y el último elemento es una lista también.
• insert(posición,elemento)
• El método insert añade un elemento en la posición que le indicamos en el primer
parámetro.
• lista=['juan','ana','luis']
lista.insert(0,'carlos')
print lista #['carlos', 'juan', 'ana', 'luis']
• En este ejemplo insertamos la cadena 'carlos' al principio de la lista, ya que
pasamos la posición 0, no se borra el elemento que se encuentra en la posición 0
sino se desplaza a la segunda posición.
• Si indicamos una posición que no existe porque supera a la posición del último
elemento se inserta al final de la lista.
• pop([posicion]
• El método pop si lo llamamos sin parámetro nos retorna y borra la información del
último nodo de la lista. Si en cambio pasamos un entero este indica la posición del
cual se debe extraer.
• lista=['juan','ana','luis','marcos']
elemento=lista.pop()
print elemento #marcos
print lista #['juan', 'ana', 'luis']
print lista.pop(1) #ana
print lista #['juan', 'luis']
• remove(elemento)
• Borra el primer nodo que coincide con la información que le pasamos como
parámetro.
• lista=['juan','ana','luis','marcos','ana']
lista.remove('ana')
print lista #['juan', 'luis', 'marcos', 'ana']
• count(elemento)
• Retorna la cantidad de veces que se repite la información que le pasamos como
parámetro.
• lista=['juan','ana','luis','marcos','ana']
print lista.count('ana') #2
• index(elemento,[inicio],[fin])

70
t: @charli3vazquez

• Retorna la primera posición donde se encuentra el primer parámetro en la lista.


Podemos eventualmente indicarle a partir de que posición empezar a buscar y en
que posición terminar la búsqueda.
• Si no lo encuentra en la lista genera un error: ValueError: list.index(x): x not in list
• lista=['juan','ana','luis','marcos','ana']
print lista.index('ana') #1
• sort()
• Ordena la lista de menor a mayor.
• lista=['juan','ana','luis','marcos','ana']
lista.sort()
print lista #['ana', 'ana', 'juan', 'luis', 'marcos']
• reverse()
• Invierte el orden de los elementos de la lista.
• lista=['juan','ana','luis','marcos','ana']
lista.reverse()
print lista #['ana', 'marcos', 'luis', 'ana', 'juan']
Si necesitamos borrar un nodo de la lista debemos utilizar el comando del que provee
Python:
lista=['juan','ana','luis','marcos']
del lista[2]
print lista #['juan', 'ana', 'marcos']

Podemos utilizar el concepto de porciones para borrar un conjunto de elementos de la


lista:
Si queremos borrar los elementos de la posición 2 hasta la 3:
lista=['juan','ana','carlos','maria','pedro']
del lista[2:4]
print lista # ['juan', 'ana', 'pedro']

Si queremos borrar desde la 2 hasta el final:


lista=['juan','ana','carlos','maria','pedro']
del lista[2:]
print lista # ['juan', 'ana']

Si queremos borrar todos desde el principio hasta la posición 3 sin incluirla:


lista=['juan','ana','carlos','maria','pedro']
del lista[:3]
print lista # ['maria', 'pedro']

Si queremos ir borrando de a uno de por medio:


lista=['juan','ana','carlos','maria','pedro']
del lista[::2]
print lista # ['ana', 'maria']

Si necesitamos modificar el contenido de un nodo de la lista debemos utilizar el operador


de asignación:
lista=['juan','ana','luis','marcos']
lista[2]='xxxxx'
print lista #['juan', 'ana', 'xxxxx', 'marcos']

71
t: @charli3vazquez

Problema resuelto
Crear una lista con 30 valores aleatorios comprendidos entre 1 y 300.
Efectuar las siguientes operaciones (Luego de cada operación mostrar el estado de la
lista):
- Borrar el primer y último elemento de la lista.
- Insertar un elemento al final con la suma de todos los elementos actuales.
- Insertar un elemento entre el primero y el segundo elemento de la lista con el valor 125.
import random

lista=[]
for x in range(1,50):
valor=random.randint(1,300)
lista.append(valor)
print lista
print '<br>'
del lista[0]
del lista[-1]
print lista
print '<br>'
suma=0
for x in range(1,len(lista)):
suma=suma+lista[x]
lista.append(suma)
print lista
print '<br>'
lista.insert(1,125)
print lista

Problema Propuesto
Crear una lista con 10 valores aleatorios comprendidos entre 1 y 5.
- Insertar un nodo al final de la lista con el mayor elemento de la lista.
- Insertar un nodo al principio de la lista con la suma de los primeros 5 nodos.
- Imprimir la cantidad de veces que se repite la información del segundo nodo en la lista.
import random

lista=[]
for x in range(1,10):
valor=random.randint(1,5)
lista.append(valor)
print lista
print '<br>'
mayor=lista[0]
for valor in lista:
if valor>mayor:
mayor=valor
lista.insert(0,mayor)
print lista
print '<br>'
print lista.count(lista[1])

72
t: @charli3vazquez

39. Los diccionarios tratados como objetos


Habíamos visto la estructura de datos tipo diccionario que utiliza una clave para acceder a
un valor. El subíndice puede ser un entero, un string etc. Un diccionario vincula una clave
y un valor.
Los diccionarios en Python también son objetos y como tales tienen una serie de métodos
que nos permiten administrarlos:
• keys()
• Retorna una lista con todas las claves del diccionario.
• diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
lista=diccionario.keys()
print lista # ['house', 'window', 'bed', 'red']
• values()
• Retorna una lista con todos los valores almacenados en el diccionario.
• diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
lista=diccionario.values()
print lista # ['casa', 'ventana', 'cama', 'rojo']
• items()
• Retorna una lista que contiene en cada nodo una tupla con la clave y valor del
diccionario.
• diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
lista=diccionario.items()
print lista # [('house', 'casa'), ('window', 'ventana'), ('bed', 'cama'), ('red', 'rojo')]
• pop(clave,[valor])
• Extrae el valor de la clave que pasamos como parámetro y borra el elemento del
diccionario. Genera un error si no se encuentra dicha clave, salvo que se inicialice
un segundo parámetro que será el dato que retornará.
• diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
valor=diccionario.pop('window')
print valor # ventana
print diccionario #{'house': 'casa', 'bed': 'cama', 'red': 'rojo'}
• Si no encuentra la clave en el diccionario y hemos indicado un segundo parámetro
al método pop será dicho valor el que retorne:
• diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
valor=diccionario.pop('love','clave no encontrada')
print valor # clave no encontrada
• has_key(clave)
• Retorna True si la clave se encuentra en el diccionario, False en caso contrario.
• diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
if diccionario.has_key('love'):
print 'Si tiene la clave buscada'
else:
print 'No existe la clave buscada'
• clear()
• Elimina todos los elementos del diccionario.
• diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
diccionario.clear()
print diccionario # {}
• copy()
• Se genera una copia idéntica del diccionario actual en otra parte de memoria.
• diccionario1={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
diccionario2=diccionario1.copy()
print diccionario2 #{'house': 'casa', 'window': 'ventana', 'red': 'rojo', 'bed': 'cama'}
diccionario1['house']='xxxxx'
print diccionario2 #{'house': 'casa', 'window': 'ventana', 'red': 'rojo', 'bed': 'cama'}
• Es importante hacer notar que no es lo mismo:
• diccionario2=diccionario1
• Con la asignación anterior no se esta creando un segundo diccionario sinó se tiene
dos variables que referencian al mismo objeto.
• popitem()

73
t: @charli3vazquez

• Retorna un elemento del diccionario y lo elimina. Como no hay un sentido de orden


en el diccionario se extrae uno al azar.
• diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
elemento=diccionario.popitem()
print elemento
print diccionario
• Para saber cual se extrajo se debe ejecutar el algoritmo.
• update(diccionario2)
• Modifica el diccionario actual agregando los elementos del diccionario2, si una
clave está repetida se modifica su valor.
• diccionario1={'uno':'1','dos':'2','tres':'3333'}
diccionario2={'tres':'3','cuatro':'4','cinco':'5'}
diccionario1.update(diccionario2)
print diccionario1 #{'cuatro': '4', 'cinco': '5', 'dos': '2', 'tres': '3', 'uno': '1'}
Además seguimos contando con el comando del para borrar elementos del diccionario:
diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
del diccionario['house']
print diccionario #{'window': 'ventana', 'bed': 'cama', 'red': 'rojo'}
El cambio o agregado de un valor al diccionario se hace mediante la asignación:
diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
diccionario['red']='colorado'
diccionario['blue']='azul'
print diccionario # {'house': 'casa', 'window': 'ventana', 'bed': 'cama', 'red': 'colorado','blue': 'azul'}

La cantidad de elementos mediante la función len:


diccionario={'house':'casa','red':'rojo','bed':'cama','window':'ventana'}
print len(diccionario) # 4

Problema resuelto
Definir un diccionario para almacenar el nombre de un usuario como clave y su mail como
valor.
Crear una función que almacene la clave y su mail siempre y cuando no haya otro nombre
de usuario igual en el diccionario
def sumarusuario(dic,usu,valor):
if not dic.has_key(usu):
dic[usu]=valor

diccionario={}
sumarusuario(diccionario,'juan','[email protected]')
sumarusuario(diccionario,'ana','[email protected]')
sumarusuario(diccionario,'luis','[email protected]')
sumarusuario(diccionario,'luis','[email protected]')
print diccionario

74
t: @charli3vazquez

Problema Propuesto
Crear un diccionario con 3 elementos (almacenar como clave el nombre de una fruta y
como valor su precio). Luego hacer las siguientes operaciones:
- Agregar un cuarto elemento.
- Imprimer la cantidad de elementos del diccionario.
- Borrar un elemento del diccionario.
- Imprimir todas las claves.
- Imprimir todos los valores.
- Imprimir claves y valores.
- Borrar el diccionario.

frutas={'manzanas':1.60,'peras':1.90,'bananas':0.95}
print frutas
print '
'
frutas['naranjas']=2.50
print len(frutas)
print '<br>'
del frutas['naranjas']
for x in frutas.keys():
print x
print '<br>'
for x in frutas.values():
print x
print '<br>'
for (clave,valor) in frutas.items():
print clave+' '+str(valor)+' - '
print '<br>'
frutas.clear()
print frutas

75
t: @charli3vazquez

40. Instalación de Python en su computadora


Ahora a llegado el momento de instalar Python en su equipo. Debemos descargar el
instalador del sitio oficial de Python.
Aquí seguiremos los pasos para instalar la versión para Windows python-2.5.2.
Descarguemos la versión para el procesasor x86.
Tenemos en nuestro equipo el archivo para hacer la instalación local de Python
python-2.5.2.msi. Lo ejecutamos
El primer diálogo nos pregunta si se instala solo para nosotros o para todos los usuarios
del equipo (podemos dejar la opción seleccionada para todos los usuarios) y presionamos
'Next'.
El segundo formulario del wizard nos permite seleccionar la unidad donde se instala el
lenguaje. Dejemos por defecto la que nos propone el instalador: c:\Python25\
El tercer paso nos permite seleccionar o suprimir distintos módulos que vienen con Python
(extensiones, documentación etc.), dejaremos por defecto que instale todos.
Finalmente ya tenemos instalado el lenguaje Python en nuestro equipo.
Ahora para codificar los programas utilizaremos un editor que se instala junto con el
lenguaje Python, desde el menú de opciones podemos acceder al editor llamado: IDLE.
En realidad lo primero que aparece es una ventana llamada Python Shell donde podemos
ejecutar instrucciones en forma unitaria:
Por ejemplo escribamos:
print 'Hola Mundo'
Pero nuestro objetivo fundamental es la creación de programas o módulos completos en
Python, para esto seleccionamos en esta ventana desde el menú de opciones File -> New
Window.
Ahora sí tenemos el editor que suministra Python para codificar nuestros programas.
Escribamos una aplicación muy sencilla:
import random

def mostrarnumeros():
for x in range(7):
valor=random.randint(1,100)
print valor

mostrarnumeros()

La grabamos en nuestro disco duro (por ejemplo prueba1.py) y desde el menú de


opciones seleccionamos Run -> Run Module, si hemos tipeado correctamente el
programa tendremos el resultado en la ventana "Python Shell".
En los conceptos siguientes veremos temas que no pueden ser ejecutados directamente
en el sitio PythonYa, por lo que tener el lenguaje Python en forma local en su equipo se
hace indispensable para probarlos.

76
t: @charli3vazquez

41. Creación, carga y lectura de archivos de texto


Python cuenta con una clase llamada file que nos permite crear, escribir y leer datos de un
archivo de texto.
Para crear un objeto de la clase file debemos utilizar la función open. Cuando llamamos a
dicha función le pasamos como primer parámetro el nombre del archivo de texto y el
modo de apertura del mismo:
open(nombre del archivo,modo)
Si el archivo de texto se encuentra en la misma carpeta que nuestro programa no
necesitamos indicar el path (camino). Los modos de apertura del archivo de texto pueden
ser:
• 'r' Abre el archivo para lectura (debe existir el archivo)
• 'w' Crea el archivo y lo abre para escribir
• 'a' Abre el archivo para escribir. Se crea si el archivo no existe. Solo podemos
agregar datos al final
Creación de un archivo de texto
El siguiente algoritmo crea en disco un archivo de texto llamado 'datos.txt' y no graba
datos. Si queremos luego de ejecutar el programa podemos verificar la existencia del
archivo en la misma carpeta donde almacenamos nuestro programa.
Cuando lo grabamos el archivo fuente en Python debemos darle un nombre al programa
(por ejemplo texto1.py)
def creaciontxt():
archi=open('datos.txt','w')
archi.close()

creaciontxt()

Creamos una función llamada creaciontxt donde primero llamamos a la función open
pasando como parámetros el nombre del archivo de texto a crear y el modo de apertura
('w')
La función open retorna la referencia del objeto file. Luego llamamos al método close de
la clase file. Si luego queremos ver si se a creado el archivo de textos podemos hacerlo
desde algun explorador de archivos, en la carpeta donde se encuentra nuestro programa
en Python veremos un archivo llamado 'datos.txt' que tiene un tamaño de 0 bytes.

Grabación de líneas en el archivo de texto


def creartxt():
archi=open('datos.txt','w')
archi.close()

def grabartxt():
archi=open('datos.txt','a')
archi.write('Linea 1\n')
archi.write('Linea 2\n')
archi.write('Linea 3\n')
archi.close()

creartxt()
grabartxt()

La función creartxt es similar al ejemplo anterior, y la función grabartxt tiene por objetivo
abrir el archivo en modo de agregado. Cada vez que grabamos un string en el archivo de
texto insertamos un salto de línea '\n'. Finalmente liberamos el archivo llamando al método
close.

77
t: @charli3vazquez

Para ver el contenido de nuestro archivo de texto debemos utilizar un editor de texto (bloc
de notas o el mismo entorno del Idle nos puede servir para ver el contenido de un archivo
txt), Lectura línea a línea de un archivo de texto.
La clase file tiene un método llamado readline() que retorna toda una línea del archivo de
texto y deja posicionado el puntero de archivo en la siguiente línea. Cuando llega al final
del archivo readline retorna un string vacío.
def creartxt():
archi=open('datos.txt','w')
archi.close()

def grabartxt():
archi=open('datos.txt','a')
archi.write('Linea 1\n')
archi.write('Linea 2\n')
archi.write('Linea 3\n')
archi.close()

def leertxt():
archi=open('datos.txt','r')
linea=archi.readline()
while linea!="":
print linea
linea=archi.readline()
archi.close()

creartxt()
grabartxt()
leertxt()

Luego de de abrir el archivo para lectura procedemos a leer la primer línea:


archi=open('datos.txt','r')
linea=archi.readline()

El while se repite mientras el método readline() no retorne un string vacío. Dentro del
while procedemos a imprimir la línea que acabamos de leer y leemos la siguiente (el
método readline() retorna el contenido de toda la línea inclusive el salto de línea \n):
while linea!="":
print linea
linea=archi.readline()

Podemos leer todo el contenido de un archivo de texto y almacenarlo en una lista (esto
tiene sentido si el archivo de texto no es muy grande):
def creartxt():
archi=open('datos.txt','w')
archi.close()

def grabartxt():
archi=open('datos.txt','a')
archi.write('Linea 1\n')
archi.write('Linea 2\n')
archi.write('Linea 3\n')
archi.close()

def leertxtenlista():
archi=open('datos.txt','r')
lineas=archi.readlines()
print lineas
archi.close()

creartxt()
grabartxt()
leertxtenlista()
78
t: @charli3vazquez

Utilizamos el método readlines() en lugar de readline(). El método readlines() retorna una


lista con cada línea del archivo de texto.
Recordemos que podemos procesar luego cada elemento de la lista recorriéndola con
una estructura repetitiva:
def leertxtenlista():
archi=open('datos.txt','r')
lineas=archi.readlines()
for li in lineas:
print li
archi.close()

79
t: @charli3vazquez

42. Captura de excepciones


Cuando nuestra aplicación genera un error que Python no puede resolver podemos
disponer un código que se ejecute para dichas situaciones.
Errores como tratar de abrir un archivo que no existe, acceder a un elemento de una lista
que no existe, dividir por cero etc. genera un error que hace que nuestro programa se
detenga y no continúe su ejecución. Pero con Python podemos preveer estas situaciones
y definir un algoritmo que se ejecutará exepcionalmente cuando ocurra dicho error.
Si ejecutamos el siguiente código el programa se detendrá informándonos que se produjo
un error y no puede continuar:
y=0
x=10/y
print 'esta linea nunca se ejecuta'

Utilizando excepciones podemos capturar el error y continuar la ejecución del programa:


y=0
try:
x=10/y
except ZeroDivisionError:
print 'No existe la division por cero'
print 'Esta linea si se ejecuta'

La estructura try/except requiere que indiquemos el tipo de excepción a capturar, en este


caso cuando se trata de dividir por cero Python genera una excepción llamada
ZeroDivisionError. Para capturar dicha excepción debemos disponerla seguido de la
palabra clave except.
Si se produce la excepción se ejecutan las instrucciones que dispongamos en las líneas
siguientes al except.
Cuando se captura una excepción el programa no se detiene y continua con las
intrucciones siguientes al bloque try/except.
Veamos otro ejemplo de intentar acceder a un elemento que no existe en una lista:
lista1=['juan','ana','carlos']
try:
print lista1[5]
except IndexError:
print 'Intenta acceder a un elemento no existente a la lista'

lista1 almacena 3 elementos y tratamos de acceder al de la posición 5. Python en este


situación genera una excepción de tipo IndexError, como disponemos el acceso dentro de
la contrucción try/except y captura el tipo de excepción IndexError el programa no se
detiene y ejecuta la instrucción seguida de la línea except IndexError.
Un tema de aplicación muy común donde se utilizan las excepciones es con el tratamiento
de archivos, hay muchas situaciones que pueden generar excepciones en estos casos
como puede ser que no se pueda abrir un archivo porque no existe, no lo pueda crear
porque la unidad de amacenamiento está llena, el archivo se encuentra bloqueado por
otro programa etc.

80
t: @charli3vazquez

El código para crear, grabar y leer un archivo capturando las excepciones queda de la
siguiente manera:
def creartxt():
try:
archi=open('datos.txt','w')
archi.close()
except IOError:
print 'No se pudo crear el archivo'

def grabartxt():
try:
archi=open('datos.txt','a')
archi.write('Linea 1\n')
archi.write('Linea 2\n')
archi.write('Linea 3\n')
archi.close()
except IOError:
print 'No se pudo abrir el archivo'

def leertxt():
try:
archi=open('noexiste.txt','r')
linea=archi.readline()
while linea!="":
print linea
linea=archi.readline()
archi.close()
except IOError:
print 'El archivo no existe'

creartxt()
grabartxt()
leertxt()

La excepción cumple un doble cometido en estas situaciones, primero mostramos


mensajes que nosotros definimos y no los que Python muestra por defecto cuando se
genera un error y por otro lado podemos continuar con la ejecución de nuestro algoritmo
sin que se detenga.
Podemos disponer varios capturas de excepciones para un bloque try:
lista1=['juan','ana','carlos']
try:
print lista1[0]
z=10/0
except IndexError:
print 'Intenta acceder a un elemento no existente a la lista'
except ZeroDivisionError:
print 'Division por cero no permitida'

En este bloque try capturamos las excepciones de tipo: IndexError y ZeroDivisionError.


Como podemos ver la que se dispara es la de ZeroDivisionError. Pero podemos generar
el otro tipo de excepción modificando la línea de impresión del elemento de la lista:
print lista1[5]
Si hacemos este cambio se ejecuta la sección seguida a 'except IndexError:'. Una vez
disparada dicha excepción no continua con las instrucciones del bloque del try, es decir no
generará la excepción de división por cero, pero si continuará con el flujo del algoritmo.

81
t: @charli3vazquez

Si no queremos tratar los errores en forma independiente podemos agrupar excepciones:


lista1=['juan','ana','carlos']
try:
print lista1[0]
z=10/0
except (IndexError,ZeroDivisionError):
print 'Se produjo un error'

Debemos indicar entre paréntesis todas las excepciones a capturar y como se procede
con ellas, en este caso solo se muestra un mensaje 'Se produjo un error'.
Otra parte opcional de un bloque try es la del else. Este bloque se ejecuta si no se produce
la excepción:
lista1=['juan','ana','carlos']
try:
print lista1[0]
z=10/5
except (IndexError,ZeroDivisionError):
print 'Se produjo un error'
else:
print z

Este programa muestra el primer elemento de la lista, luego procede a inicializar la


variable z con el valor 10/5 y seguidamente ejecuta la sección del else ya que no se a
generado excepciones.
Podemos tratar de imprimir una componente que no exista de la lista y veremos que no se
ejecuta el bloque del else.
Hemos visto que podemos capturar distintas excepciones en forma independiente:
except IndexError:
print 'Intenta acceder a un elemento no existente a la lista'
except ZeroDivisionError:
print 'Division por cero no permitida'

En forma conjunta:
except (IndexError,ZeroDivisionError):
print 'Se produjo un error'

Inclusive Python nos permite disponer un bloque try except para la captura de cualquier
tipo de excepción (si bien esto no es lo más recomendable ya que es difícil emprender
una acción para todos los tipos de errores que pueden generarse):
lista1=['juan','ana','carlos']
try:
print lista1[0]
z=10/0
except:
print 'Se produjo un error'

Otra sección que puede tener un bloque try except es finally.


finally permite disponer un bloque de código que se ejecutará siempre, indistintamente se
produzca o no la excepción.

82
t: @charli3vazquez

El objetivo de esta sección es generalmente utilizado para liberar recursos como puede
ser cerrar la conexión con una base de datos o cerrar un archivo.
try:
z=10/0
print 'Esto no se ejecuta'
except:
print 'Se produjo un error'
finally:
print 'Siempre se ejecuta'

Problema resuelto
Definir una diccionario donde se debe almacenar los nombres de frutas como clave y su
precio como valor. Tratar de acceder a una clave inexistente y capturar la excepción
KeyError que se produce en estos casos.
frutas={'naranjas':1.5,'manzanas':2.3,'peras':1.5}
try:
print frutas['sandias']
except KeyError:
print 'No existe dicha fruta'

83
t: @charli3vazquez

43. Google App Engine utilizando Python


El servicio de Google App Engine nos permite obtener una cuenta para crear nuestras
aplicaciones web utilizando los servidores y tecnología de Google. Y como ventaja
después de haber estudiado Python Google App Engine nos facilita crear un sitio
utilizando como lenguaje de servidor el Python.
Actualmente nos suministra 500 MB para el almacenamiento de nuestras páginas y base
de datos, todo esto en forma gratuita.
• El primer paso es registrarnos en Google para obtener una cuenta y esto lo
podemos hacer desde aquí
• Si tarda un poco la asignación de la cuenta no es tan importante ya que todo el
desarrollo lo hacemos en forma local en nuestro equipo. Finalizado el proyecto lo
debemos cargar en los servidores de Google.
• Para trabajar en forma local debemos tener instalado el lenguaje Python en su
versión 2.5 o superior.
• También tenemos que tener instalado el kid de desarrollo que nos provee Google y
ejecuta nuestra aplicación en forma local, podemos descargar la última
actualización del mismo desde aquí.
Luego de instalar el Python 2.5 o superior debemos proceder a instalar el kid de
desarrollo que nos provee Google. Cuando lo instalamos nos sugiere donde se instala el
software (podemos dejar el que nos propone por defecto): c:\Archivo de programa\Google
\google_appengine\
Ya tenemos todo para comenzar a experimentar con Python y el framework que nos
provee Google para el desarrollo de aplicaciones web.
Si ya dispone la cuenta suministrada por Google desde el panel de administración
podemos crear una aplicación presionando el botón "Create an Application".
Debemos seleccionar un nombre para nuestra aplicación que correrá como un
subdominio de appspot.com, como podrán comprobar muchos de los nombres más
comunes ya han sido tomados por otros usuarios.
Seleccionado un nombre disponible (podemos comprobar disponibilidad presionando el
botón "Check Availability") asignamos un título y aceptamos los términos del servicio. Ya
estamos en condiciones de subir nuestra aplicación (tengamos en cuenta que todavía no
hemos desarrollado ni el 'Hola Mundo').

84
t: @charli3vazquez

44. Hola mundo con Google App Engine


Primero debemos crear un directorio donde se instaló el Google App Engine, normalmente
en: c:\Archivo de programa\Google\google_appengine\
Este nombre debe coincidir con el que obtuvimos desde el panel de control de nuestra
cuenta de Google App Engine (yo tomaré como nombre tutorialya)
Para utilizar los servidores de Google deberemos crear un archivo de configuración
llamado app.yaml y que deberemos localizar en el directorio que acabamos de crear.
El archivo app.yaml tiene una estructura similar a:
application: tutorialya
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
script: tutorialya.py

Del ejemplo anterior deberá modificar la propiedad de application con el nombre de


aplicación que gestionó desde su panel de control del Google App Engine. Lo mismo pasa
con la propiedad script.
Ahora que tenemos nuestro directorio donde se alojará nuestro sitio en forma local y el
archivo de configuración app.yaml debemos crear el archivo Python principal y lo
llamaremos igual que el nombre de la carpeta y con extensión *.py y debe coincidir con la
propiedad script del archivo app.yaml (en mi caso yo lo llamé tutorialya.py).
Para codificar nuestra aplicación Google creó un framework propio llamado webapp y que
se instala automáticamente con nuestra aplicación.
Luego nuestra aplicación mínima utilizando dicho framework es:
import wsgiref.handlers

from google.appengine.ext import webapp

class HolaMundo(webapp.RequestHandler):
def get(self):
self.response.out.write('<html><head></head>')
self.response.out.write('<body>')
self.response.out.write('<h1>Hola Mundo</h1>')
self.response.out.write('</body>')

def main():
application = webapp.WSGIApplication([('/', HolaMundo)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

Después nos detendremos en la forma de codificar utilizando este framework, por ahora
solo nos interesa ver aparecer el 'Hola mundo' en el navegador.
Ya tenemos codificado el archivo *.yaml y *.py, ahora queda iniciar nuestro servidor y
peticionar la página.
Como servidor web no utilizaremos el Apache, sino un servidor creado con Python que
viene incluido con el Google App Engine. Para activar este servidor debemos ir a la línea
de comandos de nuestro sistema operativo hasta la carpeta (c:\Archivo de programa
\Google\google_appengine\) y desde allí arrancar el servidor indicando el nombre de
nuestra aplicación:
c:\Archivo de programa\Google\google_appengine>dev_appserver.py tutorialya/

85
t: @charli3vazquez

Tener en cuenta de pasar como parámetro al programa dev_appserver.py el nombre de la


carpeta que hemos creado para nuestro proyecto (en mi caso la llamé tutorialya)
Si tenemos correctamente creado el archivo *.yaml deberá mostrar un mensaje que el
servidor web está esperando peticiones en el puerto 8080. Luego desde el navegador
debemos llamar nuestra aplicación con la siguiente sintaxis:
http://localhost:8080
Si codificamos correctamente la aplicación deberemos tener el mensaje 'Hola Mundo'.

86
t: @charli3vazquez

45. Subir nuestra aplicación Hola mundo a internet


Si ya tenemos nuestra aplicación ejecutándose en forma correcta localmente:
http://localhost:8080
Ahora para que la puedan acceder todos en internet debemos seguir los siguientes pasos:
• El primer paso es registrarnos en Google si todavía no lo hemos hecho para
obtener una cuenta y esto lo podemos hacer desde aquí
• Si ya dispone la cuenta suministrada por Google desde el panel de administración
podemos crear una aplicación presionando el botón "Create an Application".
• Debemos seleccionar un nombre para nuestra aplicación que correrá como un
subdominio de appspot.com.
• Seleccionado un nombre disponible (podemos comprobar disponibilidad
presionando el botón "Check Availability") asignamos un título y aceptamos los
términos del servicio. Ya estamos en condiciones de subir nuestra aplicación
• Controlar que nuestro archivo app.yaml tiene una estructura similar a:
• application: tutorialya
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: tutorialya.py
• Del ejemplo anterior deberá modificar la propiedad de application con el nombre de
aplicación que gestionó desde su panel de control del Google App Engine. Lo
mismo pasa con la propiedad script.
• Desde la línea de comandos del sistema operativo ejecutar el siguiente programa
en Python que tiene por objetivo hacer el upload de todo nuestro proyecto a la
cuenta que tenemos asignada en Google App Engine:
• c:\Archivo de programa\Google\google_appengine>appcfg.py update tutorialya/
• En ese momento se nos solicitará nuestro mail y clave.
• Ya tenemos en el servidor almacenado nuestro sitio, solo nos falta llamarlo para
verlo correr en la web.
• http://tutorialya.appspot.com/
• Recordar de remplazar el nombre tutorialya con el nombre con el que crearon su
aplicación desde el panel del Google App Engine.

87
t: @charli3vazquez

46. Recuperar el dato de un text (App Engine)


Realizaremos una aplicación que muestre un formulario con un control de tipo text y
cuando se presione el botón submit mostraremos el dato ingresado en otra página.
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form method="post" action="procformulario1">
Ingrese su nombre:<input type="text" name="nombre" size="20"><br>
<input type="submit" value="Ok">
</form>
</body>
""")

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
self.response.out.write(cgi.escape(self.request.get('nombre')))
self.response.out.write("</body></body>")

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()
El programa se inicia al ser verdadera la condición:
if __name__ == '__main__':
main()

Los módulos son objetos y todos los módulos tienen un atributo llamado __name__. El
valor del __name__ de un módulo depende de cómo esté usándolo. Si se importa el
módulo, luego la propiedad __name__ es el nombre del fichero del módulo, sin el
directorio de la ruta ni la extensión del archivo. Pero también puede ejecutar el módulo
directamente como si fuera un programa, en cuyo caso __name__ tendrá un valor
especial predefinido __main__.
El if se verifica como verdadero y llama a la función main().
En la función main debemos crear un objeto de la clase WSGIApplication y pasar como
parámetro una lista con elementos de tipo tupla que asocian una URL y la clase que
procesa dicha petición.

Cuando hacemos referencia a la raiz de nuestro sitio:


http://localhost:8080/
El servidor ejecuta Formulario1 según la tupla indicada con: ('/', Formulario1)
De forma similar cuando se presiona el botón submit del formulario se llama:
http://localhost:8080/procformulario1
y mediante la asociación ('/procformulario1', ProcFormulario1) se ejecutará el código de la
clase ProcFormulario.
88
t: @charli3vazquez

Todas las páginas de nuestro sitio deben ser mapeadas en la lista:


application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1)],
debug=True)

El segundo parámetro del constructor de la clase WSGIApplication es el modo de


ejecución, normalmente el parámetro debug lo inicializamos en true mientras estamos
depurando nuestra aplicación, cuando la finalizamos y la subimos al servidor el parámetro
debug le asignamos False.
La clase WSGIApplication se encuentra en el módulo webapp que se encuentra en el
paquete google.appengine.ext:
from google.appengine.ext import webapp
La clase Formulario1 hereda de la clase RequestHandler que se encuentra en el paquete
webapp. Para generar la página solo debemos reescribir el método get que será el que
genere la página web. Para generar el contenido de la página llamamos al método write.
La clase RequestHandler contiene un atributo llamado response y este un atributo out que
es el que contiene el método write, es decir cada vez que queremos imprimir en la página
debemos disponer el siguiente código:
self.response.out.write("Hola Mundo")
Si se trata de generar un bloque grande de HTML podemos utilizar la característica de
Python de definir un String de varias líneas encerrándolas entre triple comillas:
self.response.out.write("""
<html>
<head></head>
<body>
<form method="post" action="procformulario1">
Ingrese su nombre:<input type="text" name="nombre" size="20"><br>
<input type="submit" value="Ok">
</form>
</body>
""")

Como vemos no es necesario escapar con el caracter '\' las comillas dobles cuando
usamos triple comillas.
Podemos llamar tantas veces al método write como se necesite, todos los string se
almacenan en un archivo de memoria que es el que se enviará al navegador que hizo la
petición.
Una vez que la página que contiene el formulario se muestra en el navegador el operador
ingresa el nombre y al presionar el botón submit el navegador procede a enviar el dato
ingresado al servidor.
En la propiedad action del formulario hemos indicado quien procesará el dato en el
servidor:
action="\procformulario1\"
Recordemos que tenemos mapeada dicha url :
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1)],
debug=True)

89
t: @charli3vazquez

Es decir que la clase ProcFormulario1 recibe el dato. Esta clase también hereda de
RequestHandler pero debe redefinir el método post. Luego procedemos de forma similar a
la otra clase para crear una página en forma dinámica llamando al método write, con la
salvedad que para recuperar el dato cargado en el formulario procedemos a llamar al
método get del objeto request que contiene la clase:
class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
self.response.out.write(cgi.escape(self.request.get('nombre')))
self.response.out.write("</body></body>")

90
t: @charli3vazquez

47. Formulario HTML - control radio (App Engine)


Realizaremos una aplicación que muestre un formulario con dos controles de tipo text,
luego dos controles de tipo radio que indiquen si queremos sumar o restar los valores
ingresados en los controles text.
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese primer valor:
<input type="text" name="valor1">
<br>
Ingrese segundo valor:
<input type="text" name="valor2">
<br>
<input type="radio" name="radio1" value="suma">sumar
<br>
<input type="radio" name="radio1" value="resta">restar
<br>
<input type="submit" value="operar">
</form>
</body>
</html>
""")

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
v1=int(self.request.get('valor1'))
v2=int(self.request.get('valor2'))
operacion=self.request.get('radio1')
if operacion=="suma":
resultado=v1+v2
else:
resultado=v1-v2
self.response.out.write("El resultado de la " + operacion + " es " + str(resultado))
self.response.out.write("</body></body>")

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

En la página principal del sitio asociamos la clase que despliega el formulario HTML:
('/', Formulario1)
Luego la clase que procesa los datos ingresados en el formulario es ProcFormulario1, en
esta primero rescatamos los dos valores ingresados en los controles text y procedemos a
convertilos a entero:
v1=int(self.request.get('valor1'))
v2=int(self.request.get('valor2'))

91
t: @charli3vazquez

Rescatamos la propiedad value del control radio seleccionado:


operacion=self.request.get('radio1')
Y mediante un if verificamos si tenemos que sumar o restar los contenidos de los text:
if operacion=="suma":
resultado=v1+v2
else:
resultado=v1-v2
Por último procedemos a imprimir el resultado de la operación:
self.response.out.write("El resultado de la " + operacion + " es " + str(resultado))

92
t: @charli3vazquez

48. Formulario HTML - control select (App Engine)


Veamos el control HTML de tipo select. Este tipo de control el funcionamiento es similar al
de un conjunto de controles de tipo radio.
Confeccionaremos el mismo problemas del concepto anterior es decir cargar dos números
y posteriormente mediante un control de tipo select seleccionar si queremos sumarlos o
restarlos (solo una de estas operaciones se puede elegir)
La sintaxis del control de tipo select es:
<select name="operacion">
<option value="suma">Sumar</option>
<option value="resta">Restar</option>
</select>
Es importante notar que la sintaxis es bastante distinta a los controles de tipo text y radio.
El elemento select tiene definido la propiedad name mediante la cual rescataremos el
valor seleccionado en el servidor.
El elemento select contiene un conjunto de elementos option. Cada elemento option tiene
definido la propiedad value. El que quede seleccionado el control select rescata su
propiedad value.
Luego el programa en Python utilizando Google App Engine:
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese primer valor:
<input type="text" name="valor1">
<br>
Ingrese segundo valor:
<input type="text" name="valor2">
<br>
<select name="operacion">
<option value="suma">Sumar</option>
<option value="resta">Restar</option>
</select>
<br>
<input type="submit" value="operar">
</form>
</body>
</html>
""")

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
v1=int(self.request.get('valor1'))
v2=int(self.request.get('valor2'))
op=self.request.get('operacion')
if op=="suma":
resultado=v1+v2
else:
resultado=v1-v2
self.response.out.write("El resultado de la " + op + " es " + str(resultado))
self.response.out.write("</body></body>")

def main():

93
t: @charli3vazquez
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

De forma similar como venimos trabajando en una clase desplegamos el formulario


HTML (Formulario1) y otra clase procesa el contenido del formulario (ProcFormulario1).
En la página que procesamos los datos del formulario rescatamos los valores de los
controles text y los convertimos a entero:
v1=int(self.request.get('valor1'))
v2=int(self.request.get('valor2'))
Seguidamente rescatamos la propiedad name de la opción seleccionada del control
select:
op=self.request.get('operacion')
Mediante un if verificamos si tenemos que sumar o restar:
if op=="suma":
resultado=v1+v2
else:
resultado=v1-v2
Por último mostramos el resultado:
self.response.out.write("El resultado de la " + op + " es " + str(resultado))

94
t: @charli3vazquez

49. Formulario HTML - control select con selección múltiple


(App Engine)
Veamos una variante del control select la cual permite seleccionar varias opciones de su
contenido. Para esto debemos agregar la propiedad multiple cuando lo definimos:
<select name="operacion" multiple>
Con este simple cambio podemos seleccionar más de un elemento del interior del control
select.
Confeccionaremos el mismo problema anterior, solo que ahora podremos seleccionar las
dos operaciones en forma simultanea:
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese primer valor:
<input type="text" name="valor1">
<br>
Ingrese segundo valor:
<input type="text" name="valor2">
<br>
<select name="operacion" multiple>
<option value="suma">Sumar</option>
<option value="resta">Restar</option>
</select>
<br>
<input type="submit" value="operar">
</form>
</body>
</html>
""")

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
v1=int(self.request.get('valor1'))
v2=int(self.request.get('valor2'))
operaciones=self.request.get_all('operacion')
for op in operaciones:
if op=="suma":
resultado=v1+v2
self.response.out.write("El resultado de la " + op + " es " + str(resultado) + "<br>")
if op=="resta":
resultado=v1-v2
self.response.out.write("El resultado de la " + op + " es " + str(resultado) + "<br>")
self.response.out.write("</body></body>")

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

95
t: @charli3vazquez

Para recuperar la lista de valores seleccionados del control select debemos llamar al
método get_all del objeto request en lugar de get:
operaciones=self.request.get_all('operacion')
Luego mediante una estructura repetitiva recorremos la lista de valores devuelto y
comparamos con los valores posibles:
for op in operaciones:
if op=="suma":
resultado=v1+v2
self.response.out.write("El resultado de la " + op + " es " + str(resultado) + "<br>")
if op=="resta":
resultado=v1-v2
self.response.out.write("El resultado de la " + op + " es " + str(resultado) + "<br>")

96
t: @charli3vazquez

50. Formulario HTML - control checkbox (App Engine)


Otra forma de hacer selecciones múltiples es utilizar un conjunto de controles de tipo
checkbox. Cada control de tipo checkbox es independiente.
Resolvamos el problema del concepto anterior empleando dos controles de tipo checkbox:
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese primer valor:
<input type="text" name="valor1">
<br>
Ingrese segundo valor:
<input type="text" name="valor2">
<br>
<input type="checkbox" name="check1" value="suma">sumar
<br>
<input type="checkbox" name="check2" value="resta">restar
<br>
<input type="submit" value="operar">
</form>
</body>
</html>
""")

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
v1=int(self.request.get('valor1'))
v2=int(self.request.get('valor2'))
su=self.request.get('check1')
if su=="suma":
resultado=v1+v2
self.response.out.write("El resultado de la " + su + " es " + str(resultado) + "<br>")
re=self.request.get('check2')
if re=="resta":
resultado=v1-v2
self.response.out.write("El resultado de la " + re + " es " + str(resultado) + "<br>")
self.response.out.write("</body></body>")

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

97
t: @charli3vazquez

Cada checkbox lo recuperamos en forma independiente:


su=self.request.get('check1')
if su=="suma":
resultado=v1+v2
self.response.out.write("El resultado de la " + su + " es " + str(resultado) + "<br>")
Si se encuentra seleccionado el método get retorna el valor de la propiedad value del
control HTML, en caso de no estar seleccionado retorna un string vacío.

98
t: @charli3vazquez

51. Formulario HTML - control textarea (App Engine)


Otro control de uso común es el textarea, a diferencia de un control de tipo "text" nos
permite ingresar muchas líneas de texto.
Confeccionaremos una página que solicite el ingreso del nombre de una persona y en un
control de tipo textarea permitiremos ingresar un comentario. En la página que procesa
los datos mostraremos los datos cargados en los dos controles:
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese su nombre:
<input type="text" name="nombre"><br>
Comentarios<br>
<textarea name="comentarios" rows="10" cols="40"></textarea><br>
<input type="submit" value="enviar"><br>
</form>
</body>
</html>
""")

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
self.response.out.write("Nombre:"+ nom + "<br>")
com=cgi.escape(self.request.get('comentarios'))
self.response.out.write("Comentarios:"+ com + "<br>")
self.response.out.write("</body></body>")

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

La función escape del módulo cgi tiene por objetivo convertir a entidades los caracteres <,
> etc., con esto si se ingresa una marca HTML esta se mostrará y no la interpretará el
navegador.
Recuperamos cada dato y lo mostramos en la página HTML:
nom=cgi.escape(self.request.get('nombre'))
self.response.out.write("Nombre:"+ nom + "<br>")
com=cgi.escape(self.request.get('comentarios'))
self.response.out.write("Comentarios:"+ com + "<br>")

99
t: @charli3vazquez

52. Alta y listado de una base de datos (App Engine)


El almacenamiento de datos utilizando la infraestructura de Google es bastante distinta a
las metodologías de MySql, Oracle, Sql Server etc.
Google utiliza una tecnología llamada 'Bigtable', básicamente es un sistema de
almacenamiento distribuido que permite escalar de forma muy sencilla, evitando que por
ejemplo las consultas de tablas con millones de registros se resientan.
Para hacer uso de esta tecnología debemos importar el paquete db:
from google.appengine.ext import db
Desarrollaremos una aplicación que permita almacenar el nombre de usuario y su clave.
Luego imprimiremos todos los registros almacenados.
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp


from google.appengine.ext import db

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese su nombre:
<input type="text" name="nombre"><br>
Ingrese su clave:
<input type="password" name="clave"><br>
<input type="submit" value="enviar"><br>
</form>
</body>
</html>
""")

class TablaUsuarios(db.Model):
nombre=db.StringProperty()
clave=db.StringProperty()

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
cla=cgi.escape(self.request.get('clave'))
usuario=TablaUsuarios()
usuario.nombre=nom
usuario.clave=cla
usuario.put()
self.response.out.write("<a href=\"listadousuarios\">Listado</a>")
self.response.out.write("</body></body>")

class ListadoUsuarios(webapp.RequestHandler):
def get(self):
self.response.out.write("<html><head></head><body>")
usuarios=db.GqlQuery("select * from TablaUsuarios")
for usu in usuarios:
self.response.out.write("Nombre:" + usu.nombre +"<br>")
self.response.out.write("Clave:" + usu.clave +"<br>")
self.response.out.write("<hr>")
self.response.out.write("<a href=\"\\\">Principal</a>")
self.response.out.write("</body></body>")

100
t: @charli3vazquez

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1),
('/listadousuarios', ListadoUsuarios)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

Veamos todo lo que debemos agregar:


• Debemos importar el paquete db:
• from google.appengine.ext import db
• Debemos declarar una clase que representa una tabla. Esta clase debe heredar de
la clase Model contenida en el paquete db. Definimos dos atributos de tipo
StringProperty. StringProperty es una clase contenida en el paquete db y que
encapsula el manejo de un campo de cadena de caracteres:
• class TablaUsuarios(db.Model):
" " nombre=db.StringProperty()
" " clave=db.StringProperty()

• Para efectuar el alta de un registro en la tabla:


• class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
cla=cgi.escape(self.request.get('clave'))
usuario=TablaUsuarios()
usuario.nombre=nom
usuario.clave=cla
usuario.put()
self.response.out.write("<a href=\"listadousuarios\">Listado</a>")
self.response.out.write("</body></body>")
• Creamos un objeto de la clase Tablausuarios:
• usuario=TablaUsuarios()
• Inicializamos los atributos nombre y clave con los datos extraidos del formulario.
• usuario.nombre=nom
usuario.clave=cla
• Llamamos al método put que confirma los datos previamente cargados:
• usuario.put()
• Para obtener un listado de todos los registros almacenados:
• class ListadoUsuarios(webapp.RequestHandler):
def get(self):
self.response.out.write("<html><head></head><body>")
usuarios=db.GqlQuery("select * from TablaUsuarios")
for usu in usuarios:
self.response.out.write("Nombre:" + usu.nombre +"<br>")
self.response.out.write("Clave:" + usu.clave +"<br>")
self.response.out.write("<hr>")
self.response.out.write("<a href=\"\\\">Principal</a>")
self.response.out.write("</body></body>")
• Creamos un objeto de la clase GqlQuery pasando como parámetro al constructor
los datos a recuperar:
• usuarios=db.GqlQuery("select * from TablaUsuarios")
• Mediante un for recorremos la lista de usuarios y los imprimimos:
• for usu in usuarios:
self.response.out.write("Nombre:" + usu.nombre +"<br>")
self.response.out.write("Clave:" + usu.clave +"<br>")
self.response.out.write("<hr>")

101
t: @charli3vazquez

Como esta aplicación requiere tres páginas luego debemos registrarlas cuando creamos
un objeto de la clase WSGIApplication:
def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1),
('/listadousuarios', ListadoUsuarios)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

102
t: @charli3vazquez

53. Consulta de datos (App Engine)


Confeccionaremos una aplicación que nos permita ingresar el nombre de usuario y nos
recupere y muestre su clave. Tener en cuenta los datos cargados en el concepto anterior.
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp


from google.appengine.ext import db

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese nombre de usuario:
<input type="text" name="nombre"><br>
<input type="submit" value="enviar"><br>
</form>
</body>
</html>
""")

class TablaUsuarios(db.Model):
nombre=db.StringProperty()
clave=db.StringProperty()

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
self.response.out.write("Clave:" + usu[0].clave +"<br>")
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("<a href=\"\\\">Principal</a>")
self.response.out.write("</body></body>")

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1),
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

103
t: @charli3vazquez

Creamos un formulario para ingresar el nombre de usuario a buscar:


class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese nombre de usuario:
<input type="text" name="nombre"><br>
<input type="submit" value="enviar"><br>
</form>
</body>
</html>
""")

El botón submit hace que se ejecute la clase ProcFormulario1:


class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
self.response.out.write("Clave:" + usu[0].clave +"<br>")
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("<a href=\"\\\">Principal</a>")
self.response.out.write("</body></body>")

Primero generamos una consulta a la tabla y le pasamos como parámetro en el campo


nombre el valor rescatado del formulario, debemos utilizar los dos puntos y un uno para
indicar que dicho espacio será remplazado por el segundo parámetro:
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)

La clase GqlQuery tiene un método llamado fetch que retorna todos los registros
generados en la consulta. Al método fetch le pasamos la cantidad de registros que
queremos rescatar y por último accedemos a la primer componente de la lista siempre y
cuando la cantidad de elementos sea mayor a cero.

104
t: @charli3vazquez

54. Borrado de datos (App Engine)


Confeccionaremos una aplicación que nos permita ingresar el nombre de usuario y
efectúe su borrado.. Tener en cuenta los datos cargados en conceptos anterioriores.
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp


from google.appengine.ext import db

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario1" method="post">
Ingrese nombre de usuario a borrar:
<input type="text" name="nombre"><br>
<input type="submit" value="enviar"><br>
</form>
</body>
</html>
""")

class TablaUsuarios(db.Model):
nombre=db.StringProperty()
clave=db.StringProperty()

class ProcFormulario1(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
usu[0].delete()
self.response.out.write("Se borro el usuario<br>")
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("<a href=\"\\\">Principal</a>")
self.response.out.write("</body></body>")

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/procformulario1', ProcFormulario1),
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()
Si lo comparamos con la consulta es prácticamente igual con la salvedad donde en lugar de mostrarlo procedemos a
borrarlo:
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
usu[0].delete()
self.response.out.write("Se borro el usuario<br>")
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
El método delete borrar el registro.

105
t: @charli3vazquez

55. Modificación de datos (App Engine)


Trabajaremos nuevamente con el problema de usuarios. Dispondremos un formulario que
solicite la carga del nombre de un usuario y pasaremos a un segundo formulario donde
mostraremos los datos actuales de dicho usuario. En una tercer página procedemos a
modificar los datos ingresados.
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp


from google.appengine.ext import db

class Formulario1(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="formulario2" method="post">
Ingrese nombre de usuario a modificar:
<input type="text" name="nombre"><br>
<input type="submit" value="Buscar"><br>
</form>
</body>
</html>
""")

class TablaUsuarios(db.Model):
nombre=db.StringProperty()
clave=db.StringProperty()
class Formulario2(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario2" method="post">
Nombre actual:
""")
self.response.out.write("<input type=\"text\" name=\"nombre\" value=\""+usu[0].nombre+"\"><br>")
self.response.out.write("Clave actual:")
self.response.out.write("<input type=\"text\" name=\"clave\" value=\""+usu[0].clave+"\"><br>")
self.response.out.write("<input type=\"hidden\" name=\"nombreoculto\" value=\""+usu[0].nombre+"\">")
self.response.out.write("""
<input type="submit" value="Modificar"><br>
</form>
</body>
</html>
""")
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("</body></body>")

class ProcFormulario2(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nomoculto=cgi.escape(self.request.get('nombreoculto'))
nom=cgi.escape(self.request.get('nombre'))
cla=cgi.escape(self.request.get('clave'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nomoculto)
106
t: @charli3vazquez
usu=usuario.fetch(1)
if len(usu)>0:
usu[0].nombre=nom
usu[0].clave=cla
usu[0].put()
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("<a href=\"\\\">Principal</a>")
self.response.out.write("</body></body>")

def main():
application = webapp.WSGIApplication([('/', Formulario1),
('/formulario2', Formulario2),
('/procformulario2', ProcFormulario2),
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
main()

El segundo formulario debemos inicializar los atributos value de los dos controles text
para que aparezcan cargados inicialmente con los datos actuales.
Por otro lado también es necesario definir un campo oculto donde almacenar el nombre
de usuario actual, ya que si lo modifica no sabremos cual buscar:
class Formulario2(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
self.response.out.write("""
<html>
<head></head>
<body>
<form action="procformulario2" method="post">
Nombre actual:
""")
self.response.out.write("<input type=\"text\" name=\"nombre\" value=\""+usu[0].nombre+"\"><br>")
self.response.out.write("Clave actual:")
self.response.out.write("<input type=\"text\" name=\"clave\" value=\""+usu[0].clave+"\"><br>")
self.response.out.write("<input type=\"hidden\" name=\"nombreoculto\" value=\""+usu[0].nombre+"\">")
self.response.out.write("""
<input type="submit" value="Modificar"><br>
</form>
</body>
</html>
""")
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("</body></body>")

107
t: @charli3vazquez

La tercer página recupera el usuario que ingresó en el primer formulario, pero rescatado
del campo oculto. Procedemos seguidamente a modificar los datos rescatados de la tabla
y confirmamos los nuevos datos llamando al método put:
class ProcFormulario2(webapp.RequestHandler):
def post(self):
self.response.out.write("<html><head></head><body>")
nomoculto=cgi.escape(self.request.get('nombreoculto'))
nom=cgi.escape(self.request.get('nombre'))
cla=cgi.escape(self.request.get('clave'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nomoculto)
usu=usuario.fetch(1)
if len(usu)>0:
usu[0].nombre=nom
usu[0].clave=cla
usu[0].put()
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("<a href=\"\\\">Principal</a>")
self.response.out.write("</body></body>")

108
t: @charli3vazquez

56. Listado, Alta, Baja y Modificación (App Engine)


Ahora plantearemos todos los conceptos vistos para el manejo de una tabla de datos
utilizando el Google App Engine.
Mostraremos un listado con una tabla con todos los nombres de usuarios y claves, dos
hipervínculos uno para poder borrar el usuario y otro para poder modificar el registro. Por
último dispondremos un hipervínculo para llamar a un formulario de alta de usuario.
import cgi
import wsgiref.handlers

from google.appengine.ext import webapp


from google.appengine.ext import db

class TablaUsuarios(db.Model):
nombre=db.StringProperty()
clave=db.StringProperty()

class Listado(webapp.RequestHandler):
def get(self):
self.response.out.write("<html><head></head><body>")
self.response.out.write("<table border=\"1\">")
self.response.out.write("<tr>")

self.response.out.write("<td>Usuario</td><td>Clave</td><td>Borrar</td><td>Modificar&l

t;/td>")
self.response.out.write("</tr>")
usuarios=db.GqlQuery("select * from TablaUsuarios")
for usu in usuarios:
self.response.out.write("<tr>")
self.response.out.write("<td>" + usu.nombre +"</td>")
self.response.out.write("<td>" + usu.clave +"</td>")
self.response.out.write("<td><a href=\"baja?nombre="+usu.nombre+"\">Borra?</a>"+"</td>")
self.response.out.write("<td><a

href=\"formulariomodificacion?nombre="+usu.nombre+"\">Modifica?</a>"+"</td>")
self.response.out.write("</tr>")
self.response.out.write("<tr>")
self.response.out.write("<td colspan=\"4\"><a href=\"formularioalta\">Alta</a></td>")
self.response.out.write("</tr>")
self.response.out.write("</table>")
self.response.out.write("</body></html>")

class FormularioAlta(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="alta" method="post">
Ingrese su nombre:
<input type="text" name="nombre"><br>
Ingrese su clave:
<input type="password" name="clave"><br>
<input type="submit" value="Alta"><br>
</form>
</body>
</html>
""")

class Alta(webapp.RequestHandler):
def post(self):
nom=cgi.escape(self.request.get('nombre'))
cla=cgi.escape(self.request.get('clave'))

109
t: @charli3vazquez
usuario=TablaUsuarios()
usuario.nombre=nom
usuario.clave=cla
usuario.put()
self.redirect("/")

class Baja(webapp.RequestHandler):
def get(self):
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
usu[0].delete()
self.redirect("/")

class FormularioModificacion(webapp.RequestHandler):
def get(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
self.response.out.write("""
<html>
<head></head>
<body>
<form action="modificacion" method="post">
Nombre actual:
""")
self.response.out.write("<input type=\"text\" name=\"nombre\" value=\""+usu[0].nombre+"\"><br>")
self.response.out.write("Clave actual:")
self.response.out.write("<input type=\"text\" name=\"clave\" value=\""+usu[0].clave+"\"><br>")
self.response.out.write("<input type=\"hidden\" name=\"nombreoculto\" value=\""+usu[0].nombre+"\">")
self.response.out.write("""
<input type="submit" value="Modificar"><br>
</form>
</body>
</html>
""")
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("</body></body>")

class Modificacion(webapp.RequestHandler):
def post(self):
nomoculto=cgi.escape(self.request.get('nombreoculto'))
nom=cgi.escape(self.request.get('nombre'))
cla=cgi.escape(self.request.get('clave'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nomoculto)
usu=usuario.fetch(1)
if len(usu)>0:
usu[0].nombre=nom
usu[0].clave=cla
usu[0].put()
self.redirect("/")

def main():
application = webapp.WSGIApplication([('/', Listado),
('/formularioalta',FormularioAlta ),
('/alta',Alta ),
('/baja', Baja),
('/formulariomodificacion', FormularioModificacion),
('/modificacion', Modificacion),
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
110
t: @charli3vazquez

if __name__ == '__main__':
main()
En la función main() debemos inicializar la lista que vincula las URL de las páginas y las clases que se ejecutan:
def main():
application = webapp.WSGIApplication([('/', Listado),
('/formularioalta',FormularioAlta ),
('/alta',Alta ),
('/baja', Baja),
('/formulariomodificacion', FormularioModificacion),
('/modificacion', Modificacion),
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
La clase Listado es la que muestra la raiz del sitio y tiene por objetivo crear una tabla HTML con todos los usuarios
almacenados en la TablaUsuarios. Además de imprimir cada registro disponemos un hipervínculo pasando como
parámetro el nombre de usuario a borrar o modificar:
class Listado(webapp.RequestHandler):
def get(self):
self.response.out.write("<html><head></head><body>")
self.response.out.write("<table border=\"1\">")
self.response.out.write("<tr>")

self.response.out.write("<td>Usuario</td><td>Clave</td><td>Borrar</td><td>Modificar&l

t;/td>")
self.response.out.write("</tr>")
usuarios=db.GqlQuery("select * from TablaUsuarios")
for usu in usuarios:
self.response.out.write("<tr>")
self.response.out.write("<td>" + usu.nombre +"</td>")
self.response.out.write("<td>" + usu.clave +"</td>")
self.response.out.write("<td><a href=\"baja?nombre="+usu.nombre+"\">Borra?</a>"+"</td>")
self.response.out.write("<td><a

href=\"formulariomodificacion?nombre="+usu.nombre+"\">Modifica?</a>"+"</td>")
self.response.out.write("</tr>")
self.response.out.write("<tr>")
self.response.out.write("<td colspan=\"4\"><a href=\"formularioalta\">Alta</a></td>")
self.response.out.write("</tr>")
self.response.out.write("</table>")
self.response.out.write("</body></html>")
La clase FormularioAlta muestra los dos controles text y el botón submit, cuando se presiona dicho botón se procede a
llamar a la URL alta:
class FormularioAlta(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head></head>
<body>
<form action="alta" method="post">
Ingrese su nombre:
<input type="text" name="nombre"><br>
Ingrese su clave:
<input type="password" name="clave"><br>
<input type="submit" value="Alta"><br>
</form>
</body>
</html>
""")

111
t: @charli3vazquez

La clase Alta inicializa un objeto de la clase TablaUsuarios, procede a registrar los datos y
mediante el método redirect redirige a la raiz del sitio (es decir la clase Listado):
class Alta(webapp.RequestHandler):
def post(self):
nom=cgi.escape(self.request.get('nombre'))
cla=cgi.escape(self.request.get('clave'))
usuario=TablaUsuarios()
usuario.nombre=nom
usuario.clave=cla
usuario.put()
self.redirect("/")

Cuando se presiona el hipervínculo "Borra?" en el listado se ejecuta la clase Baja y recibe


como parámetro en el hipervínculo el nombre de usuario a borrar. Recuperamos el
registro, llamamos al método delete y redirigimos nuevamente a la página de listado:
class Baja(webapp.RequestHandler):
def get(self):
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
usu[0].delete()
self.redirect("/")

Cuando se presiona el hipervínculo "Modificación?" se ejecuta la clase


FormularioModificacion, en este recuperamos el nombre de usuario e inicializamos los
controles text y el campo oculto:
class FormularioModificacion(webapp.RequestHandler):
def get(self):
self.response.out.write("<html><head></head><body>")
nom=cgi.escape(self.request.get('nombre'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nom)
usu=usuario.fetch(1)
if len(usu)>0:
self.response.out.write("""
<html>
<head></head>
<body>
<form action="modificacion" method="post">
Nombre actual:
""")
self.response.out.write("<input type=\"text\" name=\"nombre\" value=\""+usu[0].nombre+"\"><br>")
self.response.out.write("Clave actual:")
self.response.out.write("<input type=\"text\" name=\"clave\" value=\""+usu[0].clave+"\"><br>")
self.response.out.write("<input type=\"hidden\" name=\"nombreoculto\" value=\""+usu[0].nombre+"\">")
self.response.out.write("""
<input type="submit" value="Modificar"><br>
</form>
</body>
</html>
""")
else:
self.response.out.write("No existe un usuario con dicho nombre<br>")
self.response.out.write("</body></body>")

112
t: @charli3vazquez

Cuando se presiona el botón modificación del formulario anterior se ejecuta la clase


Modificacion donde se procede a modificar el nombre y clave del usuario. Por último se
redirige a la raiz del sitio:

class Modificacion(webapp.RequestHandler):
def post(self):
nomoculto=cgi.escape(self.request.get('nombreoculto'))
nom=cgi.escape(self.request.get('nombre'))
cla=cgi.escape(self.request.get('clave'))
usuario=db.GqlQuery("select * from TablaUsuarios where nombre=:1",nomoculto)
usu=usuario.fetch(1)
if len(usu)>0:
usu[0].nombre=nom
usu[0].clave=cla
usu[0].put()
self.redirect("/")

113

También podría gustarte