Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace




             ¿Porqué                                                         ?
                                                                      ...y


   Antonio Ognio Cesti
         antonio@linux.org.pe
                          Coordinador



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...
                                              ... como programador y linuxero :)

            ● 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...




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 binarios
 Windows
   (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 interactivo
  Python 2.5.2 (r252:60911, Jul 22 2009, 15:35:03)
  [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2
  Type "help", "copyright", "credits" or "license" for more information.
  >>> 1 + 1
  2
  >>> '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 * 10
  100
  >>> 874854533434324 * 24323424321424
  21279458036244482359970157376L
  >>> 9860948509850935809348504850438503485043542343434234 *
  3948309483024803480394802343243948309483094803944324343432
  38934076513063754615513224820483369228565090953244251715301778213629
  782870944071332640212573080925678121851088L
  >>> 10 / 3
  3
  >>> 10 / 3.0
  3.3333333333333335
  1024
  >>> 2 ** 8
  256
  >>> b1 = True
  >>> b1
  True
  >>> not b1
  False
  >>> 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 colores
  True
  >>> 'verde' in colores
  False
  >>> 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
  ...
  1
  2
  3
  ...
  100

Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Una clase en Java
  public 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 Python
  class 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
     >>> 1 + 1
     2
     >>> '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]

 ● Si el objeto tiene los métodos necesarios funciona
 ● La semántica del objeto la determinan sus métodos y propiedades




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.00
   Altura: 9.00
   Area: 22.50
   >>> area_triangulo(altura=9,        base=5)
   Base: 5.00
   Altura: 9.00
   Area: 22.50
   >>> area_triangulo(9, 5)
   Base: 9.00
   Altura: 5.00
   Area: 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: 1
   b: 2
   Argumentos por posición:
   *args[0]: 3
   *args[1]: 4
   Argumentos 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.a
   10

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 = { x2 : x in {0 .. 9}}
                            16
V = { 2, 4, 8 ... 2 }

X = { x | x en S y S es par }




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')
   >>> attr
   10
   >>> 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.x
   Traceback (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.a
   10
   >>>   x.b
   20
   >>>   x.c
   300
   >>>   x.d
   40




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Módulos
   operaciones.py

   def suma(a, b):
       return a + b

   >>> 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




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Módulos (2)
   operaciones/

   __init__.py      (archivo vacio)

   adicion.py

   def suma(a, b):
       return a + b


   >>> from operaciones.adicion import suma
   >>> suma(1, 1)
   2




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Módulos (3)
   operaciones/

   __init__.py

      from adicion import *

   adicion.py

     def suma(a, b):
         return a + b


   >>> from operaciones import suma
   >>> suma(1, 1)
   2




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
¿Qué es?
 ● 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




Orígenes
 ● 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 :)



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




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
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)
Django
¿Cómo es la API?
 ● 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




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Arquitectura




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
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 plantillas
from django.shortcuts import render_to_response
import 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 vista
from django.shortcuts import render_to_response
import 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 to
ship 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.
Control del flujo y otros elementos
Rendering básico de objetos

 if/else

 for

 ifequal/ifnotequal

Comentarios

Filtros

Etiquetas personalizadas

Ver: http://www.djangobook.com/en/2.0/chapter04/
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_response
From 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>]

  SELECT id, name, address, city, state_province, country, website
  FROM books_publisher
  WHERE name LIKE '%press%';



>>> 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>]
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 models
from 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 models
from django.contrib import admin

admin.site.register(models.Archivo)
admin.site.register(models.Registro)
 
