Python (Guia Rapida)
Python (Guia Rapida)
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?
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
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.
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.
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.
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
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'
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 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
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
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>'
imprimirmayor(4,5)
print '<br>'
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
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)
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
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]
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
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
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)
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
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
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
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
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
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
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
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]
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
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
Podemos modificar el valor asociado a una clave mediante una simple asignación:
productos['papas']=5
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
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
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>'
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
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'):
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'
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
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)
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
Luego desde la carpeta donde hemos instalado el Python debemos ejecutarlo con la
siguiente sintaxis:
c:\Python25>python c:\pruebaspython\programa1.py
def funcion2():
modulo1.funcion1()
print 'Función 2'
funcion2()
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
• 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)
• 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']
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
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
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
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()
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
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=[]
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
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
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
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()
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
def graficar(self):
print '<div style="font-size:40px;text-align:'+self.ubicacion+'">'
print self.titulo
print '</div>'
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>'
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>'
52
t: @charli3vazquez
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
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
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
FordK Renault 9
Siempre hacia abajo en la jerarquía hay una especialización (las subclases añaden
nuevos atributos y métodos)
DeAplicacion DeBase
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
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.
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
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()
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
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
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
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
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
67
t: @charli3vazquez
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
69
t: @charli3vazquez
70
t: @charli3vazquez
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
73
t: @charli3vazquez
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
def mostrarnumeros():
for x in range(7):
valor=random.randint(1,100)
print valor
mostrarnumeros()
76
t: @charli3vazquez
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.
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()
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
79
t: @charli3vazquez
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()
81
t: @charli3vazquez
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
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'
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
84
t: @charli3vazquez
handlers:
- url: /.*
script: tutorialya.py
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
86
t: @charli3vazquez
87
t: @charli3vazquez
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.
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
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
92
t: @charli3vazquez
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()
94
t: @charli3vazquez
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
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
98
t: @charli3vazquez
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
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()
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
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
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
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
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
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("/")
112
t: @charli3vazquez
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