Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿Porqué ?...y
Antonio Ognio [email protected]
Coordinador
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Agenda
● ¿Qué es Python?● ¿Porqué puede ser una buena idea usarlo?● Un vistazo a Python como lenguaje● Django, un framework web para Python● Mi experiencia usando Python● Ideas para proyectos en el PLUG● Conclusiones y recursos de interés
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Para que me conozcan un poquito más...
● Antonio Ognio, iqueño, 32 años, “limeño” desde 1994 :)● Programador BASIC, 10 años (Commodore 64)● Pascal / Visual Basic a los 15 años (386)● C / C++ / Delphi / Java a los 18 años (UPC, años 90's)● Miembro del PLUG desde 1998● PHP, Perl, Bash + Linux (Conectiva, Pantel – 2000)● Coordinador del PLUG desde 2000● PHP, Java, C# en Mono – Peruserver (2003 – 2005)● Java, LISP, Prolog (UPC, años 2005 - 2009)● PHP, Python – El Pedregal (2006 – 2007)● Python, Javascript, Ruby, PHP – Aureal (2008 – 2009)● Aprendiendo Erlang, Objective-C y otros lenguajes...
... como programador y linuxero :)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿Qué es Python?● Lenguaje de programación de propósito general● Lenguaje de alto nivel (de abstracción)● Enfatiza la legibilidad del código● Permite hacer mucho trabajo manteniendo una sintaxis clara● Sentencias relativamente cortas● Varios paradigmas: imperativo, orientado a objetos, funcional● Lenguaje dinámico, generalmente usado para escribir scripts y disponible en múltiples plataformas.
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Orígenes / Historia● Creado a principios de los 90's (1991)● Autor: Guido Van Rossum (GvR)● CWI (Centro de Investigacíon en Holanda)● En 1994 adquire características de programación funcional● En 1995 se muda a USA al CNRI● Desde 2001 es desarrollado por la Python Software Foundation● Desde el 2005 Guido trabaja para Google
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
GvR (Guido Van Rosum)
Dictador benevolente de por vida
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿De donde viene el nombre?
Monty Python Flying Circus(cómicos británicos)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
...pero la mayoría cree que...
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
La serpiente es la mascota...
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Logo
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿Porqué usar Python?● Lo usan grandes empresas y proyectos● Lenguaje simple pero potente● Sintaxis compacta, ordenada y legible● Suele aumentar la productividad*● Utilizado en muchas áreas● Disponibilidad de bibliotecas de código (librerías)● Cada vez más conocido y usado● Uno de los lenguajes dinámicos más maduro● Bastante utilizado en el mundo del FLOSS● Disponible para muchos entornos operativos* Cuando se viene de lenguajes como C, C++ o Java
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿Quién usa Python?
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Implementaciones
● CPython● Jython● IronPython● PyPy● Python for S60
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Implementaciones
● CPython (Implementación original)
● Jython Java / JVM
● IronPython CLR/DLR/.Net
● PyPy Python
● Python for S60 Symbian / Nokia
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Proyectos que lo usan
● Mailman● Anaconda● Launchpad● Plone● Bittorrent
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Proyectos que lo usan
● Mailman (gestor de listas de correo)
● Anaconda (instalador de RedHat)
● Launchpad (plataforma de Ubuntu)
● Plone (CMS de la FSF)
● Bittorrent (Versión original en Windows)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Proyectos que lo usan
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Versiones en uso
Python 2.5 (RHEL, Ubuntu LTS, Mac OS X)
Python 2.6 (Fedora 11+, Ubuntu 9.04+)
Python 3.0 (Instalación bajo demanda)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Disponibilidad de binariosWindows (Binarios Python.org / ActiveState / Instant Python)
Linux Todas las distribuciones incluyen Python
Mac OS X (Pre-instalado por Apple, MacPorts, etc)
Código fuente / paquetes (Otras plataforma)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
IDEs (Entornos de desarrollo)
● Komodo● NetBeans● PyDev (Eclipse)● IDLE● Boa Constructor● XCode (IDE oficial de Apple)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿Cómo se ve el código?#!/usr/bin/env python# -*- coding: utf-8 -*-
import random
numero = random.randrange(1, 100)respuesta = None
print "Ud. deber adivinar un numero entre 1 y 100."á
while respuesta != numero: print "Ingrese un numero entre 1 y 100: " x = raw_input() try: x = int(x) except ValueError: print "Ud. no ha ingresado un numero entre 1 y 100!" if x > numero: print "El numero es menor" elif x < numero: print "El numero es mayor" else: print "Adivino! La respuesta era %d" % numero break
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Ejecutando el código
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Rendimiento● Bastante bueno pero no comparable con C, C++● Competitivo con PHP, mejor que Ruby por el momento● Si hay un compilador (reporte errores de sintaxis)● Se crea un archivo .pyc a la hora de ejecutar el .py● Ejecuciones posteriores usan el .pyc● Se puede acelerar la ejecución con Psyco● Es posible extender Python con extensiones binarias● Existe una API en C para extender Python● Existe Cython un lenguaje estilo Python para escribir extensiones binarias en C● Google y otros están haciendo mucho por optimizar Python para obtener el máximo rendimiento :)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
El Zen de Python
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
El Zen de Python (Filosofía)● Hermoso es mejor que feo.● Explícito es mejor que implícito.● Simple es mejor que complejo.● Complejo es mejor que complicado.● Plano es mejor que anidado. ● Disperso es mejor que denso.● La legibilidad cuenta.● Los casos especiales no son suficientemente especiales como para romper las reglas.● Aunque lo pragmático gana a la pureza.● Los errores nunca deberían dejarse pasar silenciosamente.● A menos que se silencien explícitamente.
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
El Zen de Python (2)● Cuando te enfrentes a la ambigüedad, rechaza la tentación de adivinar.● Debería haber una -- y preferiblemente sólo una -- manera obvia de hacerlo.● Aunque puede que no sea obvia a primera vista a menos que seas holandés. (NT: Guido van Rossum, creador de Python, es holandés).● Ahora es mejor que nunca.● Aunque muchas veces nunca es mejor que ahora mismo.● Si la implementación es difícil de explicar, es una mala idea.● Si la implementación es sencilla de explicar, puede que sea una buena idea.● Los espacios de nombres son una gran idea -- ¡tengamos más de esas!
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Sintaxis de Python
- Un programa en Python está compuesto por una o más lineas lógicas.
- Un linea lógica puede estar compuesta por una o más lineas físicas.
- Las sentencias no requiere de un delimitador entre ellas como el famoso “;” en C, C++, Java, JavaScript, PHP, etc.
- La indentación es significativa ya que no hay otra manera de indicar bloques de código subordinados a estructuras de control o definiciones de clases y funciones.
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Intérprete interactivoPython 2.5.2 (r252:60911, Jul 22 2009, 15:35:03) [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> 1 + 12>>> 'Hola' + ' ' + 'mundo' + '!''Hola mundo!'>>> '[repetir]' * 5'[repetir][repetir][repetir][repetir][repetir]'>>> try:... n = 12 / 0... exception ZeroDivisionError: File "<stdin>", line 3 exception ZeroDivisionError: ^SyntaxError: invalid syntax>>> try:... n = 12 / 0... except ZeroDivisionError:... print "No se puede dividir por cero!"... No se puede dividir por cero!>>>
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Tipos y operadores básicos>>> 10 * 10100>>> 874854533434324 * 2432342432142421279458036244482359970157376L>>> 9860948509850935809348504850438503485043542343434234 * 394830948302480348039480234324394830948309480394432434343238934076513063754615513224820483369228565090953244251715301778213629782870944071332640212573080925678121851088L>>> 10 / 33>>> 10 / 3.03.33333333333333351024>>> 2 ** 8256>>> b1 = True>>> b1True>>> not b1False>>> moneda = 'S/.'>>> monto = 234.3212>>> '%s %.2f' % (moneda, monto)'S/. 234.32'
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Colecciones (Listas)>>> vocales = ['a', 'e', 'i', 'o', 'u']>>> vocales['a', 'e', 'i', 'o', 'u']>>> vocales[0]'a'>>> vocales[4]'u'>>> vocales[-1]'u'>>> vocales[-5]'a'>>> vocales[0:3]['a', 'e', 'i']>>> vocales[3:]['o', 'u']>>> vocales[2] = 'X'>>> vocales['a', 'e', 'X', 'o', 'u']>>> del(vocales[2])>>> vocales['a', 'e', 'o', 'u']>>> vocales.insert(2, 'i')>>> vocales['a', 'e', 'i', 'o', 'u']
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Colecciones (Diccionarios)>>> colores = {... 'amarillo': 'yellow',... 'rojo': 'red',... 'azul': 'blue'... }>>> colores['rojo']'red'>>> colores['azul']'blue'>>> colores{'rojo': 'red', 'azul': 'blue', 'amarillo': 'yellow'}>>> colores['marron'] = 'brown'>>> colores['marron']'brown'>>> colores{'rojo': 'red', 'azul': 'blue', 'marron': 'brown', 'amarillo': 'yellow'}>>> 'rojo' in coloresTrue>>> 'verde' in coloresFalse>>> colores['verde']Traceback (most recent call last): File "<stdin>", line 1, in <module>KeyError: 'verde'
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Estructuras de control>>> hora = 14>>> if hora >= 1 and hora <= 6:... turno = 'Madrugada'... elif hora >=7 and hora <= 11:... turno = 'Ma ana'ñ... elif hora >= 12 and hora <= 17:... turno = 'Tarde'... elif hora >= 18 and hora <= 23:... turno = 'Noche'... else:... print 'Fuera de rango!'... >>> turno'Tarde'>>> i = 1>>> while i<= 100:... print i... i += 1... 123...100
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Una clase en Javapublic class Employee{ private String myEmployeeName; private int myTaxDeductions = 1; private String myMaritalStatus = "single";
//--------- constructor #1 ------------- public Employee(String EmployeName) { this(employeeName, 1); }
//--------- constructor #2 ------------- public Employee(String EmployeName, int taxDeductions) { this(employeeName, taxDeductions, "single"); }
//--------- constructor #3 ------------- public Employee(String EmployeName, int taxDeductions, String maritalStatus) { this.employeeName = employeeName; this.taxDeductions = taxDeductions; this.maritalStatus = maritalStatus; }...
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
La misma clase en Pythonclass Employee(object):
def __init__(self, employeeName, taxDeductions=1, maritalStatus="single"): self.employeeName = employeeName self.taxDeductions = taxDeductions self.maritalStatus = maritalStatus...
● Valores por omisión para los parámetros de los métodos● No se declaran los tipos de datos
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Duck Typing
● Si el objeto tiene los métodos necesarios funciona● La semántica del objeto la determinan sus métodos y propiedades
>>> 1 + 12>>> 'Hola ' + 'mundo!''Hola mundo!'>>> def sumar(a, b):... return a + b... >>> sumar(10, 10)20>>> sumar('Hola ', 'mundo!')'Hola mundo!'>>> [1, 2, 3] + [4, 5, 6][1, 2, 3, 4, 5, 6]>>> sumar([1, 2, 3], [4, 5, 6])[1, 2, 3, 4, 5, 6]
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Argumentos con nombre>>> def area_triangulo(base, altura):... print "Base: %.2f" % base... print "Altura: %.2f" % altura... area = base * altura / 2.0... print "Area: %.2f" % area... >>> area_triangulo(5, 9)Base: 5.00Altura: 9.00Area: 22.50>>> area_triangulo(altura=9, base=5)Base: 5.00Altura: 9.00Area: 22.50>>> area_triangulo(9, 5)Base: 9.00Altura: 5.00Area: 22.50
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Argumentos variables>>> def funcion50(a, b, *args, **kwargs): ... print "a: %s" % a... print "b: %s" % b... print "Argumentos por posici n:"ó... i = 0... for elem in args:... print "*args[%d]: %s" % (i, args[i])... i += 1... print "Argumentos por nombre:"... for k,v in kwargs.items():... print "**kwargs['%s'] = %s" % (k,v)... >>> funcion50(1, 2, 3, 4, param1=5, param2=6)a: 1b: 2Argumentos por posici n:ó*args[0]: 3*args[1]: 4Argumentos por nombre:**kwargs['param2'] = 6**kwargs['param1'] = 5
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Argumentos variables (2)>>> def funcion60(**kwargs):... print "Argumentos por nombre solamente:"... for k, v in kwargs.items():... print "**kwargs['%s'] = %s" % (k,v)... >>> funcion60(1, 2, 3)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: funcion60() takes exactly 0 arguments (3 given)>>> funcion60(x=1, y=2, z=3)Argumentos por nombre solamente:**kwargs['y'] = 2**kwargs['x'] = 1**kwargs['z'] = 3
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Parámetros con defaults>>> def subrayar(cadena, subrayado='*'):... print cadena... print subrayado * len(cadena)... >>> subrayar('Titulo')Titulo******>>> subrayar('Titulo', '-')Titulo------
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Funciones como objetos>>> def funcion1():... print "Soy la funcion 1"... >>> funcion1()Soy la funcion 1>>> funcion_x = funcion1>>> funcion_x()Soy la funcion 1>>> def llamar_funcion_x(f):... f()... >>> llamar_funcion_x(funcion1)Soy la funcion 1>>> funcion1.a = 10>>> funcion1.a10
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Funciones como objetos (2)>>> funcion1.a = 10>>> funcion1.__doc__ = 'Solo imprime su nombre'>>> help(funcion1)Help on function funcion1 in module __main__:
funcion1() Solo imprime su nombre>>> def funcion1():... """Solo imprime su nombre"""... print 'Soy la funci n 1'ó... >>> funcion1.__doc__'Solo imprime su nombre'
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Funciones como objetos (3)>>> def operaciones(operador='+'):... def suma(a, b):... return a + b... def resta(a, b):... return a - b... if operador not in ['+', '-']:... return None... if operador == '+':... return suma... if operador == '-':... return resta... >>> operacion = operaciones('+')>>> operacion(1, 1)2>>> operacion = operaciones('-')>>> operacion(1, 1)0>>> operacion = operaciones('*')>>> operacion(1, 1)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: 'NoneType' object is not callable
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Lambdas y closures>>> lambda a,b: a + b<function <lambda> at 0x8392c34>>>> (lambda a,b: a + b)(1, 1)2>>> sumar = lambda a,b: a + b>>> sumar(1, 1)2>>> def crear_funcion_sumadora(sumando=1):... def funcion(parametro):... return parametro + sumando... return funcion... >>> sumadora_de_cincos = crear_funcion_sumadora(5)>>> sumadora_de_cincos(0)5>>> sumadora_de_cincos(10)15>>> sumadora_de_nueves = crear_funcion_sumadora(9)>>> sumadora_de_nueves(9)18
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Lambdas y closures>>> lambda a,b: a + b<function <lambda> at 0x8392c34>>>> (lambda a,b: a + b)(1, 1)2>>> sumar = lambda a,b: a + b>>> sumar(1, 1)2>>> def crear_funcion_sumadora(sumando=1):... def funcion(parametro):... return parametro + sumando... return funcion... >>> sumadora_de_cincos = crear_funcion_sumadora(5)>>> sumadora_de_cincos(0)5>>> sumadora_de_cincos(10)15>>> sumadora_de_nueves = crear_funcion_sumadora(9)>>> sumadora_de_nueves(9)18
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Comprensiones de listas
En matemáticas, es común la definición de conjuntos por comprensión:
S = { x : x in {0 .. 9}}
V = { 2, 4, 8 ... 2 }
X = { x | x en S y S es par }
2
16
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Comprensiones de listas (2)>>> S = [x**2 for x in range(10)]>>> S[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]>>> V[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768]>>> M = [x for x in S if x % 2 == 0]>>> M[0, 4, 16, 36, 64]
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Más sobre objetos...>>> class A(object):... a = 10... b = 20... def sumar(a=None, b=None):... if a is None:... a = self.a... if b is None:... b = self.b... return a + b... >>> 'a' in dir(A)True>>> 'sumar' in dir(A)True>>> hasattr(A, 'a')True>>> hasattr(A, 'sumar')True>>> hasattr(A, 'restar')False>>> attr = getattr(A, 'a')>>> attr10>>> callable(attr)False>>> attr = getattr(A, 'sumar')>>> callable(attr)True
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Más sobre objetos... (2)>>> setattr(A, 'c', 30)>>> setattr(A, 'restar', lambda a,b: a - b)>>> dir(A)['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'a', 'b', 'c', 'restar', 'sumar']>>> A.xTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: type object 'A' has no attribute>>> try:... A.x... except AttributeError:... print "No existe el atributo"... No existe el atributo
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Decoradores>>> def publicidad(func):... def crear_nueva_funcion(func):... def nueva_funcion(*args, **kwargs):... print "Esta funci n est auspiciada por el PLUG! :)"ó á... return func(*args, **kwargs)... return nueva_funcion... return crear_nueva_funcion(func)... >>> def multiplicacion(a, b):... return a * b... >>> multiplicacion = publicidad(multiplicacion)>>> multiplicacion(2, 2)Esta funci n est auspiciada por el PLUG! :)ó á4>>> @publicidad... def division(a, b):... return a / b... >>> division(8, 4)Esta funci n est auspiciada por el PLUG! :)ó á2
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Herencia>>> class Padre(object):... def __init__(self):... print "Hago cosas que hacen los padres..."... def trabajar(self):... print "Trabajando..."... >>> class Hijo(Padre):... def __init__(self):... super(Hijo, self).__init__()... print "Hago cosas que hacen los hijos..."... def jugar(self):... print "Jugando..."... >>> padre = Padre()Hago cosas que hacen los padres...>>> hijo = Hijo()Hago cosas que hacen los padres...Hago cosas que hacen los hijos...>>> padre.trabajar()Trabajando...>>> hijo.trabajar()Trabajando...>>> padre.jugar()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'Padre' object has no attribute 'jugar'>>> hijo.jugar()Jugando...
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Herencia (2)>>> dir(Padre)['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'trabajar']>>> dir(Hijo)['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'jugar', 'trabajar']>>> padre.jugar = hijo.jugar>>> padre.jugar()Jugando...>>> padre2 = Padre()Hago cosas que hacen los padres...>>> dir(padre2)['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'trabajar']>>> padre2.jugar()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'Padre' object has no attribute 'jugar'
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Herencia múltiple>>> class A(object):... a = 10... b = 20... >>> class B(object):... a = 100... c = 300... >>> class C(A, B):... d = 40... >>> x = C()>>> x.a10>>> x.b20>>> x.c300>>> x.d40
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Módulosoperaciones.py
>>> suma(1, 1)Traceback (most recent call last): File "<stdin>", line 1, in <module>NameError: name 'suma' is not defined>>> from operaciones import suma>>> suma(1, 1)2
>>> from operaciones import suma>>> suma(1, 1)2
def suma(a, b):return a + b
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Módulos (2)operaciones/
__init__.py (archivo vacio)
adicion.py
>>> from operaciones.adicion import suma>>> suma(1, 1)2
def suma(a, b):return a + b
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Módulos (3)operaciones/
__init__.py
adicion.py
>>> from operaciones import suma>>> suma(1, 1)2
def suma(a, b):return a + b
from adicion import *
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
XKCD y Python
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Django (framework web)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Django
● Nace de un periódico en Kansas, USA● Producto de la búsqueda de agilidad en el desarrollo web● Programación con plazos para periodistas (yo he vivo un poco eso!)● Autores originales: Adrian Holovaty (periodista) y Jakob Kaplan-Moss● El nombre viene de Django Reinhardt, guitarrista gitano de jazz (belga)● Adrian Holovaty es un guitarrista aficionado al jazz● La mascota es un pony :)
● Un framework web escrito en Python (2.2+)● Emplea el patrón MVC (Modelo-Vista-Controlador) como Rails on Rails● En Django el patrón MTV recibe el nombre MTV (Model-View-Template)● Las “vistas” de Django son los controladores en el MVC clásico● Las plantillas o “templates” con las “vistas” en el MVC clásico● Incluye sus propios compomentes:
● ruteador, despachador, controladores, ORM y lenguaje de plantillas
¿Qué es?
Orígenes
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
http://www.mylittledjango.com
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Modelo-Vista-Controlador
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Modelo-Vista-Controlador
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Modelo-Vista-Controlador
Características de Django
• Documentación!• Servidor HTTP de pruebas.• ORM• URL dispatcher• Templates• Admin• Forms• Middleware y Signals• Internacionalizacion• Cache• Autenticación• Muchas aplicaciones “enchufables” disponibles (killer app)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Django
● Las rutas con objetos URLConf (urls.py)● Relacionan expresiones regulares con vistas (funciones)● Se puede delegar una coincidencia a otro grupo de URLconfs
● El despachador invoca a las vistas y ejecuta middlewares● Se crea un objeto “request” que es pasado a la función (vista)● Este objeto request puede haber sido alterado por uno o más middlewares● Cuando la vista devuelve una respuesta también puede actuar el middleware
● Las vistas son funciones o métodos de clases, aunque es más raro:● Reciben un objeto “request” que representa a la petición HTTP● Devuelve un objeto “response” que representa a la respuesta HTTP● Las redirecciones, mensajes de error: 403, 404, 500 son subclases● El manejo de sesiones es mediante cookies y via middleware● El objeto sesión se instancia y se coloca dentro del request
● Django se comunica con el servidor web utilizando alguna de varias formas:● mod_python, mod_fastcgi, mod_wsgi, etc
¿Cómo es la API?
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Arquitectura
Una vista muy simple
from django.http import HttpResponse
def hello(request): return HttpResponse("Hola mundo!")
Una redirección
from django.http import HttpResponseRedirect
def ir_a_google(request): return HttpResponseRedirect("http://www.google.com")
Una vista que no usa plantillas
def current_datetime(request): now = datetime.datetime.now() html = "<html><body>Fecha actual: %s.</body></html>" % now return HttpResponse(html)
Una vista que si usa plantillasfrom django.shortcuts import render_to_responseimport datetime
def current_datetime(request): now = datetime.datetime.now() return render_to_response( 'fecha_actual.html', {'fecha_actual': now}))
La plantilla
<html><head><title`>Fecha actual</title></head><body>Fecha actual: {{ fecha_actual }}.</body></html>
La vistafrom django.shortcuts import render_to_responseimport datetime
def current_datetime(request): now = datetime.datetime.now() return render_to_response( 'fecha_actual.html', {'fecha_actual': now}))
Una plantilla más compleja
<html><head><title>Ordering notice</title></head>
<body>
<h1>Ordering notice</h1>
<p>Dear {{ person_name }},</p>
<p>Thanks for placing an order from {{ company }}. It's scheduled toship on {{ ship_date|date:"F j, Y" }}.</p>
<p>Here are the items you've ordered:</p>
<ul>{% for item in item_list %} <li>{{ item }}</li>{% endfor %}</ul>
{% if ordered_warranty %} <p>Your warranty information will be included in the packaging.</p>{% else %} <p>You didn't order a warranty, so you're on your own when the products inevitably stop working.</p>{% endif %}
<p>Sincerely,<br />{{ company }}</p>
</body></html>
Trabajando con una plantilla directamente
>>> from django import template>>> t = template.Template('My name is {{ name }}.')>>> c = template.Context({'name': 'Adrian'})>>> print t.render(c)My name is Adrian.>>> c = template.Context({'name': 'Jakob'})>>> print t.render(c)My name is Jakob.
Rendering básico de objetos if/else
for
ifequal/ifnotequal
Comentarios
Filtros
Etiquetas personalizadas
Ver: http://www.djangobook.com/en/2.0/chapter04/
Control del flujo y otros elementos
Un objeto URLconf simple
from django.conf.urls.defaults import *from mysite.views import hola
urlpatterns = patterns('', ('^hola/$', hola),)
Página principal
from mysite.views import pagina_principal
urlpatterns = patterns('', ('^$', pagina_principal), # ...)
Un URLconf más típico
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:# from django.contrib import admin# admin.autodiscover()
urlpatterns = patterns('', # Example: # (r'^mysite/', include('mysite.foo.urls')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs' # to INSTALLED_APPS to enable admin documentation: # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin: # (r'^admin/', include(admin.site.urls)),)
URLconf con expresión regular
from django.conf.urls.defaults import *From revista.views import articulos
urlpatterns = patterns('', (r'^articulo/(?P<id_articulo>\d+)$', mostrar_articulo))
La vista correspondiente
from django.shortcuts import get_object_or_404, render_to_responseFrom revista.models import Articulo
def mostrar_articulo(request, id_articulo): articulo = get_object_or_404(Articulo, id=id_articulo) return render_to_response( 'revista/articulo.html', {'articulo': articulo}))
Modelos
from django.db import models
class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField()
class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField()
class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()
Generación de SQL
BEGIN;CREATE TABLE "books_publisher" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(30) NOT NULL, "address" varchar(50) NOT NULL, "city" varchar(60) NOT NULL, "state_province" varchar(30) NOT NULL, "country" varchar(50) NOT NULL, "website" varchar(200) NOT NULL);CREATE TABLE "books_author" ( "id" serial NOT NULL PRIMARY KEY, "first_name" varchar(30) NOT NULL, "last_name" varchar(40) NOT NULL, "email" varchar(75) NOT NULL);CREATE TABLE "books_book" ( "id" serial NOT NULL PRIMARY KEY, "title" varchar(100) NOT NULL, "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id") DEFERRABLE INITIALLY DEFERRED, "publication_date" date NOT NULL);CREATE TABLE "books_book_authors" ( "id" serial NOT NULL PRIMARY KEY, "book_id" integer NOT NULL REFERENCES "books_book" ("id") DEFERRABLE INITIALLY DEFERRED, "author_id" integer NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INITIALLY DEFERRED, UNIQUE ("book_id", "author_id"));CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id");COMMIT;
Usando la API para DB (ORM)
>>> from books.models import Publisher>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',... city='Berkeley', state_province='CA', country='U.S.A.',... website='http://www.apress.com/')>>> p1.save()>>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.',... city='Cambridge', state_province='MA', country='U.S.A.',... website='http://www.oreilly.com/')>>> p2.save()>>> publisher_list = Publisher.objects.all()>>> publisher_list[<Publisher: Publisher object>, <Publisher: Publisher object>]>>> p1.book_set()[<Book: Book object>, <Book: Book object>]
Personalizando los modelos
from django.db import models
class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField()
def __unicode__(self): return self.name
class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField()
def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name)
class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()
def __unicode__(self): return self.title
Haciendo consultas
>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")[<Publisher: Apress>]
>>> Publisher.objects.filter(name__contains="press")[<Publisher: Apress>]
>>> try:... p = Publisher.objects.get(name='Apress')... except Publisher.DoesNotExist:... print "Apress isn't in the database yet."... else:... print "Apress is in the database."
>>> Publisher.objects.order_by("name")[<Publisher: O'Reilly>, <Publisher: Apress>]
>>> Publisher.objects.order_by("-name")[<Publisher: Apress>, <Publisher: O'Reilly>]
SELECT id, name, address, city, state_province, country, websiteFROM books_publisherWHERE name LIKE '%press%';
Django Admin
Django cuenta con una interfaz de administración muy pulida y generada automáticamente.En ella se pueden agregar, editar, visualizar y eliminar datos.Para verla generamos un archivo admin.py en la aplicación:
import modelsfrom django.contrib import admin
admin.site.register(models.Archivo)admin.site.register(models.Registro)
Django Admin
Django cuenta con una interfaz de administración muy pulida y generada automáticamente.En ella se pueden agregar, editar, visualizar y eliminar datos.Para verla generamos un archivo admin.py en la aplicación:
import modelsfrom django.contrib import admin
admin.site.register(models.Archivo)admin.site.register(models.Registro)
Django Admin (Login)
Django Admin (Mantenimiento)
Mi experienciaprogramando
en Pythoncon Django
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Mi experiencia usando Python
● Siempre lo miroseaba, no me animaba a aprenderlo● Empecé a usarlo en un proyecto cliente servidor:
● Servidor (PHP)● Cliente (PyGTK+)● Mensajes: XML-RPC (Web services)
● Descubrí Django● Empecé a escribir modelos en Django● Empecé a usar el admin● El frontend seguía siendo PHP
● Ingresé a Aureal y ahora lo uso a diario● Estoy escribiendo un framework en PHP 5.3 estilo Django
Produje código para proyectos en dos días
(con la supervisión y guía de gente con más experiencia)
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Mi editor de textos
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
$HOME/.vimrcsyntax onset tabstop=4set shiftwidth=4set smarttabset expandtabset softtabstop=4
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Algunas reglas sirven...
● 4 espacios por cada nivel de indentación● Evita los caracteres de tabulación● Nunca mezcles caracteres de tabulación y espacios.● Una línea en blanco entre funciones.● Seguir guía PEP-8● Programar Python idiomático
http://www.python.org/dev/peps/pep-0008/
http://mundogeek.net/traducciones/python-idiomatico/
http://mundogeek.net/traducciones/modismos-python.htm
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
...en Linuxhttp://twitpic.com/9idjb
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
...en Windowshttp://twitpic.com/bdls7
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
...en Machttp://twitpic.com/fb3ai
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Mi experiencia usando Python● ¿Qué me gusta?
● Simple y potente!● Ahora mi código es más ordenado y legible● Mi código es más modular y uso más OOP● Uso algunas (pocas) técnicas funcionales a diario● Ya me siendo cómodo con Django● Como sigo aprendiendo aún es divertido :)● Muy valorado en Ubuntu y Google● Usado mucho por startups
● ¿Qué no me gusta?● Aún no es muy conocido ¿Pyqué!? :)● Algunas construcciones de OOP se extrañan a veces:
● interfases, private, protected, final class
Feliz con el Pony! ..pero ya no me gustan mucho otros frameworks :(
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Ideas para proyectos en el PLUG
● CMS básico● Páginas estáticas● Miembros con perfil● Cada miembro tiene su propio blog● Posts destacados a la portada● Página administrada por algunos miembros● Cualquier miembro puede proponer un cambio a una página● Los administradores aceptan los cambios (no es wiki)
● Aplicación para canal de quemadores● Archivo de correos de la lista● Aplicación de noticias (estilo Reddit)● Sus ideas y contribuciones!!!
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Recursos
● Sitios web● Libros y revistas● Listas y grupos de usuarios● ¿Dónde conseguir código?● Como aprender más...
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Sitios Web
http://www.python.org http://www.python.org/doc/ http://pypi.python.org/pypi http://www.diveintopython.org http://www.djangoproject.org http://www.djangobook.com/en/2.0/
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Libros
http://mundogeek.net/tutorial-python/
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Libros
http://es.diveintopython.org
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Libros
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Libros
+
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Libros
+
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Libros
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Libros
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Libros
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Listas y grupos de usuarios
Python en Españolhttp://listas.aditel.org/listinfo/python-es
Python Perúhttp://www.python-peru.org
Python Argentina (PyAr)http://python.org.ar/pyar
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿Dónde conseguir código?
http://www.github.com http://code.google.com http://sourceforge.net http://launchpad.net http://djangosnippets.org http://djangoplugables.com http://snippets.dzone.com/tag/python
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿Cómo aprender más?
● Leer un libro, seguir un tutorial● Programando!
● Crear tu propio proyecto mascota● Participar de otros proyectos (PLUG!)● Leer el código de programas instalados● Participar del bug triaging● Crear y enviar parches a proyectos● Usarlo en tu trabajo o buscar un trabajo con Python
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Proyecto “plugbullet”
http://github.com/charlieman/plugbullet
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Proyecto “plugbullet”● Proyecto escrito en Django● Gestor de boletín de noticias● Gente de muchas comunidades y empresas se registra● Envían elementos a publicar
● Eventos, cursos, productos, servicios, noticias● Eligen en que ediciones quierne que aparezcan● Un moderador las acepta o rechaza (por edición)● Se genera automáticamente un correo y se envía● La lista de suscriptores la gestionamos con mailman● Información disponible via web● Recordatorios via Twitter en la cuenta @plugperu
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Proyecto “plugbullet”$ sudo apt-get install git-core
$ mkdir -p $HOME/proyectos/plug
$ cd $HOME/proyectos/plug
$ git-clone git://github.com/charlieman/plugbullet.gitInitialized empty Git repository in /home/gnrfan/proyectos/plug/plugbullet/.git/remote: Counting objects: 123, done.remote: Compressing objects: 100% (115/115), done.remote: Total 123 (delta 63), reused 0 (delta 0)Receiving objects: 100% (123/123), 20.62 KiB, done.Resolving deltas: 100% (63/63), done.
$ manage.py syncdb
$ manage.py runserver
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Conclusiones● Python es un lenguaje dinámico de alto nivel● Es simple y ordenado además de potente y flexible● Está disponible para casi todas las plataformas● Viende instalado en Linux● Muchos programas opensource están escritos en él● Permite combinar paradígmas
● Imperativo, Orientado a objetos, Funcional● Bibliotecas para todo tipo de cosas● Interoperatividad y extensibilidad: Java, .Net, C● Usado por grandes empresas● En crecimiento en Perú● Nos interesa usarlo en el PLUG!
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Eso es todo!!
Gracias!!!
Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
¿Preguntas?
Top Related