Django Admin (Login)
Django Admin (Mantenimiento)
Mi experiencia
 programando
    en Python
   con Django
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




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Produje código para proyectos en dos días
(con la supervisión y guía de gente con más experiencia)
Mi editor de textos




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
$HOME/.vimrc
   syntax on
   set tabstop=4
   set shiftwidth=4
   set smarttab
   set expandtab
   set 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 Linux                                                   http://twitpic.com/9idjb




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
...en Windows                                                 http://twitpic.com/bdls7




Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
...en Mac                                                     http://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



Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
Feliz con el Pony! ..
pero ya no me gustan mucho otros frameworks :(
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ñol
    http://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.git
   Initialized 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?

Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace

¿Porqué Python? ...y Django

  • 1.
    Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace ¿Porqué ? ...y Antonio Ognio Cesti antonio@linux.org.pe Coordinador Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 2.
    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
  • 3.
    Para que meconozcan un poquito más... ... como programador y linuxero :) ● 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... Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 4.
    ¿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
  • 5.
    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
  • 6.
    GvR (Guido VanRosum) Dictador benevolente de por vida Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 7.
    ¿De donde vieneel nombre? Monty Python Flying Circus (cómicos británicos) Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 8.
    ...pero la mayoríacree que... Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 9.
    La serpiente esla mascota... Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 10.
    Logo Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 11.
    ¿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
  • 12.
    ¿Quién usa Python? Sábado17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 13.
    Implementaciones ● CPython ● Jython ● IronPython ● PyPy ● Python for S60 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 14.
    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
  • 15.
    Proyectos que lousan ● Mailman ● Anaconda ● Launchpad ● Plone ● Bittorrent Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 16.
    Proyectos que lousan ● 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
  • 17.
    Proyectos que lousan Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 18.
    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
  • 19.
    Disponibilidad de binarios Windows (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
  • 20.
    IDEs (Entornos dedesarrollo) ● 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
  • 21.
    ¿Cómo se veel 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
  • 22.
    Ejecutando el código Sábado17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 23.
    Rendimiento ● Bastantebueno 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
  • 24.
    El Zen dePython Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 25.
    El Zen dePython (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
  • 26.
    El Zen dePython (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
  • 27.
    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
  • 28.
    Intérprete interactivo Python 2.5.2 (r252:60911, Jul 22 2009, 15:35:03) [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 1 + 1 2 >>> '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
  • 29.
    Tipos y operadoresbásicos >>> 10 * 10 100 >>> 874854533434324 * 24323424321424 21279458036244482359970157376L >>> 9860948509850935809348504850438503485043542343434234 * 3948309483024803480394802343243948309483094803944324343432 38934076513063754615513224820483369228565090953244251715301778213629 782870944071332640212573080925678121851088L >>> 10 / 3 3 >>> 10 / 3.0 3.3333333333333335 1024 >>> 2 ** 8 256 >>> b1 = True >>> b1 True >>> not b1 False >>> 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
  • 30.
    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
  • 31.
    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 colores True >>> 'verde' in colores False >>> 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
  • 32.
    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 ... 1 2 3 ... 100 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 33.
    Una clase enJava public 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
  • 34.
    La misma claseen Python class 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
  • 35.
    Duck Typing >>> 1 + 1 2 >>> '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] ● Si el objeto tiene los métodos necesarios funciona ● La semántica del objeto la determinan sus métodos y propiedades Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 36.
    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.00 Altura: 9.00 Area: 22.50 >>> area_triangulo(altura=9, base=5) Base: 5.00 Altura: 9.00 Area: 22.50 >>> area_triangulo(9, 5) Base: 9.00 Altura: 5.00 Area: 22.50 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 37.
    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: 1 b: 2 Argumentos por posición: *args[0]: 3 *args[1]: 4 Argumentos por nombre: **kwargs['param2'] = 6 **kwargs['param1'] = 5 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 38.
    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
  • 39.
    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
  • 40.
    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.a 10 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 41.
    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
  • 42.
    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
  • 43.
    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
  • 44.
    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
  • 45.
    Comprensiones de listas Enmatemáticas, es común la definición de conjuntos por comprensión: S = { x2 : x in {0 .. 9}} 16 V = { 2, 4, 8 ... 2 } X = { x | x en S y S es par } Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 46.
    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
  • 47.
    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') >>> attr 10 >>> callable(attr) False >>> attr = getattr(A, 'sumar') >>> callable(attr) True Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 48.
    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.x Traceback (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
  • 49.
    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
  • 50.
    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
  • 51.
    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
  • 52.
    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.a 10 >>> x.b 20 >>> x.c 300 >>> x.d 40 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 53.
    Módulos operaciones.py def suma(a, b): return a + b >>> 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 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 54.
    Módulos (2) operaciones/ __init__.py (archivo vacio) adicion.py def suma(a, b): return a + b >>> from operaciones.adicion import suma >>> suma(1, 1) 2 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 55.
    Módulos (3) operaciones/ __init__.py from adicion import * adicion.py def suma(a, b): return a + b >>> from operaciones import suma >>> suma(1, 1) 2 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 56.
    XKCD y Python Sábado17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 57.
    Django (framework web) Sábado17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 58.
    Django ¿Qué es? ●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 Orígenes ● 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 :) Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 59.
    http://www.mylittledjango.com Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 60.
    Modelo-Vista-Controlador Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 61.
    Modelo-Vista-Controlador Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 62.
    Modelo-Vista-Controlador Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 63.
    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)
  • 64.
    Django ¿Cómo es laAPI? ● 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 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 65.
    Arquitectura Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 66.
    Una vista muysimple 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")
  • 67.
    Una vista queno 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 plantillas from django.shortcuts import render_to_response import datetime def current_datetime(request): now = datetime.datetime.now() return render_to_response( 'fecha_actual.html', {'fecha_actual': now}) )      
  • 68.
    La plantilla <html> <head><title`>Fecha actual</title></head> <body>Fechaactual: {{ fecha_actual }}.</body> </html>       La vista from django.shortcuts import render_to_response import datetime def current_datetime(request): now = datetime.datetime.now() return render_to_response( 'fecha_actual.html', {'fecha_actual': now}) )      
  • 69.
    Una plantilla máscompleja <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 to ship 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>      
  • 70.
    Trabajando con unaplantilla 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.
  • 71.
    Control del flujoy otros elementos Rendering básico de objetos if/else for ifequal/ifnotequal Comentarios Filtros Etiquetas personalizadas Ver: http://www.djangobook.com/en/2.0/chapter04/
  • 72.
    Un objeto URLconfsimple 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), # ... )
  • 73.
    Un URLconf mástí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)), )
  • 74.
    URLconf con expresiónregular 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_response From 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}) )
  • 75.
    Modelos from django.db importmodels 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()
  • 76.
    Generación de SQL BEGIN; CREATETABLE "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;
  • 77.
    Usando la APIpara 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>]
  • 78.
    Personalizando los modelos fromdjango.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
  • 79.
    Haciendo consultas >>> Publisher.objects.filter(country="U.S.A.",state_province="CA") [<Publisher: Apress>] >>> Publisher.objects.filter(name__contains="press") [<Publisher: Apress>] SELECT id, name, address, city, state_province, country, website FROM books_publisher WHERE name LIKE '%press%'; >>> 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>]
  • 80.
    Django Admin Django cuentacon 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 models from django.contrib import admin admin.site.register(models.Archivo) admin.site.register(models.Registro)  
  • 81.
    Django Admin Django cuentacon 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 models from django.contrib import admin admin.site.register(models.Archivo) admin.site.register(models.Registro)  
  • 82.
  • 83.
  • 84.
    Mi experiencia programando en Python con Django
  • 85.
    Mi experiencia usandoPython ● 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 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 86.
    Produje código paraproyectos en dos días (con la supervisión y guía de gente con más experiencia)
  • 87.
    Mi editor detextos Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 88.
    $HOME/.vimrc syntax on set tabstop=4 set shiftwidth=4 set smarttab set expandtab set softtabstop=4 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 89.
    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
  • 90.
    ...en Linux http://twitpic.com/9idjb Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 91.
    ...en Windows http://twitpic.com/bdls7 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 92.
    ...en Mac http://twitpic.com/fb3ai Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 93.
    Mi experiencia usandoPython ● ¿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 Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 94.
    Feliz con elPony! .. pero ya no me gustan mucho otros frameworks :(
  • 95.
    Ideas para proyectosen 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
  • 96.
    Recursos ● Sitiosweb ● 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
  • 97.
    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
  • 98.
    Libros http://mundogeek.net/tutorial-python/ Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 99.
    Libros http://es.diveintopython.org Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 100.
    Libros Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 101.
    Libros + Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 102.
    Libros + Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 103.
    Libros Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 104.
    Libros Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 105.
    Libros Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 106.
    Listas y gruposde usuarios Python en Español http://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
  • 107.
    ¿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
  • 108.
    ¿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
  • 109.
    Proyecto “plugbullet” http://github.com/charlieman/plugbullet Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 110.
    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
  • 111.
    Proyecto “plugbullet” $ sudo apt-get install git-core $ mkdir -p $HOME/proyectos/plug $ cd $HOME/proyectos/plug $ git-clone git://github.com/charlieman/plugbullet.git Initialized 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
  • 112.
    Conclusiones ● Pythones 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
  • 113.
    Eso es todo!! Gracias!!! Sábado 17 de Octubre 2009 – Reunión mensual PLUG – C.C. Compupalace
  • 114.
    ¿Preguntas? Sábado 17 deOctubre 2009 – Reunión mensual PLUG – C.C. Compupalace