Guia Python
Guia Python
com/guias/#guia-python
Gua Python
Python es uno de los lenguajes de programacin multiparadigma, ms potente y que menor curva de
aprendizaje demanda. Con Python ...
Visita Gua Python para mas informacin.
Captulos
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
EL DESAFO
Comenzaremos programando con pocas introducciones. El objetivo, es que desde el
comienzo, tomes tu editor de textos favoritos, te sientes a programar a la par de cada
captulo, ejecutes tus cdigos y aprendas mientras programas.
Al final de cada captulo, encontrars un chuleta con el resumen de lo que habrs
aprendido. Y con tan solo 90 por captulo, en 15 horas estars en condiciones de
programar, como un verdadero Pythonista.
QU NECESITAS?
Un editor de textos
Pues desempolva tu legendario editor de textos, ese favorito que has tenido por
siempre. No tienes un editor de textos favorito? Si tienes un S.O. GNU/Linux chale
un vistazo a esta lista de editores de texto para Linux. En cambio si utilizas Windows,
puedes descargar Notepad++ para Windows
Instalar Python
Si utilizas un SO GNU/Linux, seguramente ya tienes Python instalado. Para comprobarlo,
abre una terminal y simplemente escribe:
python
y pulsa enter.
Nota: Si utilizas MacOS X, el procedimiento para comprobar si tienes Python instalado,
es el mismo.
Aparece un texto como este?
MDULO
Un mdulo es un archivo escrito en Python, con extensin .py
El resultado final tras ejecutar el mdulo que crearemos, ser similar al siguiente:
TIP
Un mdulo python puede ejecutarse mediante una terminal escribiendo:
python nombre_del_archivo.py
class ModeloDePresupuesto:
# Datos comerciales
titulo = "PRESUPUESTO"
encabezado_nombre = "Eugenia Bahit"
encabezado_web = "www.eugeniabahit.com.ar"
encabezado_email = "[email protected]"
# Datos impositivos
alicuota_iva = 21
# Calcular IVA
def calcular_iva(self):
self.monto_iva = self.importe*self.alicuota_iva/100
# Armar el presupuesto
def armar_presupuesto(self):
"""
Esta funcin se encarga de armar todo el presupuesto
"""
txt = '\n'+self.divline+'\n'
txt += '\t'+self.encabezado_nombre+'\n'
txt += '\tWeb Site: '+self.encabezado_web+' | '
txt += 'E-mail: '+self.encabezado_email+'\n'
txt += self.divline+'\n'
txt += '\t'+self.titulo+'\n'
txt += self.divline+'\n\n'
txt += '\tFecha: '+self.fecha+'\n'
txt += '\tEmpresa: '+self.empresa+'\n'
txt += '\tCliente: '+self.cliente+'\n'
txt += self.divline+'\n\n'
txt += '\tDetalle del servicio:\n'
txt += '\t'+self.servicio+'\n\n'
txt += '\tImporte: $%0.2f | IVA: $%0.2f\n' % (
self.importe, self.monto_iva)
txt += '-'*80
txt += '\n\tMONTO TOTAL: $%0.2f\n' % (self.neto)
txt += self.divline+'\n'
print txt
# Mtodo constructor
def __init__(self):
print self.divline
print "\tGENERACIN DEL PRESUPUESTO"
print self.divline
self.set_cliente()
self.set_datos_basicos()
self.calcular_iva()
self.calcular_neto()
self.armar_presupuesto()
# Instanciar clase
presupuesto = ModeloDePresupuesto()
ENTENDIENDO EL CDIGO
Expliquemos el cdigo paso a paso:
ENCODING
Debe ser la primera lnea del cdigo
Sintaxis: # -*- coding: CODIFICACION -*-
CLASES EN PYTHON
class ModeloDePresupuesto:
Una clase es un modelo para definir objetos que pueden realizar las mismas
acciones y poseen caractersticas similares.
En nuestro caso, crearemos decenas, miles y millones (ojal!) de presupuestos.Cada
uno de nuestros presupuestos, ser un objeto que se crear en base al modelo
ModeloDePresupuesto definido en la clase.
CLASES
Una clase se define mediante class NombreDeLaClase:
# Datos comerciales
Todas las lneas comenzadas por # son comentarios en el cdigo fuente. Y aquellos
bloques de texto, encerrados entre tres comillas dobles como ste:
"""
Esta funcin se encarga de armar todo el presupuesto
"""
Tambin son comentarios, pero que adems, sirven para generar la documentacin de
un mtodo.
COMENTARIOS
Para comentar y documentar cdigo en Python utiliza:
# comentario o sino """ documentacin """
# Datos comerciales
titulo = "PRESUPUESTO"
encabezado_nombre = "Eugenia Bahit"
encabezado_web = "www.eugeniabahit.com.ar"
encabezado_email = "[email protected]"
# Datos impositivos
alicuota_iva = 21
nombre_de_la_variable = dato
VARIABLES
variable
_otra_variable_
variable_con_numero_25
VARIABLE_CON_MAYUSCULAS
Variable_Mixta
TIPOS DE DATOS
Las variables pueden contener datos de diversos tipos, por ejemplo:
Cadenas de texto
numero_entero = 100
numero_flotante = 1298.95
variable_con_dato_verdadero = True
variable_con_dato_falso = False
variable_1 = "a"*3
es igual que:
variable_1 = "aaa"
Si has llegado hasta ac sin problemas, eso quiere decir que has cumplido con el primer
paso para aceptar el reto de aprender Python programando. No te pierdas el segundo
captulo.
5.
6.
presupuesto = ModeloDePresupuesto()
7.
8.
self.set_datos_basicos()
9.
10.
11.
12.
13.
self.seleccionar_plan()
File "presupuesto.py", line 59, in seleccionar_plan
elegir_plan = int(elegir_plan)
ValueError: invalid literal for int() with base 10: ''
>>>
14.
1. Copia el error completo, tal cual se muestra y colcalo como referencia en tu post
2. Copia tu cdigo en algn sitio que te permita compartir y corregir cdigo
pblicamente, como por ejemplohttp://pastebin.lugmen.org.ar/
3. Coloca en tu post, un enlace hacia el cdigo del Pastebin
DEFINIR FUNCIONES
Para definir una funcin, se escribe:
def nombre_de_la_funcion(parmetros):
# aqu escribimos el cdigo que realiza la accin que definimos
Los parmetros son datos contenidos en variables (una o ms), que la funcin
necesitar para realizar la accin. No siempre son necesarios. En nuestro caso, el
parmetro self indica que la funcin requerir de los atributos contenidos en la clase (los
que ya vimos recientemente).
Por ejemplo: self.empresa est llamando al atributo empresa de la clase.
Mientras que mediante: self.empresa = 'Maestros del Web', le estoyasignando el valor
Maestros del Web al atributo empresa de la clase (recuerda que un atributo es una
variable).
REFERENCIA A PROPIEDADES
Cuando necesito recurrir a un atributo de la clase, dentro de una funcin,
escriboself.nombre_del_atributo
Todo el cdigo contenido dentro de una funcin (es decir, el que est debajo de la
definicin de la funcin, con tabulado), se llama algoritmo, y es el que indicar a la
funcin, qu es lo que debe hacer.
Luego, asignamos esa variable (importe) como valor del atributo importe, pero esta vez,
es el atributo importe de la clase:
self.importe = float(importe)
FUNCIONES NATIVAS
al igual que raw_input() es una funcin nativa de Python. Su accin consiste en
convertir en nmero flotante (es decir, con decimales), el nmero que le sea pasado
como parmetro.
Float()
OPERADORES MATEMTICOS
Para
Para
Para
Para
Para
Para
Para
sumar, utilizamos +
restar utilizamos dividir flotantes utilizamos /
dividir enteros utilizamos //
multiplicar utilizamos *
obtener el resto de una divisin utilizamos %
exponenciar utilizamos **
El operador matemtico + no solo sirve para sumar nmeros. Tambin sirve para
concatenar cadenas de texto (es decir, unirlas). Fjate esta lnea:
txt = '\n'+self.divline+'\n'
txt += '\t'+self.encabezado_nombre+'\n'
Estoy diciendo aqu, que a la variable txt de antes, le agregue ahora, todo lo dems:
La cadena de texto \t (\t significa tabular)
el texto contenido en el atributo encabezado_nombre de la clase
ms finalmente, la cadena de salto de lnea \n
Haz visto lo difcil de entender que parece este cdigo? Pues Pirdele el miedo! Es
mucho ms sencillo de lo que parece.
Python nos da la posibilidad de utilizar comodines en nuestras cadenas de texto, para
poder reemplezar datos, que necesiten un formato especial.
El comodn es el signo del porcentaje %.
A este comodn, le segurir un patrn, que identifique el tipo de dato (formato) que
queremos darle al dato.
Por ejemplo: %0.2f, est indicando que en ese lugar (en vez del comodn y el patrn),
debe ir un nmero flotante con dos decimales. Es decir que el
patrn 0.2fsignifica nmero con dos decimales.
Hasta all, entonces, asignamos comodines y patrones. Pero luego, hay que decirle a
Python qu datos debe formatear. Para ello, luego de la cadena de texto, escribimos
un comodn % segudio de un espacio, y entre parantsis y separados por coma,
las variables que contienen los datos a reemplazar.
Vemoslo con otro ejemplo:
a = 10
b=5
resultado = "%0.2f y %0.2f son dos nmeros flotantes" % (a, b)
print txt
Cuando quieres mostrar texto en la pantalla, solo debes escribir print y lo que desees
mostrar.
Pueden ser tanto los datos contenidos en una variable (como en nuestro cdigo) o
directamente un dato, como en los siguientes ejemplos:
print 25
print "Cadena de texto"
CREACIN DE OBJETOS
# Instanciar clase
presupuesto = ModeloDePresupuesto()
Recuerdas cuando hablamos de la diferencia entre clases y objetos? Decamos que una
clase es un modelo que sirve como base para crear un objeto.
Pues bien. Es hora de crear nuestro nuevo objeto: un nuevo presupuesto.
CREAR OBJETOS
Para instanciar una clase y crear un nuevo objeto se escribe:
nombre_del_objeto = NombreDeLaClase()
Con lo anterior, hemos iniciado un nuevo objeto que ser creado segn el modelo
NombreDeLaClase.
def __init__(self):
notas?
Pero el nombre de la funcin __init__, Python lo reserva para los mtodos constructores.
def __init__(self):
# en las siguientes lneas, imprimo texto en pantalla
print self.divline
print "\tGENERACIN DEL PRESUPUESTO"
print self.divline
self.set_cliente() # aqu seteo los datos del cliente
self.set_datos_basicos() # aqu los del presupuesto
self.calcular_iva() # calculo el iva
self.calcular_neto() # calculo el importe total
self.armar_presupuesto()
NUEVO DESAFO
En el captulo de hoy, nos extendimos en cuestiones tericas sobre referencias del
lenguaje que utilizamos en nuestro primer ejemplo. Aprendimos muchas cosas nuevas
como:
Definir funciones
Utilizar funciones nativas de Python
Operadores matemticos
Dar formato a cadenas de texto
Entre otras
Pero algo muy importante que aprendimos es a perderle el miedo a los errores de
cdigo y tratar de resolverlos. Y si quieres convertirte en verdadero profesional,
te invito a sumarte a un nuevo desafo. A continuacin, encontrars un cdigo fuente.
Este cdigo, utiliza algunas cosas que ya hemos aprendido. Adems, no te dir donde,
pero tiene algn que otro error.
EL RETO DE HOY
1. Copia el siguiente cdigo en un archivo, con el nombre que se te ocurra
2. Ejectalo en una terminal (ya sabes como)
3. Ve si puedes encontrar el (o los) error(es) y corregirlo(s)
4. Si encuentras el(los) error(es), NO lo postees as das tiempo a los dems a hacer lo
mismo. Pero, puedes contar que los encontraste y dar pistas para ayudar a otros.
5. Si NO encuentras los errores, puedes postear preguntando a quienes s los hayan
encontrado
resultado = numero//self.divisor
return resultado
obj = Modelo()
txt = self.leer_plantilla(self.txt)
html = self.leer_plantilla(self.html)
Muy buenas Pythoneros! estamos aqu con la tercera entrega de Aprender Python
Programando.
El desafo de hoy, no es apto para personas impresionables, pues Bienvenid@s a
un nuevo reto para corajud@s!
Qu haremos? Hoy agregaremos ms funcionalidad a nuestro mdulo Presupuesto.
1. Disearemos una plantilla HTML y otra plantilla TXT para nuestro presupuesto, as,
no solo se ver ms agradable, sino que adems, ser ms fcil modificarlo
2. Comenzaremos a colocar una numeracin incremental automtica, a cada nuevo
presupuesto que generemos
3. Podremos elegir entre guardar el archivo en formato HTML o mostrarlo en pantalla
4. Crearemos una lista de precios Basta de agregar tantos datos manualmente!
Comencemos!
ARCHIVOS NECESARIOS
Para hacerte de los archivos necesarios, sigue los temes de esta lista, paso por paso:
1. Crea una carpeta llamada capitulo3
Aqu almacenaremos todos los archivos del programa
2. Dentro de la carpeta capitulo3, crea una subcarpeta llamadapresupuestos
Aqu se guardarn todos los presupuestos generamos en formato HTML (los que
decidamos guardar)
3. Dentro de la carpeta capitulo3, crea otra subcarpeta llamada templates
Aqu guardaremos la plantilla HTML y otra con formato solo texto (TXT)
4. Dentro de la carpeta templates guarda los archivos template.html ytemplate.txt
Pulsa en cada archivo para descargarlos desde Launchpad. Estas sern, nuestras dos
plantillas
5. Dentro de la carpeta capitulo3, crea un archivo llamado contador.txt
Ser la gua que utilizaremos para calcular incrementalmente nuestros nmeros de
presupuesto.
6. Abre el archivo contador.txt, edita el contenido (est vaco), escribe 100 y guarda los
cambios
Inicializamos el contador en 100. Nuestro primer presupuesto, obtendr el nmero 101 y
as sucesivamente de forma incremental.
7. Dentro de la carpeta capitulo3, guarda el mdulo presupuesto.py(modificado)
Explicaremos todos los cambios nuestro mdulo, a lo largo del captulo.
[-]capitulo3
|_ [+]presupuestos
|_ [-]templates
|_ template.html
|_ template.txt
|_ contador.txt
|_ presupuesto.py
# Tupla
# Lista
# Lista
# Diccionario
Como vers, hemos agregado cuatro nuevas propiedades de clase a nuestro mdulo.
Pero, el tipo de datos, no es ninguno de los que ya hemos visto! Pertenecen a tres
nuevos tipos de datos: tuplas, listas y diccionarios.
Tanto las tuplas, como listas y diccionarios, son una forma de almacenar varios datos
diferentes, de diversos tipos (cadenas de texto, enteros, flotantes, booleanos) en
una misma variable.
El orden en el cual estos datos se especifican dentro de la variable, se denomina
ndice, teniendo el primer dato un ndice 0 (cero), el siguiente 1, y as
incrementalmente.
Veamos estos tres nuevos tipos de datos en detalle:
TUPLAS
Para acceder a uno de esos datos, se realiza por su nmero de ndice: texto es ndice 0;
100 es ndice 1; 7.25 es ndice 2; False es ndice 3 y,True es ndice 4
Para acceder a una variable por su nmero de ndice, ste se escribe entre corchetes: print
mi_tupla[2] imprimir 7.25 mientras que print mi_tupla[4] imprimir True
En nuestro cdigo, la tupla planes lo que est haciendo es almacenar el nombre de los
tres tipos de planes que ofreceremos a nuestros clientes.
LISTAS
Para acceder a uno de esos datos, se realiza por su nmero de ndice al igual que con las
tuplas: print mi_lista[2] imprimir 7.25 mientras que print mi_lista[4] imprimir True
A diferencia de las tuplas, los datos contenidos en una lista PUEDEN modificarse,
accediendo a ellos por su nmero de ndice:
mi_lista[0] = 'otro contenido'
En nuestro cdigo, hemos creado una lista para cada tipo de plan, donde el ndice 0
(cero) ser la descripcin del servicio y el ndice 1, el precio de ese servicio.
DICCIONARIOS
lista_precios = {'corporativo':corporativo,
'personal':personal,
'mantenimiento':mantenimiento}
diccionario = {'nombre_de_clave':'texto',
'numero_entero':100,
'numero_flotante':7.25,
'falso':False,
'verdadero':True}
PARA SABER
Las tuplas, listas y diccionarios, admiten tambin como valores, otras tuplas, listas y/o
diccionarios!
Hasta aqu vemos como acceder uno a uno a los datos de una tupla, lista o diccionario.
Pero qu sucede si queremos recorrerlos todos y no sabemos cuantos ndices tiene?
Para ello, utilizaremos una estructura de control llamada bucle for.
EL BUCLE FOR
En nuestro cdigo, la estructura de control que estamos implementado se
denomina bucle for y es la que se encuentra representada por el siguiente bloque de
cdigo (lneas 44, 45 y 46):
Por qu bucle? Porque es una accin que no se ejecuta solo una vez, sino que lo har
hasta que una condicin deje de cumplirse.
Qu condicin? la que restringe la ejecucin de ese bucle. En nuestro caso, la
condicin estar delimitada por la cantidad de planes en nuestra tupla planes: for plan in
self.planes:
elegir_plan = raw_input(texto_a_mostrar)
raw_input() retorna el valor ingresado, como cadena de texto. Pero necesito utilizarlo
como nmero de ndice! entonces, convierto ese valor a entero, con otra funcin nativa
de Python: int()
elegir_plan = int(elegir_plan)
self.plan = self.planes[elegir_plan]
Lo que estoy haciendo, es traer el nombre (valor) del tipo de plan almacenado en la
tupla planes.
Los datos del servicio a cotizar como descripcin y precio, los he guardado en el
diccionario lista_precios. Recordemos que al diccionario se accede por nombre de clave.
ste, lo obtuve antes haciendo self.planes[elegir_plan].
Entonces, accedo al diccionario para traerme la lista, que contiene descripcin del
servicio e importe, utilizando como clave, el nombre del plan:
datos_servicio = self.lista_precios[self.planes[elegir_plan]]
self.servicio = datos_servicio[0]
importe = datos_servicio[1]
self.importe = float(importe)
CHULETA #1
Con nuestra lista de precios hemos aprendido sobre:
Tuplas
Crear
Acceder
Modificar
No se puede!
Listas
Crear
Acceder
Modificar
Diccionarios:
Crear
Acceder
Modificar
dict['clave'] = 'Texto'
Imprimir:
Flor de rosa
Flor de jazmn
Flor de crisantemo
Convertir un literal a entero:
literal = '234'
int(literal)
NUEVO RETO
Mirando el mtodo que se encuentra en la lnea 72 de nuestro mdulo Presupuesto:
contador.write(nuevo)
contador.close()
# sobreescribo el nmero
# cierro contador
self.numero_presupuesto = nuevo
Leyendo los comentarios a la derecha de cada lnea Alguien se anima a explicar por
qu luego de abrir un archivo, leerlo y antes de escribirlo se
utilizacontador.seek(0) para "mover el cursor al byte 0"?
Vamos a ver esto de forma detallada en el siguiente captulo, pero quin se anima a
tratar de deducirlo y explircarlo?
TRABAJANDO CON TEMPLATES, ARCHIVOS Y CONDICIONALES
Abrir un archivo
Leer un archivo
Escribir/sobrescribir un archivo
Cerrar un archivo abierto
Para abrir un archivo se realiza mediante la clase open() de Python, cuyo mtodo
constructor recibir como primer parmetro, la ruta del archivo a ser abierto y
como segundo parmetro, el modo de apertura (es decir, el objetivo para el cual lo
abrimos: escritura, solo lectura, lectura y escritura, etc.).
En la lnea 103 abrimos un archivo para leerlo:
Tanto con la variable filename como con la variable contador y presupuesto, lo que
estamos haciendo es crear un objeto archivo, para luego utilizar los mtodos
necesarios:
para leer el contenido de un archivo;
objeto.write('nuevo contenido') para escribir en el archivo;
objeto.seek(numero_de_byte) para mover el cursor hacia el byte indicado en el archivo;
y objeto.close() para cerrar el archivo.
objeto.read()
Cuando leemos el contenido de un archivo con el mtodo read(), ste, retorna una
cadena de texto. Si el contenido del archivo que estamos leyendo, es un nmero
(como en nuestro contador.txt), obtendremos el literal de ese nmero y para poder
utilizarlo como nmero (por ejemplo, para hacer operaciones matemticas), ser
necesario convertirlo a entero o flotante, como en la lnea 75, donde
medianteint() convertimos el literal ledo a nmero entero:
ultimo_num = int(contador.read())
IMPORTAR MDULOS
Importar un mdulo significa incluir un archivo .py dentro de otro, para utilizar sus
mtodos.
Para importar todo un mdulo, se escribe:
import modulo
Para importar varias clases de un mdulo, se separan los nombres de las clases con
comas:
form modulo import ClaseUno, ClaseDos, ClaseVeinte
En nuestro ejemplo:
XKCD This work is licensed under a Creative Commons Attribution-NonCommercial 2.5 license.
txt = Template(txt).safe_substitute(diccionario)
html = Template(html).safe_substitute(diccionario)
El constructor de esta clase (es decir, el mtodo __init__) recibe como parmetro una
plantilla: Template(txt) y Template(html)
Esta plantilla, debe tener ciertos comodines que indicarn los datos que deben ser
reemplazados.
Estos comodines se denominan identificadores.
Para escribir un signo $ sin hacer referencia a un identificador, debe escaparse con otro
signo $. Esto: $$ imprime $, mientras que$nombre_identificador ser reemplazado por
un identificador cuyo nombre sea nombre_identificador
UN EJEMPLO SIMPLE
La salida ser:
Este es el Identificador Uno y este $id2
diccionario = dict(nombre=self.encabezado_nombre,
web=self.encabezado_web,
email=self.encabezado_email,
titulo=self.titulo,
numero=self.numero_presupuesto,
fecha=self.fecha,
empresa=self.empresa,
cliente=self.cliente,
plan=self.plan,
servicio=self.servicio,
precio=self.importe,
iva=self.monto_iva,
total=self.neto,
limite=self.vencimiento)
Aqu lo que hicimos, fue armar un diccionario de datos con la clase dict() de Python.
Podramos haber colocado estos pares de clave=valor dentro del
mtodosafe_substitute() directamente. Pero para hacerlo ms legible y prolijo, creamos
este diccionario de datos, que luego lo pasamos como parmetro a safe_substitute():
txt = Template(txt).safe_substitute(diccionario)
html = Template(html).safe_substitute(diccionario)
Dnde plantilla debe ser el contenido del archivo ledo previamente ydiccionario el
creado mediante la clase dict()
if respuesta.lower() == 'n':
print txt
# si en cambio el usuario indica "n"
elif respuesta.lower() == 's':
filename = 'presupuestos/'+self.numero_presupuesto+'.html'
presupuesto = open(filename, 'w') # Creo el archivo
presupuesto.write(html)
presupuesto.close()
# escribo el contenido
# cierro el archivo
si condicion X se cumple:
hacer esto
sino, si condicion Y se cumple:
hacer esto otro
sino (si no se cumple ni X ni Y):
hacer tal otra cosa
si condicin X se cumple:
hacer esto
# fin
Ejemplo:
a = 10
if a == 10:
print 'a es igual a 10'
a = 10
if a == 10:
print 'a es igual a 10'
else:
print 'a no es igual a 10'
Con elif se pueden tomar tantas decisiones como condiciones quieran evaluarse::
a = 10
if a == 10:
print 'a es igual a 10'
elif a == 9:
print 'a es igual a 9'
elif a == 75:
print 'a no es ni 9 ni 10, es 75'
a = 10
if a == 10:
print 'a es igual a 10'
elif a == 9:
print 'a es igual a 9'
elif a == 75:
print 'a no es ni 9 ni 10, es 75'
else:
print 'a no es ni 9, ni 10 ni 75. Es un valor que no evalu'
Solo espero una de esas dos respuestas. Es necesario evaluar la respuesta ingresada.
if respuesta.lower() == 'n':
if respuesta.lower() == 'n':
print txt
RECURSIVIDAD
Cuando un mtodo se llama a s mismo, se denomina recursividad. sto, genera una
iteracin (un bucle) del mtodo en s mismo. Por lo tanto, se debe ser muy cuidadoso al
emplear una llamada recursiva y hacerlo solo cuando sea estrictamente necesario y
no se corra el riesgo de caer en un bucle infinito.
OPERADORES RELACIONALES
== Igual que
!= Distinto que
<
Menor que
>
Mayor que
Usos:
if
if
if
if
if
if
a
a
a
a
a
a
== b # si a es igual que b
!= b # si a es distinto que b
> b # si a es mayor que b
>= b # si a es mayor o igual que b
< b # si a es menor que b
<= b # si a es menor o igual que b
OPERADORES LGICOS
and (y)
or
(o)
not (no)
Los operadores lgicos permitirn evaluar mltiples condiciones en una misma instancia:
si condicion_1 and condicion_2 or condicion_3
and evala si todas las condiciones se cumplen, es decir, que todas las condiciones
deben retornar True (verdadero)
a = 10
b=5
if (a == 10) and (b != 10):
print 'Hola Mundo'
a = 10
b=5
if (a != 10) and (b == 5):
print 'Hola Mundo'
a = 10
b=5
if (a != 10) or (b == 5):
print 'Hola Mundo'
a = 10
b=5
if not a == 10:
print 'Hola Mundo'
lower()
# edades
Ana = 43
Juan = 43
Pedro = 8
Roberto = 12
Melisa = 15
Helena = 3
if (Ana == Juan) and ((Helena < Melisa) or (Melisa < Roberto)) and not (Pedro > Roberto):
print 'Veo condicionales hasta en la sopa!'
else:
print 'Soar con condicionales'
EL DESAFO
Modificando nicamente un operador lgico, debes lograr que se imprima la frase
Soar con condicionales. No se puede quitar ningn operador. Solo puede cambiarse
un operador lgico por otro.
QU HAREMOS HOY?
1. Agregaremos nuevas funcionalidades al programa y mejoraremos otras
existentes:
o
Haremos que tanto la fecha actual como la de caducidad de nuestro presupuesto,
se calculen de forma automtica.
o
Al finalizar la carga de un presupuesto, tendremos la opcin de abrirlo directamente
en el navegador para visualizarlo.
o
Mejoraremos el funcionamiento de la eleccin del plan a presupuestar, validando
que el dato ingresado sea correcto. De no serlo, se nos volver a pedir que
ingresemos una opcin.
2. Haremos un refactoring del cdigo, a fin de:
o
Hacer nuestro cdigo ms legible.
o
Lograr que el programa tenga un mejor rendimiento.
o
Facilitar el mantenimiento y evolucin del sistema.
INGREDIENTES
HELPER
En la programacin, un helper es una forma de agrupar funciones de uso comn,
destinadas a servir de ayuda a otros procesos.
Un Helper se compone de funciones genricas que se encargan de realizaracciones
complementarias, aplicables a cualquier elemento de un sistema.
Es importante mencionar, que un Helper, pueden ser, tanto funciones sueltas como la
abstraccin de un objeto helper (es decir, una clase).
class Helper:
def helper_1(self):
# algoritmo
def helper_2(self):
# algoritmo
def helper_1(self):
# algoritmo
def helper_2(self):
# algoritmo
5. import helpers
help(helpers)
def mi_funcion():
"""Aqu la documentacin"""
Incorrecto:
def mi_funcion():
""" Aqu la documentacin """
def mi_funcion():
"""
Aqu la documentacin
"""
def mi_funcion():
"""
Aqu la documentacin
"""
Una buena documentacin, debe incluir la accin que realiza, lo que retorna y
los parmetros que acepta.
En estos casos, se utilizan docstrings multilnea, siguiendo el prximo esquema:
"""Hace X retorna Y
Argumentos:
arg1 -- descripcin de arg1
arg2 -- descripcin de arg2
"""
def get_fecha_actual():
hoy = datetime.datetime.now()
fecha_actual = hoy.strftime("%d/%m/%Y")
return fecha_actual
def sumar_dias(dias=0):
fecha = datetime.datetime.now() + datetime.timedelta(days=dias)
nueva_fecha = fecha.strftime("%d/%m/%Y")
return nueva_fecha
import datetime
hoy = datetime.datetime.now()
La funcin strftime() convierte la fecha a cadena de texto, con el formato pasado como
parmetro:
hoy.strftime("%d/%m/%Y")
Con la funcin timedelta() podemos calcular fechas, ya sea restando, como sumando,
dividiendo o multiplicando N cantidad de das:
EL MDULO DATETIME
Este mdulo, nativo de Python, nos permite realizar diferentes manejos con fechas.
Para utilizar el mdulo debe importarse:
import datetime
datetime.datetime.now()
Donde N debe ser un nmero entero (representa la cantidad de das a sumar, restar,
multiplicar o dividir). Sumar (+), Restar (-), dividir (//), multiplicar (*).
Dar formato a una fecha:
fecha.strftime(string_formato)
Donde string_formato ser la cadena de texto que defina el formato deseado, con las
directrices indicadas.
Para dar diversos formatos de fechas, las directrices disponibles, son las siguientes:
REFACTORING
Hemos realizado algunos cambios a nuestro cdigo, pero que sin embargo, no se reflejan
al momento de utilizar el programa.
REFACTORING
Refactoring (o refactorizacin / refactorizar) es una tcnica de programacin, que
consiste en efectuar cambios al cdigo fuente, sin alterar el funcionamiento
externo del programa.
EXCEPCIONES
Una excepcin es un error inesperado que se produce durante la ejecucin de un
programa.
Las excepciones en Python, cuentan con dos instancias obligatorias: try y except,
donde el cdigo contenido en try intentar ejecutarse, y se falla, el error ser capturado
por except, lanzando otra accin.
try:
# intentar esto
except:
# Si lo anterior falla, capturar el error
# y hacer esto otro
def probar_excepciones():
dato = raw_input("Ingresar numero para pasar, letra para fallar: ")
try:
int(dato)
except:
print "ejecutando execpt, try ha fallado"
else:
print "ejecutando else, try se ha logrado"
finally:
print "finally se ejecuta siempre"
try:
elegir_plan = int(elegir_plan)
self.plan = self.planes[elegir_plan]
except:
except TipoDeExcepcion:
except TipoExcepcion1:
#...
except (TipoExcepcion2, TipoExcepcion3):
#...
except TipoExcepcion4:
#...
Una alternativa muy til, es recoger la descripcin del error para poder mostrarla:
else:
datos_servicio = self.lista_precios[self.planes[elegir_plan]]
self.servicio = datos_servicio[0]
importe = datos_servicio[1]
self.importe = float(importe)
if respuesta.lower() == 's':
webbrowser.open(BASE_DIR + "/" + archivo)
UN NUEVO DESAFO
En este captulo, hemos aprendido dos conceptos fundamentales, indispensables en la
vida de cualquier programador experto: la tcnica de refactoring y elmanejo de
excepciones. Y ninguna de las dos, es poca cosa, ni mucho menos, pueden etiquetarse
como bsicas. Los programadores que recin se inician (e incluso, puedo asegurarles
que muchos programadores con aos de experiencia), no suelen refactorizar el cdigo
fuente de sus programas, y son muy pocas las veces que manejan excepciones dentro
del cdigo.
La tarea que nos toca hoy, es animarnos a programar como verdaderos
profesionales. Cul es el desafo entonces?
Hacer un refactoring de TODOS los archivos de nuestro sistema
Cmo? Muy simple. Python, tiene una serie de recomendaciones para la escritura de
cdigo, llamada Style Guide for Python Code, definida en la PEP 8 de la cual
hemos hablado sutilmente en captulos anteriores -. Los verdaderos programadores
Python, debemos respetar esta gua de estilos al pie de la letra, ya que hacerlo,
nos garantiza que nuestro cdigo pueda ser fcilmente mantenible, legible, evolutivo y
por sobre todo, es una forma de respetarnos entre colegas. Escribir cdigo
desprolijo o con estilo propio, dificulta la lectura. Ergo, hace que entender el cdigo
escrito por otro programador, nos lleve ms trabajo.
Entonces:
1. Lee las PEP 8 (en ingls) o las PEP 7 (disponibles en espaol)
2. Revisa cuidadosamente los archivos constantes.py, helpers.py y sobre todo,
presupuesto.py (tiene violaciones a las PEP 8 de forma ex-profesa)
3. Haz todas las modificaciones que sean necesarias, para estandarizar el cdigo fuente
segn las PEP
Es muy importante que aproveches este reto para trabajar en equipo. Puedes
utilizar los comentarios para compartir con otros programadores, las lneas de cdigo
que hayas refactorizado, as como tambin, intercambiar opiniones sobre cmo sera
mejor refactorizar tal o cual otra lnea. Aprovecha esto para entrenarte! La
capacidad para trabajar en equipo, no solo la da la buena predisposicin, sino tambin la
prctica y el intercambio con otros programadores. Y ten en cuenta, que a la hora de
buscar trabajo, sumar puntos a tus fortalezas.
HERENCIA
En Programacin Orientada a Objetos, la herencia es la relacin existente entre
dos o ms clases. La herencia marca una relacin de jerarqua entre objetos, en la
cual, una clase principal (madre) puede ser heredada por otras
secundarias (hijas), las cuales adquieren por herencia los mtodos y atributos de la
primera (clase principal).
El objetivo de hoy, es utilizar esta caracterstica de la POO (la herencia), para lograr
dos tipos de presupuesto:
1. El presupuesto tradicional que venimos generando.
2. Un presupuesto extendido, que emita los recibos de pagos correspondientes, calculando el
monto de adelanto y su resto.
ARCHIVOS NECESARIOS
Utilizaremos todos los archivos disponibles en la carpeta capitulo6. En esta carpeta,
encontraremos las siguientes novedades:
=====================================================
===========================
$titulo N $numero/1
=====================================================
===========================
________________________
$nombre
$web
=====================================================
===========================
=====================================================
===========================
$titulo N $numero/2
=====================================================
===========================
________________________
$nombre
$web
=====================================================
===========================
class PresupuestoConRecibo(Presupuesto):
def __init__(self):
Presupuesto.__init__(self)
self.adelanto = 40
self.titulo = "RECIBO"
self.generar_recibo()
def calcular_pagos(self):
"""Calcula el monto correspondiente al adelanto y resto del trabajo"""
total = self.neto
self.pago_1 = total * self.adelanto / 100
self.pago_2 = total - self.pago_1
def generar_recibo(self):
"""Genera los recibos para entregar al cliente"""
self.calcular_pagos()
txt = leer_archivo(TEMPLATE_RECIBO)
diccionario = dict(titulo=self.titulo,
numero=self.numero_presupuesto,
ciudad=CIUDAD,
cliente=self.cliente,
moneda=MONEDA_DENOMINACION,
pago_1=self.pago_1,
nombre=Presupuesto.encabezado_nombre,
web=Presupuesto.encabezado_web,
pago_2=self.pago_2)
txt = Template(txt).safe_substitute(diccionario)
self.guardar_recibo(txt)
Argumentos:
"""
RUN.PY
Este archivo, ser el que desde ahora en ms ejecutemos de la lnea de comandos en
lugar de presupuesto.py. Veremos como, pasndole un parmetro determinado por lnea
de comando, se encargar de ejecutar uno u otro mdulo (Presupuesto o
PresupuestoConRecibo).
modelo = sys.argv[1]
if modelo == 'basico':
presupuesto = Presupuesto()
elif modelo == 'recibo':
presupuesto = PresupuestoConRecibo()
else:
print "Argumentos no vlidos"
.
El archivo Guia_Python.nja ser opcionalmente necesario, si deseas utilizar Ninja-IDE
para esta etapa del proyecto. El archivo .nja te evitar configurar el proyecto, pero es
opcional su descarga.
ARCHIVOS MODIFICADOS
presupuesto.py
- Cdigo estandarizado segn PEP 8
- Se elimina adems, la instancia a Presupuesto incorporndola en run.py
- Se limpia el mtodo __init__()
- Ahora, Presupuesto hereda de object (ver explicacin ms adelante)
constantes.py
- Incorpora nuevas constantes
LA HERENCIA EN PYTHON
En Python, para indicar que una clase hereda de otra, se utiliza la siguiente sintaxis:
class NombreDeLaClaseHija(NombreDeLaClaseMadre):
Cuando una clase es principal (una clase madre), debe heredar de object:
class Presupuesto(object):
Nuestro nuevo mdulo recibo.py, hereda todos los atributos y mtodos de presupuesto:
class PresupuestoConRecibo(Presupuesto):
Adems, de poder definir mtodos y atributos propios que extendern las caractersticas
de Presupuesto.
NombreDeLaClase.nombre_del_atributo
self.nombre_del_atributo
class ClaseMadre(object):
atributo_de_clase = 'valor'
def __init__(self):
self.metodo()
def metodo(self):
self.atributo_del_objeto = 'otro valor'
print ClaseMadre.atributo_de_la_clase
print self.atributo_de_la_clase
class ClaseHija(ClaseMadre):
def __init__(self):
ClaseMadre.__init__(self)
print self.atributo_del_objeto
class ClaseMadre(object):
atributo_de_clase = 'valor'
def __init__(self):
self.metodo()
def metodo(self):
self.atributo_del_objeto = 'otro valor'
def segundo_metodo(self):
print 'Hola Mundo'
class ClaseHija(ClaseMadre):
def __init__(self):
ClaseMadre.__init__(self)
self.otro_metodo()
def otro_metodo(self):
print ClaseMadre.atributo_de_clase
print self.atributo_del_objeto
self.segundo_metodo()
import sys
modelo = sys.argv[1]
sys es un mdulo estndar de Python que provee de funciones especficas del sistema
(ampliar informacin).
argv recoge una lista de parmetros que son pasados por lnea de comandos cuanso se
ejecuta mediante python archivo.py argumentos.
El primer elemento de la lista argv, es decir argv[0] es el nombre del archivo. En nuestro
cdigo, accedemos directamente al segundo elemento de la lista:sys.argv[1] el cul
nos dir qu opcin hemos elegido. Si optamos por bsico, crearemos una instancia de
Presupuesto()
if modelo == 'basico':
presupuesto = Presupuesto()
else:
print "Argumentos no vlidos"
EL DESAFO DE HOY
Nos estamos poniendo cada vez ms exigentes con nuestro cdigo. En el captulo
anterior, nos toc hacer un refactoring para estandarizar el cdigo con la normativa de la
PEP 8.
En el captulo de hoy, el reto es doble.
DESAFO #1:
Prueba a ejecutar el mdulo run.py sin pasar ningn argumento:
python run.py
DESAFO #2
El nuevo mdulo recibo.py posee un mtodo para guardar el recibo generado, muy
similar al mtodo que utiliza el mdulo Presupuesto para guardar el presupuesto en un
archivo HTML. Muchas lneas de cdigo se repiten, lo cual, incurre en una redundancia
innecesaria que puede ser evitada. Qu ideas se te ocurren para solucionar este
cdigo redundante? No es necesario que escribas cdigo. El objetivo es que entre
todos razonemos y hagamos una lluvia de ideas que nos ponga en prctica.
TEST UNITARIOS
Los test unitarios representan un mecanismo indispensable, para probar el
funcionamiento individual, de cada parte del cdigo, previniendo que el agregado de
nuevo cdigo, haga fallar el existente.
Antes de comenzar, ser necesario descargar los archivos actualizados del captulo
anterior.
A continuacin un resumen de los cambios que veremos:
capitulo6/constantes.py
capitulo6/helpers.py
Refactoring: guardar_presupuesto()
Refactoring: guardar_recibo()
DOCTEST
doctest es un mdulo nativo de Python, que busca en los comentarios de nuestro
cdigo, fragmentos que se vean como sesiones del intrprete interactivo de Python, y
procede a ejecutar dichos fragmentos, verificando que resulten como se le ha indicado.
Esto significa, que importando el mdulo doctest, ste, buscar en los comentarios de
nuestro cdigo, todo fragmento que represente al interprete interactivo, para luego
ejecutarlo. Por ejemplo:
import doctest
Argumentos:
a -- primer sumando
b -- segundo sumando
Test:
>>> sumar_dos_numeros(25, 10)
35
>>> sumar_dos_numeros(30, 20)
50
"""
resultado = a + b
print a + b
if __name__ == "__main__":
doctest.testmod()
Aqu, estoy simulando el resultado que arrojara en el intrprete interactivo. Esto, ser
interpretado por doctest, como el resultado esperado:
35
Y finalmente, verifico que el mdulo est siendo ejecutado como script (no importado),
de ser as, doy la orden a doctest de ejecutar el script en modo test:
if __name__ == "__main__":
doctest.testmod()
74
75
if __name__ == "__main__":
doctest.testfile('tests/helpers.txt')
En este caso, lo que estamos haciendo, es indicar a doctest, que nuestras pruebas se
encuentran en un archivo a parte: tests/helpers.txt Si abrimos este archivo, podremos
ver todos los test:
2
3
Probando leer_archivo()
4
5
>>> leer_archivo('')
'Error'
7
8
>>> leer_archivo('tests/archivo_de_prueba.txt')
10
11
Probando crear_archivo()
12
13
14
'Error'
15
16
'Error'
17
18
'Error'
19
Mundo\n')
20
21
22
Probando mostrar_texto()
23
24
25
Hola Mundo
26
>>> mostrar_texto()
25
Si te fijas las lneas resaltadas en gris, podrs ver las llamadas a los mtodos que
estamos testeando. Mientras que las resaltadas en negro, simulan el resultando
esperado.
El texto que no aparece resaltado, es interpretado como parte de los comentarios,
exceptuando la lnea 1, que se encarga de importar los mtodos a ser testeados.
Una vez que el cdigo fuente cuenta con los correspondientes test, es hora de correrlos.
Para ello, en la lnea de comandos, escribiremos:
python nombre_del_modulo_a_testear.py -v
python helpers.py -v
Trying:
from helpers import leer_archivo, crear_archivo, mostrar_texto
Expecting nothing
ok
Trying:
leer_archivo('')
Expecting:
'Error'
ok
Trying:
leer_archivo('tests/archivo_de_prueba.txt')
Expecting:
'Archivo de Prueba\nHola Mundo\n'
ok
Trying:
crear_archivo('', 'contenido')
Expecting:
'Error'
ok
Trying:
crear_archivo('', '')
Expecting:
'Error'
ok
Trying:
crear_archivo('tests/archivo_de_prueba.txt', '')
Expecting:
'Error'
ok
Trying:
crear_archivo('tests/archivo_de_prueba.txt', 'Archivo de Prueba\nHola Mundo\n')
Expecting nothing
ok
Trying:
mostrar_texto('Hola Mundo')
Expecting:
Hola Mundo
ok
Trying:
mostrar_texto()
Expecting nothing
ok
1 items passed all tests:
9 tests in helpers.txt
9 tests in 1 items.
9 passed and 0 failed.
Test passed.
En lo anterior, Trying nos describe el cdigo que se est ejecutando, mientras que
Expecting, el resultado esperado. Si todo sale bien, concluir el bloque indicando ok.
Al final del test, se puede acceder al reporte completo:
Test passed.
47
48
49
50
Argumentos:
51
52
53
54
"""
55
56
57
return 'Error'
else:
58
59
archivo.write(contenido)
60
archivo.close()
EL CAMINO CORRECTO
Recurre a la razn, para asimilar lo que lees. Pero recurre a tus emociones, para
saber si lo que haces, realmente te apasiona. Solo as, sabrs que ests
siguiendo el camino correcto.
El siguiente captulo de la Gua Python te trae un desafo por adelantado. Esta vez, el
tema lo elegirs t y ser sometido a votacin, mediante una encuesta.
A continuacin, encontrars una brevsima introduccin a cada uno de los temas que
puedes elegir en la votacin. Esta introduccin te servir para poder decidirte por uno
con mayor facilidad. Recuerda que solo puedes elegir una opcin:
A pedido popular, pues, ha sido votado por una amplia mayora y, a solo efecto de
cumplir por nica vez en mi vida la voluntad de las masas, en el captulo de
hoy aprenderemos veremos un ejemplo de un script Python que se ejecuta en modo
grfico! OMFG! En modo GRFICO! Jesus! Tocaremos el cielo con las manos! [apagar
modo irnico]
Para hacer este ejemplo, me inspir en la Gua oficial de Primeros Pasos con
wxPython. De esta forma, ser ms simple entender la documentacin oficial.
INSTALACIN DE WXPYTHON
El primer paso, ser instalar wxPython.
En Linux ser necesario el paquete: python-wxgtk2.8. En aquellos basados enDebian,
basta con hacer:
sudo apt-get install python-wxgtk2.8
En Gentoo:
emerge wxpython
Para RedHat, Fedora, Mandriva y compaa, pueden buscar los rpm de la versin
2.8.12.0 en este enlace www.rpmfind.net/search.php?query=wxPython o instalarlo con
yum (como root):
yum install wxPython
INTRODUCCIN
wxPython es una suite de libreras de interfaces grficas para Python (programadas en
C++), destinadas a crear GUIs de forma simple. Funciona como un mdulo ms de
Python, debiendo ser importado al igual que cualquier otro.
Cmo principales caractersticas de wxPython pueden citarse:
1. Portabilidad: Windows, Linux y Mac OS X
2. Apariencia: Nativa en todos los S.O.
3. Licencia: LGPL
constants.py
editor.py
Descargar ambos archivos, guardarlos en una carpeta y, dentro de esta, crear un subdirectorio llamado cartas. En este sub-directorio, se guardarn automticamente las
cartas que vayamos creando.
Para correrlo, simplemente haremos python editor.py y se ejecutar el script en
modo grfico.
Por otro lado, en el mtodo __init__ deben establecerse todas las propiedades de
clase y llamar a aquellos mtodos que se encarguen de generar toda la GUI.
INCRUSTANDO WIDGETS
wxPython, utiliza wxWidgets. Estos Widgets sern todos aquellos elementos que se
irn incrustando en el contenedor (frame). Una lista completa de los Widgets
implementados por wxPython, puede econtrarse
enhttp://docs.wxwidgets.org/2.8/wx_wxpython.html#wxpclasses.
Para utilizar cualquiera de estos Widgets, deben ser considerados como
mtodos de wx, simplemente utilizando la sintaxis wx.Widget(parametros).
WIDGETS UTILIZADOS EN NUESTRO CREADOR DE CARTAS COMERCIALES
En nuestro script, los widgets utilizados son:
wx.TextCtrl()
Control de entrada de texto que permite mostrar y editar su contenido. Puede ser de una
sola lnea o multilnea.
Con el parmetro value se define el contenido por defecto, mientras que styledebe ser
definido con las constantes de estilo del control.
wx.Menu()
Un men ya sea como lista desplegable o ventana emergente (pop-up) que permite
seleccionar un elemento capturando el evento y actuando en consecuencia.
wx.MenuBar()
Una barra conteniendo una serie de mens accesibles desde la parte superior de la
ventana.
wx.MessageDialog()
Un cuadro de dilogo que muestra un mensaje de una o varias lneas, con botones de
opcin como Aceptar, S, No y Cancelar. Este Widget recibe como parmetros:parent la
ventana padre, mensaje, titulo y estilo.
Ver lista completa de wxWidgets implementados por wxPython.
CONCLUSIN
Para utilizar cualquier interfaz grfica en Python, solo es necesario:
1. Saber Python (para programar algo y no solo mostrar ventanas con mens, textos y
botones que no hagan nada)
Con el captulo de hoy, llegamos al final de esta gua. Considero que hemos aprendido
muchsimas cosas de gran importancia y que no solo se han enfocado en el dominio de
un lenguaje (como Python, en este caso), sino que adems, introdujeron buenas
prcticas y conceptos de la programacin en general, sus diversas tcnicas y
paradigmas.
En este ltimo episodio, nos avocaremos a un tema particular, el cual es
prcticamente imposible evitar ser abarcado en el desarrollo de un sistema informtico.
Me refiero a la interaccin con bases de datos.
Comencemos!
MYSQL
MySQL es un sistema de gestin de bases de datos relacionales, libre y que
puede ser instalado en mltiples plataformas.
Para seguir el captulo de esta gua, ser necesario instalar MySQL. Para ello los invito
a quienes no posean MySQL instalado, que visiten el sitio de descargas de MySQL y
la documentacin de MySQL.
MYSQLDB
MySQLdb es una interfaz para trabajar con bases de datos MySQL desde
Python. El captulo N7 de esta gua, se ha indicado como lectura recomendada,
el Manual oficial de MySQLdb el cual sugiero que se lea tras finalizar este captulo.
INSTALACIN DE MYSQLDB
Para interactuar desde Python con MySQL a travs de MySQLdb, es necesario instalar
dicho mdulo. El nombre del paquete es python-mysqldb (por si desean instalarlo
desde los repositorios), o sino, pueden descargar un tarball
desdehttp://sourceforge.net/projects/mysql-python/. All mismo, encontrarn el
archivoREADME con toda la informacin para instalarlo.
3. Abrir un cursor
cursor = db.cursor()
MANOS A LA OBRA!
Hecha esta introduccin, estamos en condiciones de arrancar.
use nombre_de_tu_base_de_datos;
DESCARGAR ARCHIVOS
El ejemplo de este captulo, corresponde a un ABM de pases con arquitectura MVC
(modelo-vista-controlador). El mismo, cuenta con los siguientes archivos:
Como podrn observar, este controlador es quien recibe las peticiones que hagamos,
encargndose de realizar los cambios necesarios al modelo (la clase Pais), llamar a este
modelo, y luego, enviar los datos necesarios a la vista, para que sta, finalmente, sea
quien nos muestre esos datos en pantalla.
Saber ms sobre el patrn arquitectnico MVC
Una de las cosas chvere de Python es que se usa en muchas cosas, como
lenguaje es muy flexible para trabajar aplicaciones nativas y juegos.
Julin menciona tambin que algo que le gusta de Python es que permite escribir
frameworks como Django que son muy bonitos y permiten trabajar muy fcil. Opina
que el que algunas aplicaciones trabajen Python en el Frontend en vez de Javascript y
otros lenguajes que trabajan cosas que se parecen a Python muestra que Python est
aqu para quedarse y para hacer muchas cosas.
DESARROLLEMOS PROPUESTAS
Alvaro Martnez desarrolla en Python y es moderador del foro en Foros del Webdesde el
2005, nos comenta que en principio se interes mucho por HTML porque lo vea como
algo con lo que se podan lograr cosas interesantes. Tambin visitaba los foros de php y
css, sin embargo, desde hace tres aos participa activamente en el foro de Python.
GUA PYTHON
En Maestros del web publicamos hace algunos meses el primer captulo de la gua
Python y an estamos en proceso de agregar ms captulos de este lenguaje. En
prximas entregas publicaremos ms captulos con autora de Alvaro Martnez.
Django trae lo que en Python se conoce como bateras incluidas. Desde clases para
tareas sencillas como paginacin, geolocalizacin, autentificacin y cach hasta
componentes bastante completos como el mdulo de
comentarios, notificaciones, administrador, internacionalizacin y feeds.
Adn explica que un sitio en Django es ms limpio puesto que python tiene una
estructura modular, agrega que en otros lenguajes hay que descargarse muchos
archivos y el tener tantos archivos en el directorio puede hacer mas dificil manejar el
sitio. Para graficar la facilidad con la que se activan estos mdulos desde el archivo
de configuracin, nos mostr el cdigo correspondiente:
INSTALLED_APPS = (
'django.contrib.auth', # funciones de autentificacion
'django.contrib.comments', # funciones para agregar comentarios a los modelos
'django.contrib.admin', # administrador autogenerado
)
Adems afirma que es muy fcil encontrar un mdulo en los repositorios para aquellas
funcionalidades que no vienen incluidas en Django, un ejemplo de ello es el modulo
Gravatar que se utiliza en Mejorando.la para los avatares de los comentarios.
MODELO-VISTA-CONTROLADOR
Un punto ms a favor de Django es el patrn Modelo-Vista-Controlador que maneja,
esto quiere decir que separas tu aplicacin en tres componentes, explic Adn. El
modelo principal en este caso seria Video, en donde un video tiene titulo, imagen,
descripcion, comentarios.
Para entender mejor puedes ver el tercer capitulo de la guia Django y luego ver estos
ejemplos:
Modelo: son los datos, en el sitio se tiene un modelo para los Videos.
Ejemplo de modelo
class Video(models.Model):
titulo = models.CharField()
slug = models.CharField()
imagen = models.ImageField()
fecha = models.DateField()
descripcion = models.TextField()
Vista: sera la presentacin de este modelo, en Django entra en los templates, que
reciben los datos del controlador. Hay una plantilla para cada vista: home.html,
videos.html, video.html, heredando de base.html gracias al poderoso sistema de
plantillas de Django.
SQL
SELECT titulo, descripcion, imagen FROM videos ORDER BY fecha LIMIT 10
Django
Video.objects.all().order_by(-fecha)[:10]
Nos coment tambin que en las plantillas de Django se hace uso de la rica cantidad de
filtros que pone a disposicin, desde convertir a maysculas, eliminar etiquetas html y
agregar saltos de lnea.
Gracias a estos filtros es ms fcil tener una clara separacin entre datos, lgica
y presentacin.
SLO UN COMIENZO
Cmo te imaginars el proceso de rediseo y reprogramacin de un sitio como
Mejorando.la no se puede comentar y explicar en detalle en tan slo un artculo, sin
embargo en una proxima publicacin con Adn te contaremos ms funcionalidades y
caracteristicas que hacen de python un lenguaje fcil de aprender y de Django el
framework ideal para perfeccionistas.
La semana pasada dos hroes de Python nos contaron sus experiencias trabajando con
el lenguaje y Gissela, con la ayuda de Adn Snchez nos mostraron cmo se utiliza
Python y Django en Mejorando.la dnde profundizamos ms en el cdigo.
con Python, es desarrollador y moderador del foro Python en Foros del Web ha realizado
4 captulos para integrar en la gua desarrollando los temas:
Algunos temas que Alvaro desarrollar han sido tratados en otros captulos por Eugenia
Bahit, sin embargo, el fin es tambin aclarar algunos aspectos de forma especfica. No
olvides revisar los captulos anteriores de la gua Python:
class VideoComentarioForm(ModelForm):
class Meta:
model = VideoComentario
fields = ('autor', 'autor_email', 'autor_url', 'content')
<form>
<label for="author">nombre</label>{{ form.autor }}
{{ form.autor.errors }}
<label for="email">email</label>{{ form.autor_email }}
{{ form.content.errors }}
</form>
import Image
image = Image.open(path)
image = image.resize((newWidth, newHeight), Image.ANTIALIAS)
image.save(path)[ ejemplo ]
Es importante que ests consciente de que con Django las posibilidades son
muchas, y conforme vayas profundizando en el tema irs aprendiendo trucos.
Ya sabes cmo se utiliza python, django y otras tecnologas para desarrollar el sitio
de Mejorando.la. El sitio es Open Source y el cdigo est disponible en Github.
Y si quieres profundizar ms en el tema recuerda que puedes revisar la gua Django y
la gua Python.
SECUENCIAS
Listas y tuplas en Python son objetos que contienen listas de datos a los que se accede
mediante un ndice, de forma similar a los arreglos (vectores o matrices) de otros
lenguajes. Pertenecen a un tipo de datos que Python llama secuencias y que incluyen
tambin a las cadenas de texto.
Antes de entrar en las diferencias entre los tipos de secuencias, veamos lo que tienen en
comn:
Si sabes algo de PHP o Javascript vers que las secuencias en Python son muy similares
a los arreglos en estos lenguajes. Veamos ahora con ms detalles otras caractersticas
importantes de las secuencias.
JOIN (UNIN)
Podemos tomar una secuencia (cuyos elementos sean cadenas) y transformarla en una
cadena, usando la funcin join(). Esta funcin coloca un separador entre dos elementos
de la secuencia. Si guardamos nuestro separador en una variable s, debemos escribir:
s.join(secuencia)
Por ejemplo, para separar con guiones una lista de nmeros, hacemos:
REBANADAS (SLICES)
Se puede obtener una parte de la secuencia original usando secuencia[x:y:z],
con x, y, z enteros. Lo anterior devuelve una nueva secuencia con las siguientes
caractersticas:
Del mismo tipo que la original (una rebanada de una lista es una lista, una rebanada de
una tupla es una tupla, y una rebanada de una cadena es una cadena).
Conteniendo los elementos desde secuencia[x] hasta secuencia[y-1] (no incluye a
secuencia[y]).
Saltendose z elementos cada vez.
Por ejemplo, para obtener los nmeros impares en una lista del 1 al 10, podemos hacer
lo siguiente:
El tercer parmetro puede omitirse y eso quiere decir que no se deben saltear elementos
(se asumir z = 1). De hecho, tambin pueden omitirse los dems: si se omite x se
tomarn todos los elementos desde el primero, y si se omite y se tomarn todos los
elementos hasta el final. Por lo tanto:
sec[:4] devuelve los primeros 4 elementos (0, 1, 2, 3).
sec[4:] devuelve los elementos desde el 5 hasta el ltimo.
sec[:] crea una secuencia con todos los elementos de la primera y es de hecho la forma
ITERABLES
Tal y como se explic en el captulo 3, las listas y tuplas se pueden recorrer elemento a
elemento con el bucle for. La explicacin de Eugenia Bahit es muy clara, por lo que
solamente agregar que el bucle for puede recorrer cualquier tipo de secuencia, y como
las cadenas son secuencias, se las puede recorrer letra a letra:
...
letra = h
letra = o
letra = l
letra = a
OPERADOR DE PERTENENCIA
Para probar si un elemento pertenece a una secuencia, usamos el operador in. Ejemplos:
CONCATENACIN (SUMA)
La suma de dos secuencias a y b genera una nueva secuencia que contiene los
elementos de ambas y en la que los elementos de b aparecen luego de los elementos
de a. Las secuencias deben ser del mismo tipo (no es posible sumar cadenas y tuplas, o
tuplas y listas, por ejemplo):
MULTIPLICACIN
Python define la multiplicacin de secuencias por un nmero entero n. El resultado de la
operacin es el mismo que el de sumar la secuencia a s misma n veces.
>>> 'a' * 5
'aaaaa'
>>> 'ab' * 2
'abab'
>>> (4, 5) * 3
(4, 5, 4, 5, 4, 5)
NOTA
Si sabes PHP, vers que lo siguiente es muy similar a cmo funciona la funcin list() de PHP.
DESEMPAQUETADO (UNPACKING)
Python permite asignar los elementos de una secuencia a diferentes variables. No se
requiere un operador especial, el desempaquetado es automtico cuando se asigna
(usando =) una secuencia a una lista de variables. De forma algo ms simple: del lado
izquierdo del signo de igual se escribe una lista de variables separadas por comas, y del
lado derecho la secuencia que ser desempaquetada.
La cantidad de variables del lado izquierdo debe ser la misma que la cantidad de
elementos de la secuencia. Como esto puede sonar complicado, mejor veamos algunos
ejemplos:
>>> a, b, c, d = 'hola'
>>> print a
'h'
>>> print b
'o'
>>> print c
'l'
>>> print d
'a'
>>> a, b = [1, 2]
>>> print a
1
>>> print b
2
>>> a, b = 'hola' #ERROR: 4 valores en la secuencia y solamente 2 variables!
Traceback (most recent call last):
Esto es lo que todas las secuencias tienen en comn. Veamos ahora las particularidades
de cada una.
LISTAS
Las listas en Python son equivalentes a los arreglos en PHP o en Javascript. Para crear
una lista, simplemente se declaran sus elementos entre corchetes:
>>> mi_lista.append(10)
>>> print mi_lista
[1, 'b', 'd', 23, 10]
Para modificar un elemento particular de una lista, se asigna el nuevo valor al subndice
correspondiente:
>>> mi_lista[0] = 2
>>> print mi_lista
[2, 'b', 'd', 23, 10]
Incluso se pueden reemplazar trozos de una lista con otra, o con trozos de otra, usando
la notacin de rebanadas (slices):
>>> mi_lista[0:2] = [3, 4] # reemplazar los dos primeros elementos de la lista con los elementos de
[3, 4]
>>> print mi_lista
[3, 4, 'd', 23, 10]
Es importante notar que lo anterior no es lo mismo que asignar una secuencia entera a
un ndice:
TUPLAS
Las tuplas son como las listas, excepto que son inmutables (sus elementos no pueden
ser modificados). Se identifican fcilmente porque en vez de usar corchetes, se definen
entre parntesis. En lo dems, funcionan igual a las listas y al resto de las secuencias.
Python genera tuplas de forma automtica cuando encuentra valores separados por
comas en el cdigo, aunque no estn delimitados por parntesis. Esta generacin
automtica es lo contrario del desempaquetado, y se llama,
lgicamente, empaquetado (packing) de valores. Esto nos permite simular retorno de
mltiples valores en las funciones, o intercambiar los valores de dos variables sin crear
una variable auxiliar:
var1, var2 = x, y
En este caso, Python crea una tupla (x, y) (empaquetado), e inmediatamente asigna el
primer elemento a var1, y el segundo a var2 (desempaquetado)
def mi_funcion():
# cdigo de la funcin
...
return x, y
CADENAS
Las cadenas son secuencias cuyos elementos son los caracteres individuales. Por la
importancia que tiene el texto en casi cualquier programa y dado que las cadenas tienen
muchas operaciones especficas que no estn definidas para las dems secuencias.
En el captulo de la prxima semana, detallaremos las caractersticas nicas de las
cadenas de texto en Python.
VENTAJAS PARA LOS QUE SE PONEN LA CAMISETA DE PYTHON
Simplificado y rpido: Nos dice Adn que lo bueno de python es que simplifica mucho la
programacin hace que te cias a un modo de lenguaje de programacin, python te
propone un patrn. Por su parte Ricardo seala que es un gran lenguaje para scripting, si
quieres algo rpido (en el sentido del performance del lenguaje), con unas cuantas lneas ya
est.
Elegante y flexible: Para Ricardo el lenguaje te da muchas herramientas si quiero listas
de varios datos, no hace falta que declares cada cosa y agrega que al ser tan flexible no te
preocupas tanto por los detalles.
Programacin sana y productiva: Segn Arturo programar en python se convierte en
un estilo muy sano de programar: es sencillo de aprender, direccionado a las reglas
perfectas, te haces como dependiente de mejorar, cumplir las reglas, el uso de las lineas, de
variables. Adn afirma que esun lenguaje que fue hecho con productividad en
mente python me hace ser mas productivo, me permite entregar en los tiempos que me
piden.
Ordenado y limpio: Este es un punto en el cual los tres coinciden. Dice Arturo que es el
orden que mantiene python es de lo que ms le gusta es muy leible, cualquier otro
programador lo puede leer y trabajar sobre el. A su vez Adn destaca que
los mdulos estn bien organizados, a diferencia de otros lenguajes.
Portable: Tanto Arturo como Adn concuerdan en que es un lenguaje muy portable (ya
sea en mac, linux o windows) en comparacin con otros lenguajes.
Bateras incluidas: Las libreras que ms necesitas ya estn dentro del cdigo
menciona Arturo. As tambin Adn coment en detalle cules son estas bateras incluidas al
contarnos cmo se utiliza python en mejorando.la
Comunidad: Algo muy importante para el desarrollo de un lenguaje es la comunidad,
segn Arturo la misma comunidad de python cuida el lenguaje y casi todas las
actualizaciones se hacen de manera democrtica.
Desventajas
Arturo mencion que la curva de aprendizaje cuando ya ests en la parte web no es tan
sencilla. Por su parte Adn coment sobre el hecho de que la mayora de los servidores
no tienen python y si lo tienen la configuracin es un poco dificil.
Ricardo dijo que no le gustan algunas libreras que trae por defecto, por ejemplo las que
trae para trabajar con http y algunas que estn hechas por terceras personas.
DEFINIENDO CADENAS
En Python tenemos varias formas ligeramente diferentes de definir cadenas. La forma
ms comn es escribirlas entre comillas dobles ():
cadena = "hola"
Tambin pueden utilizarse comillas simples (), no hay diferencia entre las cadenas
delimitadas con o .
Por razones obvias, no podemos incluir en la cadena una comilla del mismo tipo que la
que se utiliza para definirla, Python no sabr dnde termina realmente:
Una forma posible de evitar esto es delimitar la cadena con comillas simples si sabemos
que contendr comillas dobles y delimitarla con comillas dobles si sabemos que
contendr comillas simples.
Tampoco podemos incluir saltos de lnea en la cadena:
Para solucionar esto, tenemos la opcin de utilizar secuencias de escape. Las secuencias
de escape permiten introducir caracteres especiales, escapndolos(forzndolos a ser
caracteres sin significado especial) con una contrabarra (\) delante. La secuencia de
escape para un salto de lnea es \n:
>>> print "hola \n \" mundo \" " # los espacios antes y despus de \n no son necesarios, se agregan
por claridad
hola
" mundo "
Para solucionar el problema de los saltos de lnea o las comillas, podemos utilizar
tambin una tercera va: las cadenas en Python pueden delimitarse con bloques de tres
comillas dobles () o tres apstrofes (). Saltos de lnea y comillas individuales estn
permitidos en este tipo de cadenas.
Adems de todo esto, hay dos modificadores (tres en Python 3) que cambian la forma en
la que la cadena es interpretada, anteponindolos a la cadena misma:
INMUTABLES
En Python, as como en Java y otros lenguajes, las cadenas son inmutables (sus
elementos no se pueden modificar). Si se requieren modificaciones, se debe construir
una cadena nueva (muchas veces esto lo hace automticamente el intrprete de
Python). Ejemplo:
MTODOS DE CADENAS
Adems de la sintaxis de subndices y rebanadas (discutidas en el captulo anterior sobre
Secuencias), las cadenas en Python tienen algunos mtodos para operaciones comunes
(bsqueda y reemplazo, por ejemplo).
BSQUEDA
Para buscar una subcadena (o un caracter) en una cadena, Python nos ofrece varias
alternativas. Si solamente necesitamos saber si una cadena contiene cierto caracter o
cierta subcadena, usamos el operador in:
print 'Est!'
...
Est!
...
No encontrada
>>> try:
...
cadena.index('ha')
...
No encontrada
Un uso comn de ambos mtodos es obtener toda la cadena desde el principio hasta la
primer ocurrencia de cierta subcadena:
Finalmente, tanto index como find aceptan parmetros que restringen la bsqueda a
cierto tramo de la cadena: en vez de buscar desde el principio y hasta el final. El
segundo argumento del mtodo indica desde qu posicin comenzar a buscar y el
tercero indica en qu posicin terminar la bsqueda.
Para ejemplificar, busquemos todas las ocurrencias de la letra e en una cadena
cualquiera (nota: hay mejores maneras de hacer esto, lo siguiente es solamente un
ejemplo!)
REEMPLAZO DE TEXTO
Otra operacin comn es reemplazar una parte de una cadena por otra. En Python esto
lo hacemos con el mtodo replace:
Notar que, como las cadenas son inmutables, el mtodo replace devuelve una nueva
cadena con el texto reemplazado, la cadena original (en el ejemplo, cadena) queda
intacta.
DIVISIN EN TROZOS
Supongamos que tenemos una cadena que contiene una fecha, en formato da/mes/ao.
Podemos obtener fcilmente cada trozo de la cadena (cada dato de la fecha) utilizando
el mtodo split. Este mtodo divide a la cadena en trozos, cortando cada trozo en cada
ocurrencia de un separador, que se pasa como argumento.
Si no le damos a split un separador, la cadena ser separada por espacios. Esto puede
servir para obtener todas las palabras de una oracin:
La operacin inversa (convertir una lista a cadena), se hace con el mtodo join, que
vimos en el captulo sobre Secuencias. Una advertencia a quienes programen en otros
lenguajes: la operacin join se define usualmente como una operacin de la lista, que
toma una cadena como argumento y la usa como delimitador. En Python, sin
embargo, join es una operacin de la cadena y toma una lista como argumento.
Como ejemplo, volvamos a unir la cadena de fecha, con diferentes caracteres
delimitadores:
Notar que si bien es un ejemplo claro, sera ms sencillo y eficiente hacer la sustitucin
sobre la cadena original con replace('/', '-').
CONCLUSIN
Hemos visto cmo realizar en Python algunas de las operaciones ms comunes sobre
cadenas: definicin, bsqueda, reemplazo de subcadenas y separacin en trozos.
Las cadenas tienen otros mtodos para operaciones varias, como por ejemplo buscar
desde la derecha en vez de desde la izquierda, o convertir la cadena entera o parte de
ella a maysculas o minsculas. La lista completa de mtodos est, como siempre, en la
documentacin: The string module y String methods.
Cuando manejamos texto, sin duda una de las operaciones ms comunes es la bsqueda
de una subcadena, ya sea para obtener su posicin en el texto o simplemente para
comprobar si est presente. Si la cadena que buscamos es fija, son suficientes los
mtodos como find(), index() o similares, pero stos no ayudan si lo que se busca es una
subcadena con cierta forma.
Al buscar direcciones de correo electrnico, nmeros de telfono, validar campos de
entrada, o encontrar por ejemplo una letra mayscula seguida de dos minsculas y de 5
dgitos entre 1 y 3, es necesario recurrir a las Expresiones Regulares, tambin
conocidas como Patrones.
PATRONES
Las expresiones regulares son un lenguaje potente de descripcin de texto, y no creo
que exista un lenguaje moderno que no permita usarlas. Las reglas con las que se
forman son bastante simples, pero requiere prctica aprender a combinarlas
correctamente.
Con expresiones regulares podemos buscar una subcadena al principio o al final del
texto, si queremos que se repita cierta cantidad de veces, si queremos que algo NO
aparezca, o si debe aparecer una subcadena entre varias posibles. Permite adems
capturar aquellos trozos del texto que coincidan con la expresin, para guardarlos en
una variable o reemplazarlos por una cadena predeterminada (o incluso una cadena
formada por los mismos trozos capturados). Veremos algunos aspectos bsicos de las
expresiones regulares, sin entrar en detalles.
METACARACTERES
Se conoce como metacaracteres a aquellos caracteres que, dependiendo del contexto,
tienen un significado especial para las expresiones regulares, y que por lo tanto
coincide con a, b, o c
[387ab]: coincide con 3, 8, a o b
ni[oa]s: coincide con nios o nias.
Para evitar errores, en caso de que queramos crear una clase de caracteres que
contenga un corchete, debemos escribir una barra \ delante, para que el motor de
expresiones regulares lo considere un caracter normal: la clase[ab\[] coincide
con a, b y [.
RANGOS
Si queremos encontrar un nmero, podemos usar una clase como [0123456789], o
podemos utilizar un rango. Un rango es una clase de caracteres abreviada que se crea
escribiendo el primer caracter del rango, un guin, y el ltimo caracter del rango.
Mltiples rangos pueden definirse en la misma clase de caracteres.
[a4-]
[-a4]
[a\-4]
RANGO NEGADO
As como podemos listar los caracteres posibles en cierta posicin de la cadena, tambin
podemos listar caracteres que NO deben aparecer. Para lograrlo, debemosnegar la clase,
colocando un circunflejo inmediatamente despus del corchete izquierdo:
CLASES PREDEFINIDAS
Hay algunas clases que se usan frecuentemente y por eso existen formas abreviadas
para ellas. En Python (as como en otros lenguajes) se soportan las clases predefinidas
de Perl y de POSIX (si no sabes lo que eso quiere decir, quizs quieras leer en Wikipedia
su signficado). Algunas de estas clases son:
Adems de las listadas arriba (y el resto, no listadas) existe una clase de caracteres que
coincide con cualquier caracter (sea letra, nmero, o un caracter especial). Esta clase es
el punto:
CUANTIFICADORES
Son caracteres que multiplican el patrn que les precede. Mientras que con las clases de
caracteres podemos buscar un dgito, o una letra, con los cuantificadores podemos
buscar cero o ms letras, al menos 7 dgitos, o entre tres y cinco letras maysculas.
Los cuantificadores son:
?: coincide con cero o una ocurrencia del patrn (dicho de otra forma: hace que el patrn
sea opcional)
+: coincide con una o ms ocurrencias del patrn
*: coincide con cero o ms ocurrencias del patrn.
{x}: coincide con exactamente x ocurrencias del patrn
{x, y}: coincide con al menos x y no ms de y ocurrencias. Si se omite x, el mnimo es
cero, y si se omite y, no hay mximo. Esto permite especificar a los otros como casos
particulares: ? es {0,1}, + es {1,} y * es {,} o{0,}.
Ejemplos:
: cualquier cadena, de cualquier largo (incluyendo una cadena vaca)
entre 3 y 6 letras minsculas
\d{4,}: al menos 4 dgitos
.*hola!?: una cadena cualquiera, seguida de hola, y terminando (o no) con un !
.*
[a-z]{3,6}:
OTROS METACARACTERES
Existen otros metacaracteres en el lenguaje de las expresiones regulares:
MDULO RE
Para utilizar Expresiones Regulares, Python provee el mdulo re. Importando este
mdulo podemos crear objetos de tipo patrn y generar objetos tipo matcher, que son
los que contienen la informacin de la coincidencia del patrn en la cadena.
CREANDO UN PATRN
Para crear un objeto patrn, importamos el mdulo re y utilizamos la funcincompile:
import os
patron = re.compile('a[3-5]+') # coincide con una letra, seguida de al menos 1 dgito entre 3 y 5
A partir de ahora, podemos usar el objeto patron para comparar cadenas con la
expresin regular.
O el mtodo finditer, que devuelve un iterador que podemos usar en el bucle for:
OBJETOS MATCHER
Ms arriba se mencion el uso del los parntesis en un patrn. Cuando se obtiene una
coincidencia del patrn en una cadena, cada grupo delimitado por parntesis captura el
texto que haya coincidido con l. Estos grupos son accesibles a travs de un objeto
tipo matcher devuelto por search o match. Los grupos se numeran de izquierda a derecha
segn su orden de aparicin en el patrn, y podemos usar este nmero para acceder al
contenido del grupo con el mtodo group del objetomatcher.
De forma alternativa, podemos usar el mtodo groups que devuelve una lista de grupos.
>>> matcher.pos
0
Tambin permiten sustituir los grupos capturados en una cadena cualquiera, mediante el
uso de referencias de la forma \g<x>, donde x es el nmero de grupo:
>>> print matcher.expand('La cadena que coincidi fue \g<0>, el grupo 1 es \g<1> y el grupo 2
es \g<2>')
La cadena que coincidi fue a455, el grupo 1 es a y el grupo 2 es 455
Vale notar que, si bien findall no devuelve objetos tipo matcher, s proporciona los grupos
de forma similar, como una lista de tuplas:
REEMPLAZO DE CADENAS
Similar a la combinacin search + expand, existe el mtodo sub, cuya funcin es encontrar
todas las coincidencias de un patrn y sustituirlas por una cadena. El mtodo recibe dos
parmetros: el primero es la cadena con la que se sustituir el patrn y el segundo es la
cadena sobre la que queremos aplicar la sustitucin.
Se pueden utilizar referencias de la misma forma que antes:
'a'
>>> matcher.group('letra') # pero adems ahora puedo acceder por nombre
'a'
>>> matcher.group('numero')
'455'
>>> matcher.expand('La letra es \g<letra>') # las referencias se usan con el nombre en vez de con
el nmero
'La letra es a'
>>> matcher.groupdict()
{'letra': 'a', 'numero': '455'}
comienzo y final de cada lnea de la cadena, en vez de coincidir con el comienzo y final de la
cadena entera
re.S o re.DOTALL: hace que el punto (.) coincida adems con un salto de lnea (sin este
modificador, el punto coincide con cualquier caracter excepto un salto de lnea)
Cada modificador se usa como segundo parmetro de la funcin, podemos unir los
efectos de ms de un modificador separndolos con |. Por ejemplo:
DICCIONARIOS
Conocidos en otros lenguajes como Hashes (Perl), arreglos asociativos (PHP)
ohashmaps (Java), los diccionarios en Python son contenedores de pares clave-valor. A
simple vista, son simplemente arreglos o listas cuyos ndices son cadenas en vez de ser
nmeros enteros. Internamente la diferencia es mucho mayor, ya que se implementan
como tablas hash en vez de listas. Pero no vale la pena entrar aqu en esos detalles,
cuando podemos encontrar descripciones precisas en Wikipedia: Lista, Tabla Hash.
Los diccionarios no preservan el orden de los elementos: ste depende de las claves que
se usen, del orden en el que se ingresan los datos y de otros factores. Adems, no se
puede iterar directamente sobre los elementos, aunque Python provee funciones para
hacerlo (y tambin para iterar sobre las claves).
Para crear un diccionario, escribimos los pares clave-valor entre llaves, separando cada
par por una coma:
>>> mi_diccionario['edad'] = 32
>>> del mi_diccionario['pais']
>>> print mi_diccionario
{'edad': 32, 'nombre': 'Juan', 'apellido': 'Perez'} # notar que se
agreg la clave 'edad', se elimin la clave 'pas', y no se preserv el
orden
Si intentamos acceder a una clave no definida, Python lanza la excepcin KeyError. Para
evitarla, podemos comprobar fcilmente si la clave est en el diccionario usando el
operador in:
print mi_diccionario['edad']
...
32
Otra forma de evitar el error es utilizar el mtodo get(). Este mtodo recibe dos
parmetros: la clave cuyo valor se quiere obtener y el valor a retornar si la clave no est
definida. Si no se especifica el segundo parmetro, get devuelve None:
Al igual que las secuencias, los diccionarios tambin pueden ser recorridos con un
bucle for. La diferencia es que en vez de iterar en orden sobre los elementos, el
bucle for itera sobre las claves sin un orden preestablecido:
Usando el mtodo items(), obtenemos una lista de tuplas (clave, valor), que podemos
usar en el for:
Los diccionarios soportan otras operaciones: el mtodo copy() devuelve una copia, y el
mtodo update() permite agregar a un diccionario las claves y valores de otro:
FUNCIONES
Las funciones en Python se declaran con la palabra clave def, seguida del nombre de la
funcin y de sus argumentos. Como todo bloque en Python, la declaracin termina con
dos puntos (:) y el cdigo siguiente debe estar sangrado a un nivel mayor:
Una vez definida, la funcin puede ser llamada desde cualquier parte de nuestro archivo
Python, simplemente con su nombre. Adems de recibir valores por va de sus
parmetros, la funcin puede acceder a variables definidas fuera de ella y en el mismo
archivo (mdulo), usando la sentencia global.
Para devolver un valor, se utiliza la sentencia return. Este valor se puede obtener por
asignacin. Veamos un ejemplo:
variable_externa = 'HOLA'
def mi_funcion(param1, param2, ...):
# cdigo de la funcin
global variable_externa
return variable_externa
mifuncion(....) # ejecuta el cdigo de la funcin
mi_variable1 = mi_funcion(var1, var2, ...) # mi_variable = 'HOLA'
Vale notar que la funcin puede devolver solamente un valor (objeto), sin embargo, se
puede simular la devolucin de valores mltiples gracias al empaquetado: valores
separados por coma luego de la sentencia return se convierten a una tupla y lo que
devuelve la funcin es esa tupla. Luego podemos recibir los valores devueltos como una
tupla o desempaquetarlos:
...
>>> var1, var2 = mi_f() # var1 = 'a', var2 = 'b'
>>> t_var = mi_f()
>>> t_var
('a', 'b')
Las funciones en Python pueden adems asignarse y pasarse como parmetro a otras
funciones.
MANEJANDO ARCHIVOS
En Python, as como en cualquier otro lenguaje, los archivos se manipulan en tres pasos:
primero se abren, luego se opera sobre ellos y por ltimo se cierran.
APERTURA
Para abrir un archivo debemos usar la funcin open(), que recibe como parmetros el
nombre del archivo y el modo en el que se debe abrir. De forma predeterminada (es
decir, si se omite el segundo parmetro), el archivo se abre como slo lectura.
Es importante tener en cuenta que todas las operaciones estn limitadas a la forma en la
que se abra el archivo: no se puede leer de un archivo abierto solamente para escritura,
ni escribir en un archivo abierto como solo lectura.
MODOS
LECTURA
Una vez abierto el archivo, podemos leer el contenido hacia una cadena conread(), leer
una lnea con readline(), u obtener una lista conteniendo las lneas del archivo
con readlines(). Los tres mtodos aceptan un parmetro entero opcional que define el
nmero mximo de bytes a leer del archivo. Si este parmetro es negativo o
simplemente se omite, read y readlines leern todo el archivo yreadline una lnea completa
sin importar su largo.
Otra forma de leer el archivo es leer lnea por lnea en un bucle for, ya que el objeto
archivo es iterable.
Para ejemplificar lo mencionado hasta ahora, supongamos que tenemos un
archivoprueba.txt con el siguiente contenido:
Esto es
una prueba
de lectura!
>>> archivo = open('prueba.txt', 'r') # slo lectura. Con modificadores, podra usar 'r+', 'rb', o 'rb+'
>>> print archivo.read()
# leer todo
Esto es
una prueba
de lectura!
>>> print archivo.readline()
# leer 1 lnea.
Esto es
>>> print archivo.readlines() # leer todas las lneas como una lista.
['Esto es\n', 'una prueba\n', 'de lectura!'] # ntese que siempre se
incluyen los saltos de
lnea.
>>> print archivo.read(2)
Es
>>> print archivo.readline(4)
...
print linea
...
Esto es
una prueba
de lectura!
Es importante notar que los ejemplos anteriores no funcionan en secuencia tal cual
fueron escritos. Esto es debido a que una vez que se lee contenido del archivo, la
siguiente lectura comenzar desde donde acab la anterior. Es decir, si leemos 4 bytes
de la primera lnea (Esto), una siguiente lectura de 3 bytes devolver es. Todo
archivo contiene un puntero interno que acta como un cursor o como un punto de
partida para las funciones de lectura o escritura y a su vez cada vez que se usa una de
estas funciones, el puntero interno se mueve
Para manipular el puntero interno existen los mtodos seek, que recibe como parmetro
la posicin a la que debe mover el puntero (0 para moverlo hacia el principio del archivo)
y tell, que devuelve la posicin actual del puntero.
ESCRITURA
Si lo que queremos es escribir en el archivo, tenemos los mtodos write ywritelines.
Contrapartes de read y readlines respectivamente, write escribe una cadena al archivo
y writelines recibe una lista de lneas para escribir. Por ejemplo, si quisiramos recrear el
archivo prueba.txt del ejemplo anterior, podemos hacerlo de dos formas:
CIERRE
Cuando terminamos de trabajar con el archivo, lo cerramos con close(). Esto libera el
archivo para ser usado por otros programas, y adems asegura que los cambios sobre l
se guarden. De ms est decir que Python se encarga de cerrar todos los archivos que
queden abiertos al final del programa, pero es una buena prctica no dejar nada al azar
y cerrar el archivo tan pronto como se lo termina de usar.
WITH
A partir de Python 2.5, podemos simplificar un poco el cdigo necesario para abrir y
cerrar el archivo usando with:
Esto nos libera de tener que cerrar el archivo explcitamente, ya que Python se
encargar de cerrarlo automticamente al salir del bloque.