SlideShare una empresa de Scribd logo
Universidad de Deusto
. . . .
ESIDE
Curso de Python
Universidad de Deusto
. . . .
ESIDE
Contenido
 Python básico
 Sintaxis.
 Instrucciones básicas.
 Tipo de datos.
 Orientación a objetos
 Paquetes esenciales de Python: XML, bases
de datos, programación web.
Universidad de Deusto
. . . .
ESIDE
El otro lenguaje de programación
que empieza con 'P'
 Python fue creado por Guido van Rossum
(http://www.python.org/~guido/)
 Da este nombre al lenguaje inspirado por el
popular grupo cómico británico Monty Python
 Guido creó Python durante unas
vacaciones de navidad en las que (al
parecer) se estaba aburriendo
Universidad de Deusto
. . . .
ESIDE
Hola Mundo en Python
#!/usr/bin/env python
print "Hola Mundo" # "Hola Mundo"
print "hola", "mundo" # "hola mundo"
print "Hola" + "Mundo" # "HolaMundo"
Universidad de Deusto
. . . .
ESIDE
Características de Python I
 Muy legible y elegante
 Imposible escribir código ofuscado
 Simple y poderoso
 Minimalista: todo aquello innecesario no hay que escribirlo (;, {,
}, 'n')
 Muy denso: poco código hace mucho
 Soporta objetos y estructuras de datos de alto nivel: strings,
listas, diccionarios, etc.
 Múltiples niveles de organizar código: funciones, clases,
módulos, y paquetes
 Python standard library
(http://www.python.org/doc/current/lib/lib.html) contiene un sinfín
de clases de utilidad
 Si hay áreas que son lentas se pueden reemplazar por plugins
en C o C++, siguiendo la API para extender o empotrar Python
en una aplicación, o a través de herramientas como SWIG, sip
o Pyrex.
Universidad de Deusto
. . . .
ESIDE
Características de Python II
 De scripting
 No tienes que declarar constantes y variables antes de utilizarlas
 No requiere paso de compilación/linkage
 La primera vez que se ejecuta un script de Python se compila y
genera bytecode que es luego interpretado
 Alta velocidad de desarrollo y buen rendimiento
 Código interoperable (como en Java "write once run everywhere")
 Se puede utilizar en múltiples plataforma (más aún que Java)
 Puedes incluso ejecutar Python dentro de una JVM (Jython)
 Open source
 Razón por la cual la Python Library sigue creciendo
 De propósito general
 Puedes hacer en Python todo lo que puedes hacer con C# o Java, o
más
Universidad de Deusto
. . . .
ESIDE
Peculiaridades sintácticas
 Python usa tabulación (o espaciado) para mostrar
estructura de bloques
 Tabula una vez para indicar comienzo de bloque
 Des-tabula para indicar el final del bloque
Código en C/Java Código en Python
if (x) {
if (y) {
f1();
}
f2();
}
if x:
if y:
f1()
f2()
Universidad de Deusto
. . . .
ESIDE
Python vs. Perl
 Los dos están basados en un buen
entendimiento de las herramientas necesarias
para resolver problemas
 Perl está basado en awk, sed, and shell scripting y su
misión es hacer las tareas de administradores de
sistemas más sencillas
 Python está basado e inspirando en OOP (Object-
oriented programming)
 Guido van Rossum diseñó un lenguaje simple, poderoso, y
elegante orientado a la creación de sistemas a partir de
componentes
Universidad de Deusto
. . . .
ESIDE
Python vs. Java
 Java es un lenguaje de programación muy completo
que ofrece:
 Amplio abanico de tipos de datos
 Soporte para threads
 Strong typing
 Y mucho más ...
 Python es un lenguaje de scripting:
 No ofrece strong typing
 Bueno para prototipos pero malo para grandes sistemas
 Puede cascar en tiempo de ejecución
 Todo lo que puedes hacer con Java también lo puedes hacer
con Python
 Incluso puedes acceder a través de Python a las API de Java si
usas Jython (http://www.jython.org)
Universidad de Deusto
. . . .
ESIDE
Python vs. Jython
 Python
 También llamado Cpython
 Implementación del lenguaje Python en C
 Python C API permite extender Python con librerías
realizadas en C
 Partes que requieren mayor rendimiento en Python
están implementadas en C o C++ y tan sólo
contienen una pequeña capa de Python encima
 Jython
 Implementación de Python en Java
 Permite acceder a todas las APIs de Java
 P.E. Podemos producir Swing GUIs desde Python
Universidad de Deusto
. . . .
ESIDE
¿Para qué [no] es útil?
 Python no es el lenguaje perfecto, no es bueno para:
 Programación de bajo nivel (system-programming), como
programación de drivers y kernels
 Python es de demasiado alto nivel, no hay control directo sobre
memoria y otras tareas de bajo nivel
 Aplicaciones que requieren alta capacidad de computo
 No hay nada mejor para este tipo de aplicaciones que el viejo C
 Python es ideal:
 Como lenguaje "pegamento" para combinar varios componentes
juntos
 Para llevar a cabo prototipos de sistema
 Para la elaboración de aplicaciones cliente
 Para desarrollo web y de sistemas distribuidos
 Para el desarrollo de tareas científicas, en los que hay que simular
y prototipar rápidamente
Universidad de Deusto
. . . .
ESIDE
Instalar Python
 Bajar la última versión de Python (2.4) de
http://www.python.org/download/
 Para Windows ejecutar instalador
 Opcionalmente bajarse extensiones Python para Windows32
de: http://starship.python.net/crew/mhammond/
 Podemos editar nuestro código Python con Notepad2 (Alt-H):
http://www.flos-freeware.ch/notepad2.html
 Para Linux:
 En Debian Sarge: apt-get install python2.4
 Para Fedora y Mandrake se pueden obtener los rpms de:
http://www.python.org/2.4/rpms.html
 rpm -iv python2.4-2.4-1pydotorg.i386.rpm
Universidad de Deusto
. . . .
ESIDE
Usando Python desde línea de
comando
 Para arrancar el intérprete (Python interactivo) ejecutar:
C:>python
Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32
bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more
information.
>>>
 Un comando simple:
>>> print "Hola Mundo"
Hola Mundo
>>>
 Para salir del intérprete Ctrl-D (en Linux) o Ctrl-Z (en Windows) o:
>>> import sys
>>> sys.exit()
$
Universidad de Deusto
. . . .
ESIDE
Ejecutando programa
holamundo.py
 Python desde script:
 Guardar las siguientes sentencias en fichero:
holamundo.py
#!/usr/bin/env python
print “Kaixo Mundua!"
 Ejecutar el script desde línea de comando:
$ python helloworld.py
Kaixo Mundua!
$
Universidad de Deusto
. . . .
ESIDE
Sentencias y bloques
 Las sentencias acaban en nueva línea, no en ;
 Los bloques son indicados por tabulación que sigue a una sentencia
acabada en ':'. E.j. (bloque.py):
# comentarios de línea se indican con carácter '#'
name = "Diego1" # asignación de valor a variable
if name == "Diego":
print "Aupa Diego"
else:
print "¿Quién eres?"
print "¡No eres Diego!"
$ python bloque.py
¿Quién eres?
¡No eres Diego!
Universidad de Deusto
. . . .
ESIDE
Identificadores
 Los identificadores sirven para nombrar variables, funciones y
módulos
 Deben empezar con un carácter no numérico y contener letras,
números y '_'
 Python es case sensitive (sensible a la capitalización)
 Palabras reservadas:
 and elif global or assert else if pass break except
import print class exec in raise continue finally
is return def for lambda try del from not while
 Variables y funciones delimitadas por __ corresponden a símbolos
implícitamente definidos:
 __name__ nombre de función
 __doc__ documentación sobre una función
 __init__() constructor de una clase
 __dict__, diccionario utilizado para guardar los atributos de un
objeto
Universidad de Deusto
. . . .
ESIDE
Tipos de datos I
 Numéricos (integer, long integer, floating-point, and
complex)
>>> x = 4
>>> int (x)
4
>>> long(x)
4L
>>> float(x)
4.0
>>> complex (4, .2)
(4+0.2j)
Universidad de Deusto
. . . .
ESIDE
Tipos de datos II
 Strings, delimitados por un par de (', " ,""")
 Dos string juntos sin delimitador se unen
>>> print "Hi" "there"
Hithere
 Los códigos de escape se expresan a través de '':
>>>print 'n'
 Raw strings
>>> print r'n' # no se 'escapa' n
 Lo mismo ' que ", p.e. "[foo]" r'[foo]'
 Algunos de los métodos que se pueden aplicar a un string son:
>>> len('La vida es mucho mejor con Python.')
>>> 34
>>> 'La vida es mucho mejor con Python.'.upper()
'LA VIDA ES MUCHO MEJOR CON PYTHON'
>>> "La vida es mucho mejor con Python".find("Python")
27
>>> "La vida es mucho mejor con Python".find('Perl')
-1
>>> 'La vida es mucho mejor con Python'.replace('Python', 'Jython')
'La vida es mucho mejor con Jython'
Universidad de Deusto
. . . .
ESIDE
Tipos de datos III
 El módulo string de la Python library define
métodos para manipulación de strings:
>>> import string
>>> s1 = 'La vida es mejor con Python'
>>> string.find(s1, 'Python')
21
 '%' es el operador de formateo de cadenas:
>>> provincia = 'Araba'
>>> "La capital de %s es %s" % (provincia,
"Gasteiz")
'La capital de Araba es Gasteiz'
 Los caracteres de formateo son los mismos que en C, p.e. d, f, x
Universidad de Deusto
. . . .
ESIDE
Tipos de datos IV
 Para poder escribir caracteres con
acentos es necesario introducir la
siguiente línea al comienzo de un
programa Python:
 # -*- coding: iso-8859-1 -*-
 Los strings en formato unicode se
declaran precediendo el string de una
‘u’:
 print u'¿Qué tal estás?'
Universidad de Deusto
. . . .
ESIDE
Tipos de datos V
 Listas []
 Indexadas por un entero comienzan en 0:
>>> meses = ["Enero", "Febrero"]
>>> print meses[0]
Enero
>>> meses.append("Marzo")
>>> print meses
['Enero', 'Febrero', 'Marzo']
 Dos puntos (:) es el operador de rodajas, permite trabajar con una
porción de la lista, el elemento indicado por el segundo parámetro no se
incluye:
>>> print meses[1:2]
['Febrero']
 Más (+) es el operador de concatenación:
>>> print meses+meses
['Enero', 'Febrero', 'Marzo', 'Enero', 'Febrero',
'Marzo']
Universidad de Deusto
. . . .
ESIDE
Tipos de datos VI
 Las listas pueden contener cualquier tipo de objetos Python:
>>> meses.append (meses)
>>> print meses
['Enero', 'Febrero', 'Marzo', ['Enero', 'Febrero', 'Marzo' ]]
>>> meses.append(1)
['Enero', 'Febrero', 'Marzo', ['Enero', 'Febrero', 'Marzo' ], 1]
 Para añadir un elemento a una lista:
>>> items = [4, 6]
>>> items.insert(0, -1)
>>> items
[-1, 4, 6]
 Para usar una lista como una pila, se pueden usar append y pop:
>>> items.append(555)
>>> items [-1, 4, 6, 555]
>>> items.pop()
555
>>> items [-1, 4, 6]
Universidad de Deusto
. . . .
ESIDE
Tipos de datos VII
 Tuplas (), lo mismo que listas, pero no se pueden modificar
D:>python
Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)
on win32
Type "help", "copyright", "credits" or "license" for more
information.
>>> mitupla = ('a', 1, "hola")
>>> mitupla[2]
'hola'
>>> dir(mitupla)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__',
'__init__', '__iter__', '__le__', '__len__', '__lt__',
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__rmul__', '__setattr__', '__str__']
Universidad de Deusto
. . . .
ESIDE
Tipos de datos VIII
 Diccionarios {} arrays asociativos o mapas, indexados por una clave, la
cual puede ser cualquier objeto Python, aunque normalmente es una
tupla:
>>> mydict = {"altura" : "media", "habilidad" :
"intermedia", "salario" : 1000 }
>>> print mydict
{altura': 'media', 'habilidad': 'intermedia', 'salario':
1000}
>>> print mydict["habilidad"]
intermedia
 Puedes comprobar la existencia de una clave en un diccionario usando
has_key:
if mydict.has_key('altura'):
print 'Nodo encontrado'
 Lo mismo se podría hacer:
if 'altura' in mydict:
print 'Nodo encontrado'
Universidad de Deusto
. . . .
ESIDE
Control de flujo: condicionales
 E.j. (condicional.py)
q = 4
h = 5
if q < h :
print "primer test pasado"
elif q == 4:
print “q tiene valor 4”
else:
print "segundo test pasado"
>>> python condicional.py
primer test pasado
 Operadores booleanos: "or," "and," "not"
 Operadores relacionales: ==, >, <, !=
Universidad de Deusto
. . . .
ESIDE
Control de flujo: bucles
 for se utiliza para iterar sobre los miembros de una
secuencia
 Se puede usar sobre cualquier tipo de datos que sea una
secuencia (lista, tupla, diccionario)
 Ej. bucle.py
for x in range(1,5):
print x
$ python bucle.py
1 2 3 4
 La función range crea una secuencia descrita por
([start,] end [,step]), donde los campos
start y step son opcionales. Start es 0 y step
es 1 por defecto.
Universidad de Deusto
. . . .
ESIDE
Control de flujo: bucles
 while es otra sentencia de repetición. Ejecuta un bloque de
código hasta que una condición es falsa.
 break nos sirve para salir de un bucle
 Por ejemplo:
reply = 'repite'
while reply == 'repite':
print 'Hola'
reply = raw_input('Introduce "repite" para
hacerlo de nuevo: ')
Hola
Introduce "repite" para hacerlo de nuevo: repite
Hola
Introduce "repite" para hacerlo de nuevo: adiós
Universidad de Deusto
. . . .
ESIDE
Funciones
 Una función se declara usando la palabra clave def
# funcionsimple.py
def myfunc(a,b):
sum = a + b
return sum
print myfunc (5,6)
$ python funcionsimple.py
11
 A una función se le pueden asignar parámetros por defecto:
# funcionvaloresdefecto.py
def myfunc(a=4,b=6):
sum = a + b
return sum
print myfunc()
print myfunc(b=8) # a es 4, sobreescribir b a 8
$ python funcion.py
10
12
Universidad de Deusto
. . . .
ESIDE
Funciones
 Listas de argumentos y argumentos basados en palabras clave:
# funcionargumentosvariablesyconclave.py
def testArgLists_1(*args, **kwargs):
print 'args:', args
print 'kwargs:', kwargs
testArgLists_1('aaa', 'bbb', arg1='ccc', arg2='ddd')
def testArgLists_2(arg0, *args, **kwargs):
print 'arg0: "%s"' % arg0
print 'args:', args
print 'kwargs:', kwargs
print '=' * 40
testArgLists_2('un primer argumento', 'aaa', 'bbb', arg1='ccc',
arg2='ddd')
 Visualizaría:
args: ('aaa', 'bbb')
kwargs: {'arg1': 'ccc', 'arg2': 'ddd'}
========================================
arg0: "un primer argumento"
args: ('aaa', 'bbb')
kwargs: {'arg1': 'ccc', 'arg2': 'ddd'}
Universidad de Deusto
. . . .
ESIDE
Clases
 Una clase contiene una colección de métodos.
Cada método contiene como primer
parámetro (self) que hace referencia a un
objeto
 self equivalente a this en C++
 Existe un soporte limitado para variables privadass
mediante name mangling.
 Un identificador __spam es reemplazado por
_classname__spam.
 El identificador es todavía accesible por
_classname__spam.
 En Python se soporta la herencia múltiple
Universidad de Deusto
. . . .
ESIDE
Clases
# clasepinguinos.py
class PenguinPen:
def __init__(self):
self.penguinCount = 0
def add (self, number = 1):
""" Add penguins to the pen. The default number is 1 """
self.penguinCount = self.penguinCount + number
def remove (self, number = 1):
""" Remove one or more penguins from the pen """
self.penguinCount = self.penguinCount - number
def population (self):
""" How many penguins in the pen? """
return self.penguinCount
def __del__(self):
pass
penguinPen = PenguinPen()
penguinPen.add(5) # Tux y su familia
print penguinPen.population()
Universidad de Deusto
. . . .
ESIDE
Más clases
# clasesherencia.py
class Basic:
def __init__(self, name):
self.name = name
def show(self):
print 'Basic -- name: %s' % self.name
class Special(Basic): # entre paréntesis la clase base
def __init__(self, name, edible):
Basic.__init__(self, name) # se usa Basic para referir a
self.upper = name.upper() # clase base
self.edible = edible
def show(self):
Basic.show(self)
print 'Special -- upper name: %s.' % self.upper,
if self.edible:
print "It's edible."
else:
print "It's not edible."
def edible(self):
return self.edible
Universidad de Deusto
. . . .
ESIDE
Probando clases
obj1 = Basic('Manzana')
obj1.show()
print '=' * 30
obj2 = Special('Naranja', True)
obj2.show()
 Visualizaría:
Basic -- name: Manzana
==============================
Basic -- name: Naranja
Special -- upper name: NARANJA. It's edible.
Universidad de Deusto
. . . .
ESIDE
Excepciones
 Cada vez que un error ocurre se lanza una excepción, visualizándose
un extracto de la pila del sistema. E.j. excepcion.py:
#!/usr/bin/python
print a
$ python exception.py
Traceback (innermost last): File "exception.py", line 2, in
? print a NameError: a
 Para capturar la excepción se usa except:
try:
fh=open("new.txt", "r")
except IOError, e:
print e
$ python excepcion.py
[Errno 2] No such file or directory: 'new.txt'
 Puedes lanzar tu propia excepción usando el comando raise:
raise MyException
raise SystemExitModules
Universidad de Deusto
. . . .
ESIDE
Excepciones personalizadas
# excepcionpersonalizada.py
class E(RuntimeError):
def __init__(self, msg):
self.msg = msg
def getMsg(self):
return self.msg
try:
raise E('mi mensaje de error')
except E, obj:
print 'Msg:', obj.getMsg()
 Visualizaría:
Msg: mi mensaje de error
Universidad de Deusto
. . . .
ESIDE
Módulos
 Un módulo es una colección de métodos en un fichero que
acaba en .py. El nombre del fichero determina el nombre del
módulo en la mayoría de los casos.
 E.j. modulo.py:
def one(a):
print "in one"
def two (c):
print "in two"
 Uso de un módulo:
>>> import modulo
>>> dir(modulo) # lista contenidos módulo
['__builtins__', '__doc__', '__file__', '__name__',
'one', 'two']
>>> modulo.one(2)
in one
Universidad de Deusto
. . . .
ESIDE
Módulos II
 import hace que un módulo y su contenido sean
disponibles para su uso.
 Algunas formas de uso son:
import test
 Importa modulo test. Referir a x en test con "test.x".
from test import x
 Importa x de test. Referir a x en test con "x".
from test import *
 Importa todos los objetos de test. Referir a x en test con
"x".
import test as theTest
 Importa test; lo hace disponible como theTest. Referir a
objecto x como "theTest.x".
Universidad de Deusto
. . . .
ESIDE
Paquetes I
 Un paquete es una manera de organizar un conjunto de
módulos como una unidad. Los paquetes pueden a su vez
contener otros paquetes.
 Para aprender como crear un paquete consideremos el siguiente
contenido de un paquete:
package_example/
package_example/__init__.py
package_example/module1.py
package_example/module2.py
 Y estos serían los contenidos de los ficheros correspondientes:
# __init__.py
# Exponer definiciones de módulos en este paquete.
from module1 import class1
from module2 import class2
Universidad de Deusto
. . . .
ESIDE
Paquetes II
# module1.py
class class1:
def __init__(self):
self.description = 'class #1'
def show(self):
print self.description
# module2.py
class class2:
def __init__(self):
self.description = 'class #2'
def show(self):
print self.description
Universidad de Deusto
. . . .
ESIDE
Paquetes III
# testpackage.py
import package_example
c1 = package_example.class1()
c1.show()
c2 = package_example.class2()
c2.show()
 Visualizaría:
class #1
class #2
 La localización de los paquetes debe especificarse o bien a
través de la variable de entorno PYTHONPATH o en código del
script mediante sys.path
Universidad de Deusto
. . . .
ESIDE
Paquetes IV
 Como en Java el código de un paquete puede recogerse en un .zip:
>>> import zipfile
>>> a=zipfile.PyZipFile('mipackage.zip', 'w', zipfile.ZIP_DEFLATED)
>>> a.writepy('package_example')
>>> a.close()
>>> ^Z
 Luego lo puedes importar y usar insertando su path en sys.path o
alternativamente añadiendo a la variable de entorno PYTHONPATH una
referencia al nuevo .zip creado:
$ mkdir prueba; cp mipackage.zip prueba
$ export PYTHONPATH=/home/dipina/examples/prueba/mipackage.zip
>>> import sys # esta y la siguiente no hacen falta si se ha
inicializado PYTHONPATH
>>> sys.path.insert(0, '/home/dipina/examples/prueba/mipackage.zip')
>>> import package_example
>>> class1 = package_example.module1.class1()
>>> class1.show()
class #1
>>> ^Z
Universidad de Deusto
. . . .
ESIDE
Manejo de ficheros
 Leer un fichero (leerfichero.py)
fh = open("holamundo.py") # open crea un objeto de tipo fichero
for line in fh.readlines() : # lee todas las líneas en un fichero
print line,
fh.close()
$ python leerfichero.py
#!/usr/bin/python
print "Hola mundo"
 Escribir un fichero (escribirfichero.py)
fh = open("out.txt", "w")
fh.write ("estamos escribiendo ...n")
fh.close()
$ python escribirfichero.py
$ cat out.txt
estamos escribiendo ...
Universidad de Deusto
. . . .
ESIDE
Más sobre print
 print (printredirect.py)
 stdout en Python es sys.stdout, stdin es sys.stdin:
import sys
class PrintRedirect:
def __init__(self, filename):
self.filename = filename
def write(self, msg):
f = file(self.filename, 'a')
f.write(msg)
f.close()
sys.stdout = PrintRedirect('tmp.log')
print 'Log message #1'
print 'Log message #2'
print 'Log message #3'
Universidad de Deusto
. . . .
ESIDE
Variables globales en Python
 Usar identificador global para referirse a variable global:
# variableglobal.py
NAME = "Manzana"
def show_global():
name = NAME
print '(show_global) nombre: %s' % name
def set_global():
global NAME
NAME = 'Naranja'
name = NAME
print '(set_global) nombre: %s' % name
show_global()
set_global()
show_global()
 Lo cual visualizaría:
(show_global) nombre: Manzana
(set_global) nombre: Naranja
(show_global) nombre: Naranja
Universidad de Deusto
. . . .
ESIDE
Serialización de objetos
 Pickle: Python Object Serialization
 El módulo pickle implementa un algoritmo para
la serialización y deserialización de objetos Python
 Para serializar una jerarquía de objetos, creas un
Pickler, y luego llamas al método dump(), o
simplemente invocas el método dump() del módulo
pickle
 Para deserializar crear un Unpickler e invocas su
método load() method, o simplemente invocas el
método load() del módulo pickle
 Se serializa el contenido del objeto __dict__ de
la clase, si se quiere cambiar este comportamiento
hay que sobrescribir los métodos
__getstate__() y __setstate__().
Universidad de Deusto
. . . .
ESIDE
Serialización de objetos:
Ejemplo pickle
import pickle # pickleunpickle.py
class Alumno:
def __init__(self, dni, nombre, apellido1, apellido2):
self.dni = dni
self.nombre = nombre
self.apellido1 = apellido1
self.apellido2 = apellido2
def __str__(self):
return "DNI: " + self.dni + "ntNombre: " + self.nombre + "ntApellido1: " +
self.apellido1 + "ntApellido2: " + self.apellido2 + "n"
def get_dni(self):
return self.dni
def get_nombre(self):
return self.nombre
def get_apellido1(self):
return self.apellido1
def get_apellido2(self):
return self.apellido2
alum = Alumno("44567832P", "Diego", "Lz. de Ipina", "Gz. de Artaza")
print "Alumno a serializar:n", alum
f = open("Alumno.db", 'w')
pickle.dump(alum, f)
f.close()
f = open("Alumno.db", "r")
alum2 = pickle.load(f)
f.close()
print alum2.get_dni()
print "Alumno leido:n", alum2
Universidad de Deusto
. . . .
ESIDE
Serialización de objetos: Otro
ejemplo más sofisticado
 Revisar ejemplos:
 picklingexample.py
 unpicklingexample.py
 Utilizan los métodos especiales
__setstate__() y
__getstate__()
Universidad de Deusto
. . . .
ESIDE
Serialización de objetos
 El módulo shelve define diccionarios persistentes,
las claves tienen que ser strings mientras que los
valores pueden ser cualquier objeto que se puede
serializar con pickle (ala gdbm)
import shelve
d = shelve.open(filename) # abre un fichero
d[key] = data # guarda un valor bajo key
data = d[key] # lo recupera
del d[key] # lo borra
d.close()
Universidad de Deusto
. . . .
ESIDE
Juego TresEnRaya Modo
Texto
 Implementar el juego de tres en raya en la clase JuegoTresEnRaya
con métodos:
 resetGame
 __elegirMarcaMaquina
 __verTablero
 __hayGanador
 jugar
 Permitir jugar sólo a aquellos usuarios que hagan login previamente a
través de la clase RegistroJugadores
 Registrar estadísticas de juego primero en memoria con un diccionario y
luego de manera persistente con un shelf.
 Los métodos soportados por esta clase serán:
 registrarJugador
 login
 registrarVictoria | registrarEmpate | registrarPerdida
 getEstadisticas
Universidad de Deusto
. . . .
ESIDE
Programación de BD en
Python
 Lo que es JDBC en Java es DB API en Python
 Información detallada en: http://www.python.org/topics/database/
 Para conectarnos a una base de datos usamos el método connect del
módulo de base de datos utilizado que devuelve un objeto de tipo
conection
 El objeto connection define el método cursor() que sirve para
recuperar un cursor de la BD
 Otros métodos definidos en connection son close(), commit(),
rollback()
 El objeto cursor define entre otros los siguientes métodos:
 execute() nos permite enviar una sentencia SQL a la BD
 fetchone() recuperar una fila
 fetchall() recuperar todas las filas
 Hay varios módulos que implementan el estándar DB-API:
 DCOracle (http://www.zope.org/Products/DCOracle/) creado por Zope
 MySQLdb (http://sourceforge.net/projects/mysql-python)
 MySQL-python.exe-1.2.0.win32-py2.4.zip para Windows
 MySQL-python-1.2.0.tar.gz para Linux
 apt-get install python2.4-mysqldb
 Etc.
Universidad de Deusto
. . . .
ESIDE
 La base de datos open source más popular
 Desarrollada por MySQL AB, compañía sueca cuyo negocio se basa
en labores de consultoría sobre MySQL
 http://www.mysql.com
 Diseñada para:
 Desarrollo de aplicaciones críticas
 Sistemas con altos requerimientos de carga
 Ser embebida en software
 Existen otras buenas alternativas open source como PostGreSQL
(http://www.postgresql.org/)
 MySQL 5.0 (development release) soporta procedimientos
almacenados
 Desde MySQL 4.1 (production release) se soportan subqueries
Universidad de Deusto
. . . .
ESIDE
Instalación MySQL
 En la siguiente URL se pueden obtener RPMs y
ejecutables para instalar la última versión de
producción de MySQL (4.1) tanto en Linux como
Windows:
 http://dev.mysql.com/
downloads/mysql/4.0.html
 En las distribuciones que soportan apt-get,
instalar con el comando:
apt-get install mysql-server php4-mysql
 Con yum:
yum install mysql-server mysql
Universidad de Deusto
. . . .
ESIDE
Ejemplo programación BD en
Python con MySQL I
 Creamos una base de datos de nombre deusto a la que podemos hacer login con
usuario deusto y password deusto, a través del siguiente SQL:
CREATE DATABASE deusto;
GRANT ALTER, SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON deusto.*
TO deusto@'%'
IDENTIFIED BY 'deusto';
GRANT ALTER, SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON deusto.*
TO deusto@localhost
IDENTIFIED BY 'deusto';
use deusto;
CREATE TABLE EVENTOS(ID int(11) NOT NULL PRIMARY KEY,
NOMBRE VARCHAR(250), LOCALIZACION VARCHAR(250), FECHA bigint(20),
DESCRIPCION VARCHAR(250));
INSERT INTO EVENTOS VALUES (0, 'SEMANA ESIDE', 'ESIDE-DEUSTO', 0,
'Charla sobre Python');
Universidad de Deusto
. . . .
ESIDE
Ejemplo programación BD en
Python con MySQL II
# db/accesodbeventos.py
import MySQLdb, time, string, _mysql, _mysql_exceptions
def executeSQLCommand(cursor, command):
rowSet = []
command = string.strip(command)
if len(command):
try:
cursor.execute(command) # Ejecuta el comando
if string.lower(command).startswith('select'): # si es select
lines = cursor.fetchall() # recuperar todos los resultados
for line in lines:
row = []
for column in line:
row.append(column)
rowSet.append(row)
except _mysql_exceptions.ProgrammingError, e:
print e
sys.exit()
return rowSet
Universidad de Deusto
. . . .
ESIDE
Ejemplo programación BD en
Python con MySQL III
if __name__ == '__main__':
db=MySQLdb.connect(host="localhost",user="deusto",
passwd="deusto", db="deusto")
cursor = db.cursor()
executeSQLCommand(cursor, "update eventos set fecha=" +
str(time.time()*1000))
rowSet = executeSQLCommand(cursor, "select * from eventos")
for row in rowSet:
print row
del cursor
 Visualizando lo siguiente:
$ python accesodbeventos.py
[0L, 'SEMANA ESIDE', 'ESIDE-DEUSTO', 1110133067870L, 'Charla sobre Python']
[1L, 'CURSO J2EE', 'CESINE', 1110133067870L, 'Curso sobre ...']
Universidad de Deusto
. . . .
ESIDE
Programación de expresiones
regulares I
 A través del módulo re, Python permite el uso de expresiones
regulares similares a como se hace en Perl (una razón más para
moverse de Perl a Python)
# regex/procesaUrlConRe.py
import re, urllib, sys
if len(sys.argv) <= 4:
print "Usage: procesaUrl <url-a-procesar> <palabra-a-
reemplazar> <nueva-palabra> <fichero-html-a-crear>"
sys.exit(0)
print sys.argv[1]
s = (urllib.urlopen(sys.argv[1])).read() # lee el contenido de
una url
# reemplaza todas las ocurrencias de "Artaza" por "artaza"
t = re.sub(sys.argv[2], sys.argv[3], s)
backupFile = open(sys.argv[4], "w")
backupFile.write(t)
backupFile.close()
print 'Fichero ' + sys.argv[4] + ' escrito con contenido de
url: ' + sys.argv[1] + ' al reemplazar palabra ' +
sys.argv[2] + ' con palabra ' + sys.argv[3]
Universidad de Deusto
. . . .
ESIDE
Programación de expresiones
regulares II
# conseguir el titulo del documento HTML
tmatch = re.search(r'<title>(.*?)</title>', s, re.IGNORECASE)
if tmatch:
title = tmatch.group(1)
print 'Titulo de pagina ' + sys.argv[1] + ' es: ' + title
# extraer lista de enlaces url:
pat = re.compile(r'(http://[w-]*[.w-]+)')
addrs = re.findall(pat, s)
print 'La lista de enlaces encontrados en esta pagina es: '
for enlace in addrs:
print enlace
Universidad de Deusto
. . . .
ESIDE
Programación de sistemas
 Python permite la programación de sistema tanto accediendo a
la API de Windows
(http://www.python.org/windows/index.html) como a las
llamadas al sistema de UNIX (módulo os)
 El módulo os nos da acceso a:
 El entorno del proceso: getcwd(), getgid(), getpid()
 Creación de ficheros y descriptores: close(), dup(), dup2(),
fstat(), open(), pipe(), stat(), socket()
 Gestión de procesos: execle(), execv(), kill(), fork(),
system()
 Gestión de memoria mmap()
 El módulo threading permite la creación de threads en
Python
 Revisar ejemplo del servidor web en Python
 Siguiente transparencia muestra cómo usar módulo threading
para recuperar el contenido de varias urls
Universidad de Deusto
. . . .
ESIDE
Ejemplo threads
#!/usr/bin/env python
import threading # threading/ejemplothreading.py
import urllib
class FetchUrlThread(threading.Thread):
def __init__(self, url, filename):
threading.Thread.__init__(self)
self.url = url
self.filename = filename
def run(self):
print self.getName(), "Fetching ", self.url
f = open(self.getName()+self.filename, "w")
content = urllib.urlopen(self.url).read()
f.write(content)
f.close()
print self.getName(), "Saved in ", (self.getName()+self.filename)
urls = [ ('http://www.python.org', 'index.html'),
('http://www.google.es', 'index.html') ]
# Recuperar el contenido de las urls en diferentes threads
for url, file in urls:
t = FetchUrlThread(url, file)
t.start()
Universidad de Deusto
. . . .
ESIDE
¿Por qué usar XML?
 Un documento XML puede ser
fácilmente procesado y sus datos
manipulados
 Existen APIs para procesar esos
documentos en Java, C, C++, Perl.. (y
por supuesto Python)
 XML define datos portables al igual que
Java define código portable
Universidad de Deusto
. . . .
ESIDE
Componentes documento XML
 Los documentos XML constan de:
 Instrucciones de procesamiento
(processing instructions – PI)
 Declaraciones de tipo de documento
 Comentarios
 Elementos
 Referencias a entidades
 Secciones CDATA
Universidad de Deusto
. . . .
ESIDE
Ejemplo Documento XML
<?xml version="1.0"?>
<!DOCTYPE mensaje SYSTEM “labgroups.dtd">
<lab_group>
<student_name dni=“44670523">
Josu Artaza
</student_name>
<student_name dni=“44543211">
Nuria Buruaga
</student_name>
<student_name dni=“23554521" tutor=“33456211">
Inga Dorsman
</student_name>
</lab_group>
Universidad de Deusto
. . . .
ESIDE
XML Parsing
Documento
XML
XML DTD
XML Schema
Parser XML
Aplicación
XML
Universidad de Deusto
. . . .
ESIDE
XML Parsing (cont)
 SAX
 Define interfaz dirigido por eventos (event-driven)
para el procesamiento de un documento XML
 Definido por David Megginson y lista correo XML-
DEV : http://www.megginson.com/SAX
 DOM
 Provee una representación de un documento XML
en forma de un árbol
 Carga todo el documento XML en memoria
 http://www.w3.org/DOM
Universidad de Deusto
. . . .
ESIDE
Simple API for XML: SAX
 Define un interfaz común implementado por
muchos XML Parsers
 Es el estándar de-facto para procesamiento
de XML basado en eventos
 SAX no es un parseador de XML
 SAX2 añade soporte para XML Namespaces
 La especificación de SAX 2.0/Java está en:
http://www.megginson.com/SAX/Java/index.
html
Universidad de Deusto
. . . .
ESIDE
Características de SAX
 Analizador o parser SAX:
 Detecta cuándo empieza y termina un elemento o el
documento, o un conjunto de caracteres, etc. (genera
eventos)
 Gestiona los espacios de nombres
 Comprueba que el documento está bien formado
 Las aplicaciones necesitan implementar manejadores
de los eventos notificados
 SAX lee secuencialmente de principio a fin, sin cargar
todo el documento en memoria
 Ventaja: eficiencia en cuanto al tiempo y la
memoria empleados en el análisis
 Desventaja: no disponemos de la estructura en
árbol de los documentos
Universidad de Deusto
. . . .
ESIDE
¿Cómo funciona SAX?
XML Document
<?xml version=“1.0”?>
<addressbook>
</addressbook>
<person>
</person>
<name>Diego Ipiña</name>
<email>dipina@deusto.es</email>
<person>
</person>
<name>Asier Perallos</name>
<email>perallos@deusto.es</email>
SAX Objects
Parser startDocument
Parser startElement
Parser startElement & characters
Parser startElement & characters
Parser endElement
Parser startElement
Parser startElement & characters
Parser startElement & characters
Parser endElement
Parser endElement & endDocument
Universidad de Deusto
. . . .
ESIDE
Programación en XML con SAX
 Soporte para SAX en Python es ofrecido por el
módulo xml.sax de la Python Library
 Define 2 métodos:
 make_parser([parser_list])
 Crea y devuelve un objeto SAX XMLReader
 parse(filename_or_stream, handler[,
error_handler])
 Crea un parser SAX y lo usa para procesar el documento a
través de un handler
 El módulo xml.sax.xmlreader define readers
para SAX
 El módulo xml.sax.handler define manejadores
de eventos para SAX: startDocument,
endDocument, starElement, endElement
Universidad de Deusto
. . . .
ESIDE
Ejemplo procesamiento SAX I
# xml/ElementCounterSAX.py
# Ejecutar: python ElementCounterSAX.py Cartelera.xml
import sys
from xml.sax import make_parser, handler
class ElementCounter(handler.ContentHandler):
def __init__(self):
self._elems = 0
self._attrs = 0
self._elem_types = {}
self._attr_types = {}
def startElement(self, name, attrs):
self._elems = self._elems + 1
self._attrs = self._attrs + len(attrs)
self._elem_types[name] = self._elem_types.get(name, 0) + 1
for name in attrs.keys():
self._attr_types[name] = self._attr_types.get(name, 0) + 1
Universidad de Deusto
. . . .
ESIDE
Ejemplo procesamiento SAX II
def endDocument(self):
print "There were", self._elems, "elements."
print "There were", self._attrs, "attributes."
print "---ELEMENT TYPES"
for pair in self._elem_types.items():
print "%20s %d" % pair
print "---ATTRIBUTE TYPES"
for pair in self._attr_types.items():
print "%20s %d" % pair
parser = make_parser()
parser.setContentHandler(ElementCounter())
parser.parse(sys.argv[1])
Universidad de Deusto
. . . .
ESIDE
W3C Document Object Model
(DOM)
 Documentos XML son tratados como un
árbol de nodos
 Cada elemento es un “nodo”
 Los elementos hijos y el texto contenido
dentro de un elemento son subnodos
 W3C DOM Site:
http://www.w3.org/DOM/
Universidad de Deusto
. . . .
ESIDE
Características DOM
 Documento se carga totalmente en memoria
en una estructura de árbol
 Ventaja: fácil acceder a datos en función
de la jerarquía de elementos, así como
modificar el contenido de los documentos e
incluso crearlos desde cero.
 Desventaja: coste en tiempo y memoria
que conlleva construir el árbol
Universidad de Deusto
. . . .
ESIDE
W3C XML DOM Objects
 Element – un elemento XML
 Attribute – un attributo
 Text – texto contenido en un elemento o atributo
 CDATAsection – sección CDATA
 EntityReference – Referencia a una entidad
 Entity – Indicación de una entidad XML
 ProcessingInstruction – Una instrucción de procesamiento
 Comment – Contenido de un comentario de XML
 Document – El objeto documento
 DocumentType – Referencia al elemento DOCTYPE
 DocumentFragment – Referencia a fragmento de documento
 Notation – Contenedor de una anotación
Universidad de Deusto
. . . .
ESIDE
Objetos relacionados con
Nodos
 Node – un nodo en el árbol de un
documento
 NodeList – una lista de objetos nodos
 NamedNodeMap – permite interacción y
acceso por nombre a una colección de
atributos
Universidad de Deusto
. . . .
ESIDE
Documento XML como Árbol
de Nodos
<?xml version="1.0" encoding="iso-8859-1"?>
<Peliculas>
<Pelicula codigo='1' titulo='Lo que el viento se
llevó'
director='Victor Fleming'
actores='Clark Gable, Vivien Leigh,
Leslie Howard'/>
<Pelicula codigo='2' titulo='Los Otros'
director='Alejandro Amenabar'
actores='Nicole Kidman'/>
<Pelicula codigo="5" titulo="Malena"
director="Giuseppe Tornatore"
actores="Monica Bellucci, Giuseppe
Sulfaro"/>
</Peliculas>
Universidad de Deusto
. . . .
ESIDE
Documento XML como Árbol de
Nodos
Root
Películas
...Película
titulo=’Lo que el
viento se llevó’codigo=1
actores=’Clark Gable, Vivien
Leigh, Leslie Howard’
diirector=’Victor Fleming’
Película
titulo=’Malena’codigo=5
actores=’Monica Bellucci,
Giuseppe Sulfaro’
diirector=’Giuseppe
Tornatore’
Universidad de Deusto
. . . .
ESIDE
Procesando XML con DOM
 Python provee el módulo xml.dom.minidom que es
una implementación sencilla de DOM
 El método parse a partir de un fichero crea un objeto
DOM, el cual tiene todos los métodos y atributos
estándar de DOM: hasChildNodes(),
childNodes, getElementsByTagName()
 Para más información sobre procesamiento XML en
Python ir a: http://pyxml.sourceforge.net/topics/
 El módulo PyXML, que no viene en la distribución por defecto
de Python, permite procesamiento un poco más sofisticado
 http://pyxml.sourceforge.net/topics/
Universidad de Deusto
. . . .
ESIDE
Ejemplo DOM I
# xml/ejemploDOM.py
# Ejecutar: python ejemploDOM.py Cartelera.xml
#!/usr/bin/env python
import xml.dom.minidom, sys
class Pelicula:
def __init__(self, codigo, titulo, director, actores):
self.codigo = codigo
self.titulo = titulo
self.director = director
self.actores = actores
def __repr__(self):
return "Codigo: " + str(self.codigo) + " - titulo: " +
self.titulo + " - director: " + self.director + " - actores: " +
self.actores
class PeliculaDOMParser:
def __init__(self, filename):
self.dom = xml.dom.minidom.parse(filename)
self.peliculas = []
Universidad de Deusto
. . . .
ESIDE
Ejemplo DOM II
def getPeliculas(self):
if not self.peliculas:
peliculaNodes = self.dom.getElementsByTagName("Pelicula")
numPelis = len(peliculaNodes)
for i in range(numPelis):
pelicula = peliculaNodes.item(i)
# Recuperar los attributes de cada nodo Pelicula
peliAttribs = pelicula.attributes
codigo = peliAttribs.getNamedItem("codigo").nodeValue
titulo = peliAttribs.getNamedItem("titulo").nodeValue
director = peliAttribs.getNamedItem("director").nodeValue
actores = peliAttribs.getNamedItem("actores").nodeValue
self.peliculas.append(Pelicula(codigo,titulo,director,actores))
return self.peliculas
if __name__ == '__main__':
domParser = PeliculaDOMParser(sys.argv[1])
for peli in domParser.getPeliculas():
print peli
Universidad de Deusto
. . . .
ESIDE
Extensible Style Language
Transformations (XSLT) I
 Con la diversidad de lenguajes de
presentación que hay (WML, HTML, cHTML)
existen dos alternativas para desarrollar las
aplicaciones:
 Desarrollar versiones de los procesos de
generación de presentación (JSP, ASP, CGI,..)
para cada lenguaje.
 Desarrollar solo una versión que genere XML y
conversores de XML a los lenguajes de
presentación.
Universidad de Deusto
. . . .
ESIDE
Extensible Style Language
Transformations (XSLT) II
 Dos partes:
 Transformation Language (XSLT)
 Formatting Language (XSL Formatting Objects)
 XSLT transforma un documento XML en otro
documento XML
 XSLFO formatea y estiliza documentos en
varios modos
 XSLT W3C Recommendation -
http://www.w3.org/TR/xslt
Universidad de Deusto
. . . .
ESIDE
Operaciones entre árboles en
XSL
Universidad de Deusto
. . . .
ESIDE
Ventajas y desventajas de
XSLT
 Ventajas:
 No asume un único formato de salida de documentos
 Permite manipular de muy diversas maneras un documento
XML: reordenar elementos, filtrar, añadir, borrar, etc.
 Permite acceder a todo el documento XML
 XSLT es un lenguaje XML
 Desventajas:
 Su utilización es más compleja que un lenguaje de
programación convencional
 Consume cierta memoria y capacidad de proceso  DOM
detrás
Universidad de Deusto
. . . .
ESIDE
Usando hojas de estilo XSLT
 Para crear una transformación XSL
necesitamos:
 El documento XML a transformar
(students.xml)
 La hoja de estilo que especifica la
transformación (students.xsl)
Universidad de Deusto
. . . .
ESIDE
Documento XML
(students.xml)
<?xml version="1.0"?>
<course>
<name id="csci_2962">Programming XML in Java</name>
<teacher id=“di">Diego Ipiña</teacher>
<student id=“ua">
<name>Usue Artaza</name>
<hw1>30</hw1>
<hw2>70</hw2>
<project>80</project>
<final>85</final>
</student>
<student id=“iu">
<name>Iñigo Urrutia</name>
<hw1>80</hw1>
<hw2>90</hw2>
<project>100</project>
<final>40</final>
</student>
</course>
Universidad de Deusto
. . . .
ESIDE
Hoja de estilo XSLT
(students.xsl)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0“
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="course">
<HTML>
<HEAD><TITLE>Name of students</TITLE></HEAD>
<BODY>
<xsl:apply-templates select="student"/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="student">
<P><xsl:value-of select="name"/></P>
</xsl:template>
</xsl:stylesheet>
Universidad de Deusto
. . . .
ESIDE
Resultado de transformación
 (students.html)
<HTML>
<HEAD> <TITLE>Name of students</TITLE>
</HEAD>
<BODY>
<P>Usue Artaza</P>
<P>Iñigo Urrutia</P>
</BODY>
</HTML>
Universidad de Deusto
. . . .
ESIDE
XSLT en Python
 Herramientas para procesamiento XSLT tools en
Python:
 http://uche.ogbuji.net/tech/akara/nodes/2003-01-
01/python-xslt
 En la siguiente url podemos encontrar adaptaciones
Python de las librerías de la toolkit Gnome en C
Libxml y Libxslt:
 http://xmlsoft.org/python.html (Linux)
 http://users.skynet.be/sbi/libxml-python/ (Windows)
 El ejemplo en la siguiente página ilustra el uso de esta
librería
Universidad de Deusto
. . . .
ESIDE
Ejemplo XSLT
# Instalar fichero libxml2-python-2.6.16.win32-py2.4.exe
# Ejecutar: python xsltexample.py Cartelera.xml Cartelera.xsl transform.html
import libxml2
import libxslt
import sys
if len(sys.argv) != 4:
print 'Usage: python xsltexample <xml-file> <xslt-file>
<output-file>'
sys.exit(0)
else:
styledoc = libxml2.parseFile(sys.argv[2])
style = libxslt.parseStylesheetDoc(styledoc)
doc = libxml2.parseFile(sys.argv[1])
result = style.applyStylesheet(doc, None)
style.saveResultToFilename(sys.argv[3], result, 0)
style.freeStylesheet()
doc.freeDoc()
result.freeDoc()
Universidad de Deusto
. . . .
ESIDE
Ejemplo XML (Cartelera.xml)
<?xml version="1.0" encoding="iso-8859-1"?>
<Cartelera>
<Cine codigo='1' nombre='Coliseo Java' direccion='Avda. Abaro'
poblacion='Portugalete'>
<Pelicula codigo='1' titulo='Lo que el viento se llevo'
director='Santiago Segura'
actores='Bo Derek, Al Pacino, Robert Reford'>
<Sesion>16:00</Sesion>
<Sesion>19:30</Sesion>
<Sesion>22:00</Sesion>
</Pelicula>
<Pelicula codigo='2' titulo='Los Otros'
director='Alejandro Amenabar'
actores='Nicole Kidman'>
<Sesion>16:30</Sesion>
<Sesion>19:45</Sesion>
<Sesion>22:30</Sesion>
</Pelicula>
</Cine>
...
Universidad de Deusto
. . . .
ESIDE
Ejemplo XSL (Cartelera.xsl)
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<style type="text/css">
table {font-family: arial, 'sans serif';
margin-left: 15pt;}
th,td {font-size: 80%;}
th {background-color:#FAEBD7}
</style>
</head>
<body>
<table border="1">
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
Universidad de Deusto
. . . .
ESIDE
Ejemplo XSL (Cartelera.xsl)
<xsl:template match="Cartelera">
<xsl:for-each select="Cine">
<tr>
<th><xsl:text>Cine</xsl:text></th>
<th><xsl:text>Dirección</xsl:text></th>
<th><xsl:text>Población</xsl:text></th>
<th></th>
</tr>
<tr>
<td><xsl:value-of select="./@nombre"/></td>
<td><xsl:value-of select="./@direccion"/></td>
<td><xsl:value-of select="./@poblacion"/></td>
<td><xsl:text></xsl:text></td>
</tr>
Universidad de Deusto
. . . .
ESIDE
Ejemplo XSL (Cartelera.xsl)
<xsl:for-each select="Pelicula“>
<tr>
<th></th>
<th><xsl:text>Película</xsl:text></th>
<th><xsl:text>Director</xsl:text></th>
<th><xsl:text>Actores</xsl:text></th>
</tr>
<tr>
<td><xsl:text></xsl:text></td>
<td><xsl:value-of select="./@titulo"/></td>
<td><xsl:value-of select="./@director"/></td>
<td><xsl:value-of select="./@actores"/></td>
</tr>
Universidad de Deusto
. . . .
ESIDE
Ejemplo XSL (Cartelera.xsl)
<tr>
<th></th>
<th></th>
<th><xsl:text>Sesión</xsl:text></th>
<th><xsl:text>Hora</xsl:text></th>
</tr>
<xsl:for-each select="Sesion">
<tr>
<td><xsl:text></xsl:text></td>
<td><xsl:text></xsl:text></td>
<td><xsl:value-of select="position()"/></td>
<td><xsl:value-of select="."/></td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Universidad de Deusto
. . . .
ESIDE
Resultado XSL parsing
Universidad de Deusto
. . . .
ESIDE
Programación de GUIs I
 Tkinter es la GUI toolkit que por defecto viene con Python
(http://www.python.org/doc/current/lib/module-
Tkinter.html)
 Basada en Tcl/tk, no tiene apariencia nativa
 Es lenta pero su uso es muy sencillo
 Pmw (Python meta widgets) (http://pmw.sourceforge.net/)
 Componentes más elaborados encima de Tkinter
 Existen otras toolkits para generación de GUIs:
 wxPython (http://www.wxpython.org/)
 Apariencia nativa, basado en wxWindows (multiplaforma), muy
rápida
 Pythonwin (http://www.python.org/windows/pythonwin/)
 Solamente para Windows, usa directamente la API de Windows
 PyGTK (http://www.pygtk.org/)
 PyQt (http://www.riverbankcomputing.co.uk/pyqt/)
Universidad de Deusto
. . . .
ESIDE
Ejemplo Tkinter I
# gui/tkinterwatch.py
from Tkinter import *
import time, sys
class StopWatch(Frame):
""" Implements a stop watch frame widget. """
def __init__(self, parent=None, **kw):
Frame.__init__(self, parent, kw)
self._start = 0.0
self._elapsedtime = 0.0
self._running = 0
self.timestr = StringVar()
self.makeWidgets()
def makeWidgets(self):
""" Make the time label. """
l = Label(self, textvariable=self.timestr)
self._setTime(self._elapsedtime)
l.pack(fill=X, expand=NO, pady=2, padx=2)
def _update(self):
""" Update the label with elapsed time. """
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._timer = self.after(50, self._update)
def _setTime(self, elap):
""" Set the time string to Minutes:Seconds:Hundreths """
minutes = int(elap/60)
seconds = int(elap - minutes*60.0)
hseconds = int((elap - minutes*60.0 - seconds)*100)
self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))
Universidad de Deusto
. . . .
ESIDE
Ejemplo Tkinter II
def Start(self):
""" Start the stopwatch, ignore if running. """
if not self._running:
self._start = time.time() - self._elapsedtime
self._update()
self._running = 1
def Stop(self):
""" Stop the stopwatch, ignore if stopped. """
if self._running:
self.after_cancel(self._timer)
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._running = 0
def Reset(self):
""" Reset the stopwatch. """
self._start = time.time()
self._elapsedtime = 0.0
self._setTime(self._elapsedtime)
if __name__ == '__main__': root = Tk()
sw = StopWatch(root)
sw.pack(side=TOP)
Button(root, text='Start', command=sw.Start).pack(side=LEFT)
Button(root, text='Stop', command=sw.Stop).pack(side=LEFT)
Button(root, text='Reset', command=sw.Reset).pack(side=LEFT)
Button(root, text='Quit', command=sys.exit(0)).pack(side=LEFT)
root.mainloop()
Universidad de Deusto
. . . .
ESIDE
Ejemplo de GUI con Pmw
Universidad de Deusto
. . . .
ESIDE
wxPython I
 Basado en wxWidgets toolkit:
 Creada para proveer una manera barata y flexible de
maximizar la inversión realizada en el desarrollo de GUIs
 Hasta Febrero del 2004, wxWidgets era conocida como
wxWindows, pero Microsoft “sugirió” un cambio de nombre
...
 Instalación:
 http//www.wxpython.org/downloads
 En UNIX requiere las librerías glib y gtk+ y wxGTK (disponible
en http://www.wxwidgets.org )
 Para Windows usar: wxPython2.5-win32-unicode-2.5.3.1-
py24.exe
Universidad de Deusto
. . . .
ESIDE
wxPython II
 En wxPython todas las clases están definidas
dentro del módulo wx
 Para crear una aplicación en wxPython hay
que crear una clase que deriva de wx.App y
sobreescribe el método OnInit
 Toda aplicación está formada al menos de un
Frame o un Dialog
 Los marcos pueden contener otros paneles,
barras de menús y herramientas (MenuBar y
ToolBar ) y línea de estado (StatusBar)
Universidad de Deusto
. . . .
ESIDE
wxPython III
 Los marcos y diálogos contienen controles:
Button, CheckBox, Choice, ListBox,
RadioBox y Slider, ...
 Existen diálogos predefinidos:
MessageDialog o FileDialog
 A través del programa
wxPythondemodemo.py se pueden
ver demos
 Vienen acompañadas de código fuente
Universidad de Deusto
. . . .
ESIDE
Ejemplo wxPython I
#!/usr/bin/env python
# gui/wxPythonSemanaESIDE.py
__author__ = "Diego Ipiña <dipina@eside.deusto.es>"
import wx
class Frame(wx.Frame):
"""Clase frame que visualiza una imagen."""
def __init__(self, image, parent=None, id=-1,
pos=wx.DefaultPosition, title='¡Hola, semaneros
ESIDE!'):
"""Crea un Frame y visualiza imagen."""
temp = image.ConvertToBitmap()
size = temp.GetWidth(), temp.GetHeight()
wx.Frame.__init__(self, parent, id, title, pos, size)
self.bmp = wx.StaticBitmap(parent=self, id=-1, bitmap=temp)
Universidad de Deusto
. . . .
ESIDE
Ejemplo wxPython II
class App(wx.App):
"""Clase aplicación.""“
def __init__(self):
wx.App.__init__(self)
def OnInit(self):
wx.InitAllImageHandlers()
image = wx.Image('semanaeside.jpg', wx.BITMAP_TYPE_JPEG)
self.frame = Frame(image)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def main():
app = App()
app.MainLoop()
if __name__ == '__main__':
main()
Universidad de Deusto
. . . .
ESIDE
wxGlade
 No siempre es necesario (o
conveniente) crear de manera
programática las interfaces en
wxPython.
 Hay herramientas que nos ayudarán a
generar el código wxPython
correspondiente:
 wxGlade (http://wxglade.sourceforge.net/)
Universidad de Deusto
. . . .
ESIDE
Manejo de eventos en
wxPython
 Toda control define una serie de eventos que se lanzan cuando
el usuario interactúa sobre ellos
 Mirar documentación de wxWidgets
(http://www.wxwidgets.org/manuals/2.5.2/wx_contents.html)
 wxPython define por cada control una tabla de eventos que
asocia un tipo de evento con un gestor del mismo
...
wx.EVT_BUTTON(self, self.botonNuevoUsuario.GetId(),
self.OnNuevoUsuario)
...
def OnNuevoUsuario(self, evt):
# código para crear nuevo usuario
Universidad de Deusto
. . . .
ESIDE
Gestores de posicionamiento
en wxPython
 Representados por wx.Sizer y sus descendientes en la jerarquía de
clases de wxPython
 Definen posicionamiento de controles en diálogos, independientes de la
plataforma, teniendo en consideración las diferencias en tamaño y estilo de
los controles individuales
 GridSizer: dispone los controles en una matriz donde las celdas tienen el
mismo tamaño
 BoxSizer: dispone controles en una fila o columna
 bsizer = wx.BoxSizer(wx.VERTICAL)
topSizer = wx.BoxSizer(wx.HORIZONTAL)
topSizer.Add(nombreUsuarioLabel, 0, wx.GROW|wx.ALL, 4)
topSizer.Add(self.nombreUsuarioTxtCtrl, 0,
wx.GROW|wx.ALL|wx.ALIGN_RIGHT , 4)
bsizer.Add(topSizer, 0, wx.GROW|wx.ALL, 4)
bsizer.Fit(self)
self.SetSizer(bsizer)
Universidad de Deusto
. . . .
ESIDE
Dibujando gráficos en
wxPython
 Preciso usar un contexto de dispositivo (device context ó DC).
 DC es la clase base para ClientDC, PaintDC, MemoryDC,
PostScriptDC, MemoryDC, MetafileDC y PrinterDC
 Se puede utilizar exactamente el mismo código para dibujar
encima de cualquiera de estos dispositivos
 Algunos ejemplos de las funciones disponibles para dibujar son
DC.DrawLine, DC.DrawCircle o DC.DrawText.
 Para optimizar el pintado de figuras geométricas, es
recomendable incluir las primitivas de dibujo entre las llamadas
DC.BeginDrawing y DC.EndDrawing.
 El color del fondo de cada figura dibujada se puede controlar
con el concepto de brocha (Brush) y el grosor y color de los
bordes de cada figura con el concepto de bolígrafo (Pen).
Universidad de Deusto
. . . .
ESIDE
Ejemplo dibujado gráficos
wxPython I
dc = wx.PaintDC(self)
dc.Clear()
dc.BeginDrawing()
dc.SetPen( wx.Pen("BLACK",1) )
dc.SetBrush( wx.Brush("RED") )
cabecera = "Total partidas jugadas: " +
str(int(partidasJugadas))
(w, h) = dc.GetTextExtent(cabecera)
dc.DrawText(cabecera, 320-(w/2), 70-h)
(w, h) = dc.GetTextExtent("Ganadas")
dc.DrawText("Ganadas", 160-(w/2), 390-h)
dc.DrawRectangle(100, 350, 120, -alturaBarraGanadas)
(w, h) = dc.GetTextExtent(`self.resultadoEstadisticas[0]`)
dc.DrawText(‘self.resultadoEstadisticas[0]’,
160-(w/2), 350-alturaBarraGanadas-20)
...
Universidad de Deusto
. . . .
ESIDE
Ejemplo dibujado gráficos
wxPython II
Universidad de Deusto
. . . .
ESIDE
Ejemplo: Tres En Raya
Universidad de Deusto
. . . .
ESIDE
Programación Web Python
 Necesitamos instalar Apache 2.0
 El módulo de Apache mod_python
Universidad de Deusto
. . . .
ESIDE
Servidor HTTP Apache
 El servidor HTTP Apache es una herramienta
software libre tanto para las plataformas UNIX como
Windows NT.
 Su objetivo es proporcionar un servidor web seguro,
eficiente y extensible que provea servicios HTTP
acorde con el estándar actual de este protocolo.
 Apache es desde 1996 el servidor web más popular.
 El estudio de Netcraft de Febrero del 2005 así lo atestigua,
más del 68% de los portales web usan Apache.
 Este servidor es un desarrollo de la Apache Software
Foundation.
 http://httpd.apache.org/
Universidad de Deusto
. . . .
ESIDE
Popularidad de Apache
http://news.netcraft.com/archives/web_server_survey.html
Universidad de Deusto
. . . .
ESIDE
Instalación de Apache
 La mayoría de las distribuciones Linux ya traen
preinstalado este servidor bien en su versión 1.3 o
2.0
 Nosotros utilizaremos 2.0
 Instalación:
 Para Windows bajar fichero .msi de
http://httpd.apache.org/
 Para Linux, utilizar vuestro gestor de paquetes favorito para
su instalación:
 Con yum:
yum install httpd
 Con apt-get para instalar Apache2 y PHP 4:
apt-get install apache2 libapache2-mod-php4
Universidad de Deusto
. . . .
ESIDE
Programación Web Python
 Pasos para desarrollar aplicaciones web en Python:
 Instalar Apache 2.0, disponible en: http://httpd.apache.org/download.cgi
 Instalar mod_python 3.1.2b: http://httpd.apache.org/modules/python-download.cgi (si
tienes problemas instalando en Python ir a: http://www.lehuen.com/nicolas/download/ o
http://www.modpython.org/pipermail/mod_python/2004-April/015474.html)
 Modificar Apache2confhttpd.conf, encontrar otras líneas LoadModule y añadir los siguiente:
LoadModule python_module modules/mod_python.so
 Comprobar instalación en:
http://www.modpython.org/live/current/doc-html/inst-testing.html
 Configurar Apache añadiendo a httpd.conf las siguientes líneas, para dar soporte a CGIs
en Python y PSPs (Python Server Pages):
<Directory "<dir-donde-guardar-python-scripts>">
AddHandler mod_python .py
PythonHandler mod_python.publisher
PythonDebug On
</Directory>
<Directory "<dir-donde-guardar-paginas-psp>">
AddHandler mod_python .psp
PythonHandler mod_python.psp
PythonDebug On
</Directory>
 Usar el módulo cgi de la Python Library para programar y seguir documentación de
mod_python (http://www.modpython.org/live/current/doc-html/)
Universidad de Deusto
. . . .
ESIDE
Ejemplo CGI I
# Copiar contenido examplescgi-bin a %APACHE_HOME%
# cgi-bin/python/holamundo.py
# metodos de ayuda del CGI
def _formatAsHTML(req, content):
req.content_type = "text/html"
return "<html><head><title>Hola Mundo Python
CGI</title></head><body><h1>Ejemplo Python de CGI</h1><p>" +
content + "</p></body></html>"
def _usage():
return "Uso: Debes especificar un parametro de nombre ‘quien’, para
saber a quien saludar, e.j: http://localhost:8080/cgi-
bin/python/holamundo.py/diHola?quien=Diego"
Universidad de Deusto
. . . .
ESIDE
Ejemplo CGI II
# único método público que se puede invocar al que hay que pasar
obligatoriamente un parámetro
def diHola(req, quien=""):
if not quien:
return _formatAsHTML(req, _usage())
return _formatAsHTML(req, "¡Hola " + quien + "!")
# si no se especifica un metodo en la url se invoca index por defecto,
# es decir http://localhost:8080/cgi-bin/python/holamundo.py
def index(req, **params):
paramsPassedStr = ""
if params:
for param in params:
paramsPassedStr += (param + "n")
return _formatAsHTML(req, "Unico metodo publico en CGI es
diHola<br>Parametros recibidos: " + paramsPassedStr + "<br>" + _usage())
Universidad de Deusto
. . . .
ESIDE
Python Server Pages
 Mecanismo para incluir sentencias Python en
documentos HTML o XML
 Similar a PHP, JSP o ASP
 ¿Es buena práctica mezclar marcado y código?
 Patrón de diseño MVC
 Sintaxis muy similar a JSP, 4 tipos de entidades:
 Código en Python delimitado por códigos de escape <% y
%>.
 Expresiones delimitadas por <%= y %>.
 Directivas, <%@ incluye file=’nombre-fichero’>
 Comentarios delimitados por los símbolos <%-- y --%>
 IMPORTANTE: el intérprete de PSP recuerda la última
tabulación de Python.
Universidad de Deusto
. . . .
ESIDE
Python Server Pages
 Hay un conjunto de variables accesibles
por PSP en tiempo de ejecución:
 req, referencia a un objeto de tipo
Request
 psp, objeto de tipo PSPInstance que
permite invocar métodos como
redirect(location) o
set_error_page(filename)
 form, objeto de tipo FieldStorage
 session, objeto de tipo Session
Universidad de Deusto
. . . .
ESIDE
Ejemplo PSP
<!– /cgi-bin/psp/login.psp -->
<%
import tresenrayaweb
import RegistroJugadoresDB
if not session.has_key('registro'):
session['registro'] = RegistroJugadoresDB.RegistroJugadoresDB()
mensajeError = ""
if form.has_key('nombreUsuario') and form.has_key('clave'):
try:
session['registro'].login(form['nombreUsuario'], form['clave'])
psp.redirect('/cgi-bin/psp/tresenraya.psp?nombreUsuario=' + form['nombreUsuario'])
except:
mensajeError = 'Los detalles de login introducidos son incorrectos'
saludo = 'Introduce tus detalles de logeo para jugar al Tres en Raya'
# end
%>
<html>
<h1><%= saludo %></h1>
<form method="post" action="/cgi-bin/psp/login.psp">
<table>
<tr><td>Nombre usuario:</td><td><input type="text" name="nombreUsuario"></td></tr>
<tr><td>Contraseña:</td><td><input type="password" name="clave"></td></tr>
<tr><td><input type="submit" value="Login"></td><td><input type="reset"
name="Limpiar"></td></tr>
</table>
</form>
<%
if len(mensajeError):
%>
<p><%=mensajeError%></p>
<%
# end if
%>
</html>
Universidad de Deusto
. . . .
ESIDE
Ejemplo Python
!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
import MySQLdb, string, _mysql, _mysql_exceptions, tresenraya
class RegistroJugadoresDB(tresenraya.RegistroJugadores):
def __init__(self):
tresenraya.RegistroJugadores.__init__(self)
db=MySQLdb.connect(host="localhost",user="tresenraya", passwd="tresenraya",
db="tresenraya")
self.cursor = db.cursor()
# Asegurarse que si no existe un usuario solop se añada
usuarioSolop = self._executeSQLCommand("select * from usuario where
nombreUsuario='solop'")
if not len(usuarioSolop):
self._executeSQLCommand("insert into usuario values('solop', 'solop')")
self._executeSQLCommand("insert into estadistica values('solop', 0, 0, 0)")
print 'Usuario solop y sus estadisticas creadas'
else:
usuarios = self._executeSQLCommand("select * from usuario")
for usuario in usuarios:
self._RegistroJugadores__jugadores[usuario[0]] = usuario[1]
# recuperamos las estadísticas de partidas de un jugador
estadisticasUsuario = self._executeSQLCommand("select ganadas,
empatadas, perdidas from estadistica where nombreUsuario='" + usuario[0] + "'")
self._RegistroJugadores__estadisticas[usuario[0]] =
[int(estadisticasUsuario[0][0]), int(estadisticasUsuario[0][1]),
int(estadisticasUsuario[0][2])]
Universidad de Deusto
. . . .
ESIDE
Ejemplo Python
def _executeSQLCommand(self, command):
# si la consulta devuelve resultados lo hará como una lista de tuplas, donde cada tupla
# representa una fila de la tabla correspondiente, y cada elemento de la tupla una columna
resultado = []
command = string.strip(command)
if len(command):
try:
resultCode = self.cursor.execute(command) # Ejecuta el comando
if string.lower(command).startswith('select'): # si es una select ...
filas = self.cursor.fetchall() # recuperar todos los resultados
for fila in filas:
contenidoFila = []
for columna in fila:
if columna == None:
contenidoFila.append(None)
else:
contenidoFila.append(columna)
resultado.append(tuple(contenidoFila))
except _mysql_exceptions.ProgrammingError, e:
print e
sys.exit()
return resultado
# sigue más código
Universidad de Deusto
. . . .
ESIDE
Aplicación LAMP con Python
Universidad de Deusto
. . . .
ESIDE
LCE Sentient Library
Universidad de Deusto
. . . .
ESIDE
Programación distribuida:
CORBA con omniORBpy
 Desde Python se puede usar tanto CORBA (omniORBpy) como
servicios web (SOAPpy disponible en
http://pywebsvcs.sourceforge.net/)
 En este curso nos concentramos sólo en CORBA:
 Download omniORBpy de: http://omniorb.sourceforge.net/
 Desarrollada por Duncan Grisby en AT&T Labs Cambridge
 Basada en la ORB para C++: omniORB
 Descomprimir y compilar en Linux o simplemente descomprimir en
Windows
 Las siguientes variables de entorno son necesarias:
 PYTHONPATH=<omniORBpy-install-dir>/lib/python;
<omniORBpy-install-dir>libx86_win32
 PATH=$PATH:=<omniORBpy-install-dir>/bin/x86_win32
 LD_LIBRARY_PATH=<omniORBpy-install-
dir>lib<platform>
 Para compilar IDL usar: omniidl -bpython <fichero-idl-
a-compilar>
Universidad de Deusto
. . . .
ESIDE
Ejemplo CORBA: IDL
// corba/example_echo.idl
module Example {
interface Echo {
string echoString(in string mesg);
};
};
Universidad de Deusto
. . . .
ESIDE
Ejemplo CORBA: servidor
#!/usr/bin/env python
import sysfrom omniORB import CORBA, PortableServer
# Import the stubs and skeletons for the Example module
import Example, Example__POA
# Define an implementation of the Echo interface
class Echo_i (Example__POA.Echo):
def echoString(self, mesg):
print "echoString() called with message:", mesg
return mesg
# Initialise the ORB
orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID)
# Find the root POA
poa = orb.resolve_initial_references("RootPOA")
# Create an instance of Echo_ie
i = Echo_i()# Create an object reference, and implicitly activate the objecte
o = ei._this()
# Print out the IOR
print orb.object_to_string(eo)
# Activate the POA
poaManager = poa._get_the_POAManager()
poaManager.activate()
# Everything is running now, but if this thread drops out of the end
# of the file, the process will exit. orb.run() just blocks until the
# ORB is shut down
orb.run()
Universidad de Deusto
. . . .
ESIDE
Ejemplo CORBA: servidor
#!/usr/bin/env pythonimport sys
# Import the CORBA module
from omniORB import CORBA
# Import the stubs for the Example module
import Example
# Initialise the ORB
orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID)
# Get the IOR of an Echo object from the command line (without
# checking that the arguments are sensible!)
ior = sys.argv[1]
# Convert the IOR to an object reference
obj = orb.string_to_object(ior)
# Narrow reference to an Example::Echo objecte
o = obj._narrow(Example.Echo)
if eo is None:
print "Object reference is not an Example::Echo"
sys.exit(1)
# Invoke the echoString operation
message = "Hello from Python"
result = eo.echoString(message)
print "I said '%s'. The object said '%s'." % (message,result)
Universidad de Deusto
. . . .
ESIDE
SOA
 Los servicios web han dado lugar a un nuevo
modo de diseñar sistemas distribuídos:
 Arquitecturas SOA (Service Oriented Arquitecture)
 SOA = colección de servicios
 Más información en http://www.service-
architecture.com/
 http://msdn.microsoft.com/Longhorn/understandi
ng/pillars/Indigo/default.aspx?pull=/library/en-
us/dnbda/html/srorientwp.asp
Universidad de Deusto
. . . .
ESIDE
Servicios Web
 Son un estándar basado en protocolos abiertos como
HTTP y SOAP
 SOAP es un vocabulario XML que representa RPCs
 http://www.w3.org/TR/SOAP
 No necesitas ni Windows ni .NET, ni UNIX ni Java
para escribir servicios web
 Servicio web = aplicación que:
 se ejecuta en un servidor web
 expone métodos a clientes
 escucha peticiones HTTP representando comandos que
invocan a métodos Web
 ejecuta métodos web y devuelve resultados
Universidad de Deusto
. . . .
ESIDE
SOAP
 SOAP es un protocolo de comunicación basado en XML útil para la
comunicación entre aplicaciones
 Actualmente en versión 1.2, aunque la más utilizada es la 1.1
 http://www.w3.org/2000/xp/Group/
 SOAP es reconocido como el backbone de una nueva generación de
aplicaciones multi-platforma y multi-lenguaje, denominado Servicios
Web.
 SOAP es un mecanismo para el intercambio de mensajes a través de
Internet independiente de los lenguajes de programación
 Es un protocolo de transporte
 Los clientes envían una petición SOAP mediante un HTTP POST
normalmente y reciben un código de respuesta (éxito o error) y una
respuesta SOAP
 Un mensaje SOAP es un mensaje XML que consta de un conjunto de
cabeceras opcionales y de un cuerpo.
Universidad de Deusto
. . . .
ESIDE
Petición SOAP
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/
soap/envelope/">
<soap:Body>
<getProductDetails
xmlns="http://warehouse.example.com/ws"
>
<productId>827635</productId>
</getProductDetails>
</soap:Body>
</soap:Envelope>
Universidad de Deusto
. . . .
ESIDE
Respuesta SOAP
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getProductDetailsResponse
xmlns="http://warehouse.example.com/ws">
<getProductDetailsResult>
<productName>Toptimate 3-Piece Set</productName>
<productId>827635</productId>
<description>3-Piece luggage set. Black
Polyester.</description>
<price>96.50</price>
<inStock>true</inStock>
</getProductDetailsResult>
</getProductDetailsResponse>
</soap:Body>
</soap:Envelope>
Universidad de Deusto
. . . .
ESIDE
Servicios Web en Python
 En la siguiente URL tenemos
información sobre las APIs disponibles:
 http://pywebsvcs.sourceforge.net/
 Revisar artículos sobre desarrollo de
servicios web en Python en:
 http://www-
106.ibm.com/developerworks/library/ws-
pyth5/
Universidad de Deusto
. . . .
ESIDE
SOAPpy - Simple to use SOAP
library for Python
 Requiere la previa instalación de:
 XML package for Python, http://pyxml.sourceforge.net/
 Hacer doble clic sobre PyXML-0.8.4.win32-py2.4.exe
 Fpconst, librería para trabajar con números en coma flotante
http://research.warnes.net/projects/rzope/fpconst/
 Ofrece soporte para valores especiales Not-a-Number (NaN), Positive
Infinity (Inf), y Negative Infinity (-Inf), parte de la especificación SOAP
 Extraer fpconst-0.7.2.zip
 cd <directorio-donde-se-ha-extraido-fpconst-0.7.2.zip>
 Python setup.py install
 SOAPpy, http://pywebsvcs.sourceforge.net/
 Extraer fichero SOAPpy-0.12.0.zip
 cd SOAPpy-0.12.0
 python setup.py build
 python setup.py install
Universidad de Deusto
. . . .
ESIDE
Servidor Hola Mundo
import SOAPpy
def hello():
return "Hello World"
server =
SOAPpy.SOAPServer(("localhost
", 8080))
server.registerFunction(hello)
server.serve_forever()
Universidad de Deusto
. . . .
ESIDE
Cliente Hola Mundo
import SOAPpy
server =
SOAPpy.SOAPProxy("http://loca
lhost:8080/")
print server.hello()
Universidad de Deusto
. . . .
ESIDE
Explicación SOAPpy
 El objeto SOAProxy maneja todos los
detalles internos del uso de SOAP
 Crea un intermediario (proxy) entre
nosotros y el servicio web final
 Podemos utilizar las propiedades
dumpSOAPIn y dumpSOAPOut para ver el
contenido de las peticiones y respuestas
SOAP
Universidad de Deusto
. . . .
ESIDE
Debugging con SOAPpy
>>> from SOAPpy import SOAPProxy
>>> url =
'http://services.xmethods.net:80/soap/servlet/r
pcrouter'
>>> n = 'urn:xmethods-Temperature'
>>> server = SOAPProxy(url, namespace=n) 1
>>> server.config.dumpSOAPOut = 1 2
>>> server.config.dumpSOAPIn = 1
>>> temperature = server.getTemp('27502')
Universidad de Deusto
. . . .
ESIDE
WSDL
 Un fichero WSDL contiene la siguiente
información:
 La URL y espacio de nombres del servicio
 El tipo de servicio web
 La lista de funciones disponibles
 Los argumentos de estas funciones
 Los tipos de datos de cada argumento
 Los valores de retorno de cada función y sus tipos
Universidad de Deusto
. . . .
ESIDE
Obteniendo Metainformación
de un Servicio Web
from SOAPpy import WSDL
wsdlFile =
'http://www.xmethods.net/sd/2001/TemperatureSer
vice.wsdl'
server = WSDL.Proxy(wsdlFile)
server.methods.keys()
callInfo = server.methods['getTemp']
print callInfo.inparams
print callInfo.inparams[0].name
print callInfo.inparams[0].type
print callInfo.outparams
print callInfo.outparams[0].name
print callInfo.outparams[0].type
Universidad de Deusto
. . . .
ESIDE
Un poco de Jython
 Download Jython de:
 http://www.jython.org/download.html
 Para instalar simplemente ejecutar: java jython-21
 Usa Lift-Off Java-Installer: http://liftoff.sourceforge.net/
 Algunos ejemplos de Jython en:
 http://www.jython.org/applets/index.html
 Documentación básica sobre Jython disponible en:
 http://www.jython.org/docs/usejava.html
Universidad de Deusto
. . . .
ESIDE
Jython
 Jython (http://www.jython.org) es una implementación open
source en Java de Python que se integra de manera
transparente con la plataforma Java.
 Jython complementa a Java y es especialmente indicada para
las siguientes tareas:
 Empotrar scripts en aplicaciones Java, de modo que los usuarios
finales puedan escribir scripts que añadan funcionalidad a la
aplicación.
 Experimentación interactiva por medio del intérprete interactivo
suministrado por Jython que permite interactuar con los paquetes
Java o aplicaciones en ejecución.
 Desarrollo rápido de aplicaciones. Los programas en Python son
típicamente entre 2 y 10 veces más cortos que los programas Java.
Esto se traduce en una mayor productividad en la programación.
La integración transparente de Jython y Java permite combinar
estos dos lenguajes en productos.
Universidad de Deusto
. . . .
ESIDE
Ejemplo Jython: TresEnRaya
Universidad de Deusto
. . . .
ESIDE
IronPython
 En Marzo del 2004 en la conferencia PyCon fue presentado IronPython
(http://ironpython.com/)
 Una implementación Python orientada a las plataformas .NET y Mono.
 Sus características principales son:
 Tan rápida como la versión estándar de Python
 Integrada de modo transparente con la Common Language Runtime de
.NET. Desde IronPython podemos usar las librerías de clases .NET y
extender otras clases .NET
 Dinámico, soporta el modo de ejecución interactivo como Python
 Opcionalmente estático, se pueden compilar ficheros Python para producir
ejecutables (.exes) que pueden ejecutarse directamente o incluso dlls.
 Soporta código gestionado (managed code)
 No finalizado, todavía en versión alfa no puede ser utilizada para producción
de software.
 IronPython parece una contribución prometedora que nos permitirá
programar aplicaciones .NET desde la cómoda y sencilla sintaxis de
Python.
 ¡Mantente atento a los progresos en este proyecto.!
Universidad de Deusto
. . . .
ESIDE
Casos de éxito de Python
 BitTorrent (http://bitconjurer.org/BitTorrent/), sistema P2P que
ofrece mayor rendimiento que eMule
 PyGlobus, permite la programación de Grid Computing
(http://www-itg.lbl.gov/gtg/projects/pyGlobus/)
 ZOPE (www.zope.org) es un servidor de aplicaciones para
construir y gestionar contenido, intranets, portales, y
aplicaciones propietarias
 Industrial Light & Magic usa Python en el proceso de producción
de gráficos por ordenador
 Google usa Python internamente, lo mismo que Yahoo para su
sitio para grupos
 Red Hat Linux utiliza Python para la instalación, configuración, y
gestión de paquetes.
 Más historias de éxito de Python en:
http://pbf.strakt.com/success
Universidad de Deusto
. . . .
ESIDE
Recursos utilizados
 Compilador de Python 2.4 y documentación:
 http://www.python.org/2.4/
 Extensiones para Windows:
 https://sourceforge.net/projects/pywin32/
 Módulo de bases de datos MySQLdb 0.9.2:
 http://sourceforge.net/projects/mysql-python
 Base de datos MySQL 4.1:
 http://www.mysql.com/downloads/
 omniORBpy
 http://omniorb.sourceforge.net/
 Servidor Apache 2.0 (http://httpd.apache.org/)
 Módulo mod_python para Apache: http://www.modpython.org
 wxPython 2.5:
 http://www.wxpython.org/download.php#binaries
 Jython 2.1
 http://www.jython.org/download.html
Universidad de Deusto
. . . .
ESIDE
References
 Libro “Dive into Python”,
http://diveintopython.org/http://diveint
opython.org/
 Librería de Python:
http://docs.python.org/lib/lib.html

Más contenido relacionado

PDF
Intro Python
PDF
Programador Jr. para Python Primera Parte
PPTX
Cap4
PDF
Curso python
DOCX
Manual de python
PDF
Programacion orientada a objetos python manuel casado martín - universidad ...
PDF
Python
PDF
Presentacion Python
Intro Python
Programador Jr. para Python Primera Parte
Cap4
Curso python
Manual de python
Programacion orientada a objetos python manuel casado martín - universidad ...
Python
Presentacion Python

La actualidad más candente (17)

PDF
Introducción a python
PPTX
Python y la POO, en una clase, UNNe-Corrientes
PDF
Clase4_Python-CTIC
PPTX
Uso de las clases iostream
PDF
Semana 2 Fundamentos de Python(Variables)
PPT
Exposición Python
DOCX
Trabajo de python
PDF
Aprenda a pensar como un programador con Python
PPTX
Software para el aprendizaje de la programación EC 2. Presentación 3: Python
PDF
Python para todos
PDF
Python básico I
PPTX
Python (Lenguaje de Programación)
PPTX
Clase 03
PDF
Tutorial python3
Introducción a python
Python y la POO, en una clase, UNNe-Corrientes
Clase4_Python-CTIC
Uso de las clases iostream
Semana 2 Fundamentos de Python(Variables)
Exposición Python
Trabajo de python
Aprenda a pensar como un programador con Python
Software para el aprendizaje de la programación EC 2. Presentación 3: Python
Python para todos
Python básico I
Python (Lenguaje de Programación)
Clase 03
Tutorial python3
Publicidad

Destacado (13)

PPTX
CSSED, PYTHON, PERL
ODP
Diapositiva de Cine
PPTX
PROGRAMACIÓN WEB INTRODUCCIÓN
PPTX
Evidencias de la tercera sesión: Programación en Python
PPS
Lenguajes De Programación Web
PPS
HISTORIA DEL CINE MEXICANO
PDF
Soluciones derivadas
PPTX
Historia del cine
PPTX
¿Como hacer un pseudocodigo y diagrama de flujo?
PPTX
Historia del cine
PPT
Origen y Evolucion del Cine
ODP
Historia del cine
PPTX
PRINCIPIOS DE CONTABILIDAD GENERALMENTE ACEPTADOS
CSSED, PYTHON, PERL
Diapositiva de Cine
PROGRAMACIÓN WEB INTRODUCCIÓN
Evidencias de la tercera sesión: Programación en Python
Lenguajes De Programación Web
HISTORIA DEL CINE MEXICANO
Soluciones derivadas
Historia del cine
¿Como hacer un pseudocodigo y diagrama de flujo?
Historia del cine
Origen y Evolucion del Cine
Historia del cine
PRINCIPIOS DE CONTABILIDAD GENERALMENTE ACEPTADOS
Publicidad

Similar a Python101 (20)

PPT
Curso de Python para progrmadores 2022.ppt
PPTX
Python-Thonny programación avanzada TESE
PDF
Eventos intropython
PPSX
FUNDAMENTOS PYTHON.ppsx
PDF
Intro python
PDF
PPTX
PDF
Clase1_Python-CTIC
PDF
Python_Module_01_Courtesy.pdf
PDF
Portafolio de evidencias actividades
PPT
Java Ago Dic07
PPT
Yudy Centeno M
PPT
JAVA (1).PPT
PPT
JAVA.PPT
PPT
JAVA (1).PPT
PPT
TUTORIAL JAVA
ODP
python programming learning
PDF
Python_para_todos.pdf
PDF
Python para todos
PDF
Python para todos
Curso de Python para progrmadores 2022.ppt
Python-Thonny programación avanzada TESE
Eventos intropython
FUNDAMENTOS PYTHON.ppsx
Intro python
Clase1_Python-CTIC
Python_Module_01_Courtesy.pdf
Portafolio de evidencias actividades
Java Ago Dic07
Yudy Centeno M
JAVA (1).PPT
JAVA.PPT
JAVA (1).PPT
TUTORIAL JAVA
python programming learning
Python_para_todos.pdf
Python para todos
Python para todos

Último (20)

PDF
DI, TEA, TDAH.pdf guía se secuencias didacticas
PDF
Metodologías Activas con herramientas IAG
PDF
ACERTIJO Súper Círculo y la clave contra el Malvado Señor de las Formas. Por ...
PDF
Breve historia de los Incas -- Patricia Temoche [Temoche, Patricia] -- Breve ...
PDF
La Evaluacion Formativa en Nuevos Escenarios de Aprendizaje UGEL03 Ccesa007.pdf
PDF
COMUNICACION EFECTIVA PARA LA EDUCACION .pdf
DOCX
2 GRADO UNIDAD 5 - 2025.docx para primaria
PDF
Integrando la Inteligencia Artificial Generativa (IAG) en el Aula
PDF
Punto Critico - Brian Tracy Ccesa007.pdf
DOCX
V UNIDAD - SEGUNDO GRADO. del mes de agosto
PPT
Cosacos y hombres del Este en el Heer.ppt
PPTX
AGENTES PATÓGENOS Y LAS PRINCIPAL ENFERMEAD.pptx
PDF
ciencias-1.pdf libro cuarto basico niños
PDF
Híper Mega Repaso Histológico Bloque 3.pdf
PDF
Salcedo, J. et al. - Recomendaciones para la utilización del lenguaje inclusi...
PDF
PFB-MANUAL-PRUEBA-FUNCIONES-BASICAS-pdf.pdf
PDF
Escuelas Desarmando una mirada subjetiva a la educación
PDF
Romper el Circulo de la Creatividad - Colleen Hoover Ccesa007.pdf
PDF
Crear o Morir - Andres Oppenheimer Ccesa007.pdf
PDF
Didactica de la Investigacion Educativa SUE Ccesa007.pdf
DI, TEA, TDAH.pdf guía se secuencias didacticas
Metodologías Activas con herramientas IAG
ACERTIJO Súper Círculo y la clave contra el Malvado Señor de las Formas. Por ...
Breve historia de los Incas -- Patricia Temoche [Temoche, Patricia] -- Breve ...
La Evaluacion Formativa en Nuevos Escenarios de Aprendizaje UGEL03 Ccesa007.pdf
COMUNICACION EFECTIVA PARA LA EDUCACION .pdf
2 GRADO UNIDAD 5 - 2025.docx para primaria
Integrando la Inteligencia Artificial Generativa (IAG) en el Aula
Punto Critico - Brian Tracy Ccesa007.pdf
V UNIDAD - SEGUNDO GRADO. del mes de agosto
Cosacos y hombres del Este en el Heer.ppt
AGENTES PATÓGENOS Y LAS PRINCIPAL ENFERMEAD.pptx
ciencias-1.pdf libro cuarto basico niños
Híper Mega Repaso Histológico Bloque 3.pdf
Salcedo, J. et al. - Recomendaciones para la utilización del lenguaje inclusi...
PFB-MANUAL-PRUEBA-FUNCIONES-BASICAS-pdf.pdf
Escuelas Desarmando una mirada subjetiva a la educación
Romper el Circulo de la Creatividad - Colleen Hoover Ccesa007.pdf
Crear o Morir - Andres Oppenheimer Ccesa007.pdf
Didactica de la Investigacion Educativa SUE Ccesa007.pdf

Python101

  • 1. Universidad de Deusto . . . . ESIDE Curso de Python
  • 2. Universidad de Deusto . . . . ESIDE Contenido  Python básico  Sintaxis.  Instrucciones básicas.  Tipo de datos.  Orientación a objetos  Paquetes esenciales de Python: XML, bases de datos, programación web.
  • 3. Universidad de Deusto . . . . ESIDE El otro lenguaje de programación que empieza con 'P'  Python fue creado por Guido van Rossum (http://www.python.org/~guido/)  Da este nombre al lenguaje inspirado por el popular grupo cómico británico Monty Python  Guido creó Python durante unas vacaciones de navidad en las que (al parecer) se estaba aburriendo
  • 4. Universidad de Deusto . . . . ESIDE Hola Mundo en Python #!/usr/bin/env python print "Hola Mundo" # "Hola Mundo" print "hola", "mundo" # "hola mundo" print "Hola" + "Mundo" # "HolaMundo"
  • 5. Universidad de Deusto . . . . ESIDE Características de Python I  Muy legible y elegante  Imposible escribir código ofuscado  Simple y poderoso  Minimalista: todo aquello innecesario no hay que escribirlo (;, {, }, 'n')  Muy denso: poco código hace mucho  Soporta objetos y estructuras de datos de alto nivel: strings, listas, diccionarios, etc.  Múltiples niveles de organizar código: funciones, clases, módulos, y paquetes  Python standard library (http://www.python.org/doc/current/lib/lib.html) contiene un sinfín de clases de utilidad  Si hay áreas que son lentas se pueden reemplazar por plugins en C o C++, siguiendo la API para extender o empotrar Python en una aplicación, o a través de herramientas como SWIG, sip o Pyrex.
  • 6. Universidad de Deusto . . . . ESIDE Características de Python II  De scripting  No tienes que declarar constantes y variables antes de utilizarlas  No requiere paso de compilación/linkage  La primera vez que se ejecuta un script de Python se compila y genera bytecode que es luego interpretado  Alta velocidad de desarrollo y buen rendimiento  Código interoperable (como en Java "write once run everywhere")  Se puede utilizar en múltiples plataforma (más aún que Java)  Puedes incluso ejecutar Python dentro de una JVM (Jython)  Open source  Razón por la cual la Python Library sigue creciendo  De propósito general  Puedes hacer en Python todo lo que puedes hacer con C# o Java, o más
  • 7. Universidad de Deusto . . . . ESIDE Peculiaridades sintácticas  Python usa tabulación (o espaciado) para mostrar estructura de bloques  Tabula una vez para indicar comienzo de bloque  Des-tabula para indicar el final del bloque Código en C/Java Código en Python if (x) { if (y) { f1(); } f2(); } if x: if y: f1() f2()
  • 8. Universidad de Deusto . . . . ESIDE Python vs. Perl  Los dos están basados en un buen entendimiento de las herramientas necesarias para resolver problemas  Perl está basado en awk, sed, and shell scripting y su misión es hacer las tareas de administradores de sistemas más sencillas  Python está basado e inspirando en OOP (Object- oriented programming)  Guido van Rossum diseñó un lenguaje simple, poderoso, y elegante orientado a la creación de sistemas a partir de componentes
  • 9. Universidad de Deusto . . . . ESIDE Python vs. Java  Java es un lenguaje de programación muy completo que ofrece:  Amplio abanico de tipos de datos  Soporte para threads  Strong typing  Y mucho más ...  Python es un lenguaje de scripting:  No ofrece strong typing  Bueno para prototipos pero malo para grandes sistemas  Puede cascar en tiempo de ejecución  Todo lo que puedes hacer con Java también lo puedes hacer con Python  Incluso puedes acceder a través de Python a las API de Java si usas Jython (http://www.jython.org)
  • 10. Universidad de Deusto . . . . ESIDE Python vs. Jython  Python  También llamado Cpython  Implementación del lenguaje Python en C  Python C API permite extender Python con librerías realizadas en C  Partes que requieren mayor rendimiento en Python están implementadas en C o C++ y tan sólo contienen una pequeña capa de Python encima  Jython  Implementación de Python en Java  Permite acceder a todas las APIs de Java  P.E. Podemos producir Swing GUIs desde Python
  • 11. Universidad de Deusto . . . . ESIDE ¿Para qué [no] es útil?  Python no es el lenguaje perfecto, no es bueno para:  Programación de bajo nivel (system-programming), como programación de drivers y kernels  Python es de demasiado alto nivel, no hay control directo sobre memoria y otras tareas de bajo nivel  Aplicaciones que requieren alta capacidad de computo  No hay nada mejor para este tipo de aplicaciones que el viejo C  Python es ideal:  Como lenguaje "pegamento" para combinar varios componentes juntos  Para llevar a cabo prototipos de sistema  Para la elaboración de aplicaciones cliente  Para desarrollo web y de sistemas distribuidos  Para el desarrollo de tareas científicas, en los que hay que simular y prototipar rápidamente
  • 12. Universidad de Deusto . . . . ESIDE Instalar Python  Bajar la última versión de Python (2.4) de http://www.python.org/download/  Para Windows ejecutar instalador  Opcionalmente bajarse extensiones Python para Windows32 de: http://starship.python.net/crew/mhammond/  Podemos editar nuestro código Python con Notepad2 (Alt-H): http://www.flos-freeware.ch/notepad2.html  Para Linux:  En Debian Sarge: apt-get install python2.4  Para Fedora y Mandrake se pueden obtener los rpms de: http://www.python.org/2.4/rpms.html  rpm -iv python2.4-2.4-1pydotorg.i386.rpm
  • 13. Universidad de Deusto . . . . ESIDE Usando Python desde línea de comando  Para arrancar el intérprete (Python interactivo) ejecutar: C:>python Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>>  Un comando simple: >>> print "Hola Mundo" Hola Mundo >>>  Para salir del intérprete Ctrl-D (en Linux) o Ctrl-Z (en Windows) o: >>> import sys >>> sys.exit() $
  • 14. Universidad de Deusto . . . . ESIDE Ejecutando programa holamundo.py  Python desde script:  Guardar las siguientes sentencias en fichero: holamundo.py #!/usr/bin/env python print “Kaixo Mundua!"  Ejecutar el script desde línea de comando: $ python helloworld.py Kaixo Mundua! $
  • 15. Universidad de Deusto . . . . ESIDE Sentencias y bloques  Las sentencias acaban en nueva línea, no en ;  Los bloques son indicados por tabulación que sigue a una sentencia acabada en ':'. E.j. (bloque.py): # comentarios de línea se indican con carácter '#' name = "Diego1" # asignación de valor a variable if name == "Diego": print "Aupa Diego" else: print "¿Quién eres?" print "¡No eres Diego!" $ python bloque.py ¿Quién eres? ¡No eres Diego!
  • 16. Universidad de Deusto . . . . ESIDE Identificadores  Los identificadores sirven para nombrar variables, funciones y módulos  Deben empezar con un carácter no numérico y contener letras, números y '_'  Python es case sensitive (sensible a la capitalización)  Palabras reservadas:  and elif global or assert else if pass break except import print class exec in raise continue finally is return def for lambda try del from not while  Variables y funciones delimitadas por __ corresponden a símbolos implícitamente definidos:  __name__ nombre de función  __doc__ documentación sobre una función  __init__() constructor de una clase  __dict__, diccionario utilizado para guardar los atributos de un objeto
  • 17. Universidad de Deusto . . . . ESIDE Tipos de datos I  Numéricos (integer, long integer, floating-point, and complex) >>> x = 4 >>> int (x) 4 >>> long(x) 4L >>> float(x) 4.0 >>> complex (4, .2) (4+0.2j)
  • 18. Universidad de Deusto . . . . ESIDE Tipos de datos II  Strings, delimitados por un par de (', " ,""")  Dos string juntos sin delimitador se unen >>> print "Hi" "there" Hithere  Los códigos de escape se expresan a través de '': >>>print 'n'  Raw strings >>> print r'n' # no se 'escapa' n  Lo mismo ' que ", p.e. "[foo]" r'[foo]'  Algunos de los métodos que se pueden aplicar a un string son: >>> len('La vida es mucho mejor con Python.') >>> 34 >>> 'La vida es mucho mejor con Python.'.upper() 'LA VIDA ES MUCHO MEJOR CON PYTHON' >>> "La vida es mucho mejor con Python".find("Python") 27 >>> "La vida es mucho mejor con Python".find('Perl') -1 >>> 'La vida es mucho mejor con Python'.replace('Python', 'Jython') 'La vida es mucho mejor con Jython'
  • 19. Universidad de Deusto . . . . ESIDE Tipos de datos III  El módulo string de la Python library define métodos para manipulación de strings: >>> import string >>> s1 = 'La vida es mejor con Python' >>> string.find(s1, 'Python') 21  '%' es el operador de formateo de cadenas: >>> provincia = 'Araba' >>> "La capital de %s es %s" % (provincia, "Gasteiz") 'La capital de Araba es Gasteiz'  Los caracteres de formateo son los mismos que en C, p.e. d, f, x
  • 20. Universidad de Deusto . . . . ESIDE Tipos de datos IV  Para poder escribir caracteres con acentos es necesario introducir la siguiente línea al comienzo de un programa Python:  # -*- coding: iso-8859-1 -*-  Los strings en formato unicode se declaran precediendo el string de una ‘u’:  print u'¿Qué tal estás?'
  • 21. Universidad de Deusto . . . . ESIDE Tipos de datos V  Listas []  Indexadas por un entero comienzan en 0: >>> meses = ["Enero", "Febrero"] >>> print meses[0] Enero >>> meses.append("Marzo") >>> print meses ['Enero', 'Febrero', 'Marzo']  Dos puntos (:) es el operador de rodajas, permite trabajar con una porción de la lista, el elemento indicado por el segundo parámetro no se incluye: >>> print meses[1:2] ['Febrero']  Más (+) es el operador de concatenación: >>> print meses+meses ['Enero', 'Febrero', 'Marzo', 'Enero', 'Febrero', 'Marzo']
  • 22. Universidad de Deusto . . . . ESIDE Tipos de datos VI  Las listas pueden contener cualquier tipo de objetos Python: >>> meses.append (meses) >>> print meses ['Enero', 'Febrero', 'Marzo', ['Enero', 'Febrero', 'Marzo' ]] >>> meses.append(1) ['Enero', 'Febrero', 'Marzo', ['Enero', 'Febrero', 'Marzo' ], 1]  Para añadir un elemento a una lista: >>> items = [4, 6] >>> items.insert(0, -1) >>> items [-1, 4, 6]  Para usar una lista como una pila, se pueden usar append y pop: >>> items.append(555) >>> items [-1, 4, 6, 555] >>> items.pop() 555 >>> items [-1, 4, 6]
  • 23. Universidad de Deusto . . . . ESIDE Tipos de datos VII  Tuplas (), lo mismo que listas, pero no se pueden modificar D:>python Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel) on win32 Type "help", "copyright", "credits" or "license" for more information. >>> mitupla = ('a', 1, "hola") >>> mitupla[2] 'hola' >>> dir(mitupla) ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__str__']
  • 24. Universidad de Deusto . . . . ESIDE Tipos de datos VIII  Diccionarios {} arrays asociativos o mapas, indexados por una clave, la cual puede ser cualquier objeto Python, aunque normalmente es una tupla: >>> mydict = {"altura" : "media", "habilidad" : "intermedia", "salario" : 1000 } >>> print mydict {altura': 'media', 'habilidad': 'intermedia', 'salario': 1000} >>> print mydict["habilidad"] intermedia  Puedes comprobar la existencia de una clave en un diccionario usando has_key: if mydict.has_key('altura'): print 'Nodo encontrado'  Lo mismo se podría hacer: if 'altura' in mydict: print 'Nodo encontrado'
  • 25. Universidad de Deusto . . . . ESIDE Control de flujo: condicionales  E.j. (condicional.py) q = 4 h = 5 if q < h : print "primer test pasado" elif q == 4: print “q tiene valor 4” else: print "segundo test pasado" >>> python condicional.py primer test pasado  Operadores booleanos: "or," "and," "not"  Operadores relacionales: ==, >, <, !=
  • 26. Universidad de Deusto . . . . ESIDE Control de flujo: bucles  for se utiliza para iterar sobre los miembros de una secuencia  Se puede usar sobre cualquier tipo de datos que sea una secuencia (lista, tupla, diccionario)  Ej. bucle.py for x in range(1,5): print x $ python bucle.py 1 2 3 4  La función range crea una secuencia descrita por ([start,] end [,step]), donde los campos start y step son opcionales. Start es 0 y step es 1 por defecto.
  • 27. Universidad de Deusto . . . . ESIDE Control de flujo: bucles  while es otra sentencia de repetición. Ejecuta un bloque de código hasta que una condición es falsa.  break nos sirve para salir de un bucle  Por ejemplo: reply = 'repite' while reply == 'repite': print 'Hola' reply = raw_input('Introduce "repite" para hacerlo de nuevo: ') Hola Introduce "repite" para hacerlo de nuevo: repite Hola Introduce "repite" para hacerlo de nuevo: adiós
  • 28. Universidad de Deusto . . . . ESIDE Funciones  Una función se declara usando la palabra clave def # funcionsimple.py def myfunc(a,b): sum = a + b return sum print myfunc (5,6) $ python funcionsimple.py 11  A una función se le pueden asignar parámetros por defecto: # funcionvaloresdefecto.py def myfunc(a=4,b=6): sum = a + b return sum print myfunc() print myfunc(b=8) # a es 4, sobreescribir b a 8 $ python funcion.py 10 12
  • 29. Universidad de Deusto . . . . ESIDE Funciones  Listas de argumentos y argumentos basados en palabras clave: # funcionargumentosvariablesyconclave.py def testArgLists_1(*args, **kwargs): print 'args:', args print 'kwargs:', kwargs testArgLists_1('aaa', 'bbb', arg1='ccc', arg2='ddd') def testArgLists_2(arg0, *args, **kwargs): print 'arg0: "%s"' % arg0 print 'args:', args print 'kwargs:', kwargs print '=' * 40 testArgLists_2('un primer argumento', 'aaa', 'bbb', arg1='ccc', arg2='ddd')  Visualizaría: args: ('aaa', 'bbb') kwargs: {'arg1': 'ccc', 'arg2': 'ddd'} ======================================== arg0: "un primer argumento" args: ('aaa', 'bbb') kwargs: {'arg1': 'ccc', 'arg2': 'ddd'}
  • 30. Universidad de Deusto . . . . ESIDE Clases  Una clase contiene una colección de métodos. Cada método contiene como primer parámetro (self) que hace referencia a un objeto  self equivalente a this en C++  Existe un soporte limitado para variables privadass mediante name mangling.  Un identificador __spam es reemplazado por _classname__spam.  El identificador es todavía accesible por _classname__spam.  En Python se soporta la herencia múltiple
  • 31. Universidad de Deusto . . . . ESIDE Clases # clasepinguinos.py class PenguinPen: def __init__(self): self.penguinCount = 0 def add (self, number = 1): """ Add penguins to the pen. The default number is 1 """ self.penguinCount = self.penguinCount + number def remove (self, number = 1): """ Remove one or more penguins from the pen """ self.penguinCount = self.penguinCount - number def population (self): """ How many penguins in the pen? """ return self.penguinCount def __del__(self): pass penguinPen = PenguinPen() penguinPen.add(5) # Tux y su familia print penguinPen.population()
  • 32. Universidad de Deusto . . . . ESIDE Más clases # clasesherencia.py class Basic: def __init__(self, name): self.name = name def show(self): print 'Basic -- name: %s' % self.name class Special(Basic): # entre paréntesis la clase base def __init__(self, name, edible): Basic.__init__(self, name) # se usa Basic para referir a self.upper = name.upper() # clase base self.edible = edible def show(self): Basic.show(self) print 'Special -- upper name: %s.' % self.upper, if self.edible: print "It's edible." else: print "It's not edible." def edible(self): return self.edible
  • 33. Universidad de Deusto . . . . ESIDE Probando clases obj1 = Basic('Manzana') obj1.show() print '=' * 30 obj2 = Special('Naranja', True) obj2.show()  Visualizaría: Basic -- name: Manzana ============================== Basic -- name: Naranja Special -- upper name: NARANJA. It's edible.
  • 34. Universidad de Deusto . . . . ESIDE Excepciones  Cada vez que un error ocurre se lanza una excepción, visualizándose un extracto de la pila del sistema. E.j. excepcion.py: #!/usr/bin/python print a $ python exception.py Traceback (innermost last): File "exception.py", line 2, in ? print a NameError: a  Para capturar la excepción se usa except: try: fh=open("new.txt", "r") except IOError, e: print e $ python excepcion.py [Errno 2] No such file or directory: 'new.txt'  Puedes lanzar tu propia excepción usando el comando raise: raise MyException raise SystemExitModules
  • 35. Universidad de Deusto . . . . ESIDE Excepciones personalizadas # excepcionpersonalizada.py class E(RuntimeError): def __init__(self, msg): self.msg = msg def getMsg(self): return self.msg try: raise E('mi mensaje de error') except E, obj: print 'Msg:', obj.getMsg()  Visualizaría: Msg: mi mensaje de error
  • 36. Universidad de Deusto . . . . ESIDE Módulos  Un módulo es una colección de métodos en un fichero que acaba en .py. El nombre del fichero determina el nombre del módulo en la mayoría de los casos.  E.j. modulo.py: def one(a): print "in one" def two (c): print "in two"  Uso de un módulo: >>> import modulo >>> dir(modulo) # lista contenidos módulo ['__builtins__', '__doc__', '__file__', '__name__', 'one', 'two'] >>> modulo.one(2) in one
  • 37. Universidad de Deusto . . . . ESIDE Módulos II  import hace que un módulo y su contenido sean disponibles para su uso.  Algunas formas de uso son: import test  Importa modulo test. Referir a x en test con "test.x". from test import x  Importa x de test. Referir a x en test con "x". from test import *  Importa todos los objetos de test. Referir a x en test con "x". import test as theTest  Importa test; lo hace disponible como theTest. Referir a objecto x como "theTest.x".
  • 38. Universidad de Deusto . . . . ESIDE Paquetes I  Un paquete es una manera de organizar un conjunto de módulos como una unidad. Los paquetes pueden a su vez contener otros paquetes.  Para aprender como crear un paquete consideremos el siguiente contenido de un paquete: package_example/ package_example/__init__.py package_example/module1.py package_example/module2.py  Y estos serían los contenidos de los ficheros correspondientes: # __init__.py # Exponer definiciones de módulos en este paquete. from module1 import class1 from module2 import class2
  • 39. Universidad de Deusto . . . . ESIDE Paquetes II # module1.py class class1: def __init__(self): self.description = 'class #1' def show(self): print self.description # module2.py class class2: def __init__(self): self.description = 'class #2' def show(self): print self.description
  • 40. Universidad de Deusto . . . . ESIDE Paquetes III # testpackage.py import package_example c1 = package_example.class1() c1.show() c2 = package_example.class2() c2.show()  Visualizaría: class #1 class #2  La localización de los paquetes debe especificarse o bien a través de la variable de entorno PYTHONPATH o en código del script mediante sys.path
  • 41. Universidad de Deusto . . . . ESIDE Paquetes IV  Como en Java el código de un paquete puede recogerse en un .zip: >>> import zipfile >>> a=zipfile.PyZipFile('mipackage.zip', 'w', zipfile.ZIP_DEFLATED) >>> a.writepy('package_example') >>> a.close() >>> ^Z  Luego lo puedes importar y usar insertando su path en sys.path o alternativamente añadiendo a la variable de entorno PYTHONPATH una referencia al nuevo .zip creado: $ mkdir prueba; cp mipackage.zip prueba $ export PYTHONPATH=/home/dipina/examples/prueba/mipackage.zip >>> import sys # esta y la siguiente no hacen falta si se ha inicializado PYTHONPATH >>> sys.path.insert(0, '/home/dipina/examples/prueba/mipackage.zip') >>> import package_example >>> class1 = package_example.module1.class1() >>> class1.show() class #1 >>> ^Z
  • 42. Universidad de Deusto . . . . ESIDE Manejo de ficheros  Leer un fichero (leerfichero.py) fh = open("holamundo.py") # open crea un objeto de tipo fichero for line in fh.readlines() : # lee todas las líneas en un fichero print line, fh.close() $ python leerfichero.py #!/usr/bin/python print "Hola mundo"  Escribir un fichero (escribirfichero.py) fh = open("out.txt", "w") fh.write ("estamos escribiendo ...n") fh.close() $ python escribirfichero.py $ cat out.txt estamos escribiendo ...
  • 43. Universidad de Deusto . . . . ESIDE Más sobre print  print (printredirect.py)  stdout en Python es sys.stdout, stdin es sys.stdin: import sys class PrintRedirect: def __init__(self, filename): self.filename = filename def write(self, msg): f = file(self.filename, 'a') f.write(msg) f.close() sys.stdout = PrintRedirect('tmp.log') print 'Log message #1' print 'Log message #2' print 'Log message #3'
  • 44. Universidad de Deusto . . . . ESIDE Variables globales en Python  Usar identificador global para referirse a variable global: # variableglobal.py NAME = "Manzana" def show_global(): name = NAME print '(show_global) nombre: %s' % name def set_global(): global NAME NAME = 'Naranja' name = NAME print '(set_global) nombre: %s' % name show_global() set_global() show_global()  Lo cual visualizaría: (show_global) nombre: Manzana (set_global) nombre: Naranja (show_global) nombre: Naranja
  • 45. Universidad de Deusto . . . . ESIDE Serialización de objetos  Pickle: Python Object Serialization  El módulo pickle implementa un algoritmo para la serialización y deserialización de objetos Python  Para serializar una jerarquía de objetos, creas un Pickler, y luego llamas al método dump(), o simplemente invocas el método dump() del módulo pickle  Para deserializar crear un Unpickler e invocas su método load() method, o simplemente invocas el método load() del módulo pickle  Se serializa el contenido del objeto __dict__ de la clase, si se quiere cambiar este comportamiento hay que sobrescribir los métodos __getstate__() y __setstate__().
  • 46. Universidad de Deusto . . . . ESIDE Serialización de objetos: Ejemplo pickle import pickle # pickleunpickle.py class Alumno: def __init__(self, dni, nombre, apellido1, apellido2): self.dni = dni self.nombre = nombre self.apellido1 = apellido1 self.apellido2 = apellido2 def __str__(self): return "DNI: " + self.dni + "ntNombre: " + self.nombre + "ntApellido1: " + self.apellido1 + "ntApellido2: " + self.apellido2 + "n" def get_dni(self): return self.dni def get_nombre(self): return self.nombre def get_apellido1(self): return self.apellido1 def get_apellido2(self): return self.apellido2 alum = Alumno("44567832P", "Diego", "Lz. de Ipina", "Gz. de Artaza") print "Alumno a serializar:n", alum f = open("Alumno.db", 'w') pickle.dump(alum, f) f.close() f = open("Alumno.db", "r") alum2 = pickle.load(f) f.close() print alum2.get_dni() print "Alumno leido:n", alum2
  • 47. Universidad de Deusto . . . . ESIDE Serialización de objetos: Otro ejemplo más sofisticado  Revisar ejemplos:  picklingexample.py  unpicklingexample.py  Utilizan los métodos especiales __setstate__() y __getstate__()
  • 48. Universidad de Deusto . . . . ESIDE Serialización de objetos  El módulo shelve define diccionarios persistentes, las claves tienen que ser strings mientras que los valores pueden ser cualquier objeto que se puede serializar con pickle (ala gdbm) import shelve d = shelve.open(filename) # abre un fichero d[key] = data # guarda un valor bajo key data = d[key] # lo recupera del d[key] # lo borra d.close()
  • 49. Universidad de Deusto . . . . ESIDE Juego TresEnRaya Modo Texto  Implementar el juego de tres en raya en la clase JuegoTresEnRaya con métodos:  resetGame  __elegirMarcaMaquina  __verTablero  __hayGanador  jugar  Permitir jugar sólo a aquellos usuarios que hagan login previamente a través de la clase RegistroJugadores  Registrar estadísticas de juego primero en memoria con un diccionario y luego de manera persistente con un shelf.  Los métodos soportados por esta clase serán:  registrarJugador  login  registrarVictoria | registrarEmpate | registrarPerdida  getEstadisticas
  • 50. Universidad de Deusto . . . . ESIDE Programación de BD en Python  Lo que es JDBC en Java es DB API en Python  Información detallada en: http://www.python.org/topics/database/  Para conectarnos a una base de datos usamos el método connect del módulo de base de datos utilizado que devuelve un objeto de tipo conection  El objeto connection define el método cursor() que sirve para recuperar un cursor de la BD  Otros métodos definidos en connection son close(), commit(), rollback()  El objeto cursor define entre otros los siguientes métodos:  execute() nos permite enviar una sentencia SQL a la BD  fetchone() recuperar una fila  fetchall() recuperar todas las filas  Hay varios módulos que implementan el estándar DB-API:  DCOracle (http://www.zope.org/Products/DCOracle/) creado por Zope  MySQLdb (http://sourceforge.net/projects/mysql-python)  MySQL-python.exe-1.2.0.win32-py2.4.zip para Windows  MySQL-python-1.2.0.tar.gz para Linux  apt-get install python2.4-mysqldb  Etc.
  • 51. Universidad de Deusto . . . . ESIDE  La base de datos open source más popular  Desarrollada por MySQL AB, compañía sueca cuyo negocio se basa en labores de consultoría sobre MySQL  http://www.mysql.com  Diseñada para:  Desarrollo de aplicaciones críticas  Sistemas con altos requerimientos de carga  Ser embebida en software  Existen otras buenas alternativas open source como PostGreSQL (http://www.postgresql.org/)  MySQL 5.0 (development release) soporta procedimientos almacenados  Desde MySQL 4.1 (production release) se soportan subqueries
  • 52. Universidad de Deusto . . . . ESIDE Instalación MySQL  En la siguiente URL se pueden obtener RPMs y ejecutables para instalar la última versión de producción de MySQL (4.1) tanto en Linux como Windows:  http://dev.mysql.com/ downloads/mysql/4.0.html  En las distribuciones que soportan apt-get, instalar con el comando: apt-get install mysql-server php4-mysql  Con yum: yum install mysql-server mysql
  • 53. Universidad de Deusto . . . . ESIDE Ejemplo programación BD en Python con MySQL I  Creamos una base de datos de nombre deusto a la que podemos hacer login con usuario deusto y password deusto, a través del siguiente SQL: CREATE DATABASE deusto; GRANT ALTER, SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON deusto.* TO deusto@'%' IDENTIFIED BY 'deusto'; GRANT ALTER, SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON deusto.* TO deusto@localhost IDENTIFIED BY 'deusto'; use deusto; CREATE TABLE EVENTOS(ID int(11) NOT NULL PRIMARY KEY, NOMBRE VARCHAR(250), LOCALIZACION VARCHAR(250), FECHA bigint(20), DESCRIPCION VARCHAR(250)); INSERT INTO EVENTOS VALUES (0, 'SEMANA ESIDE', 'ESIDE-DEUSTO', 0, 'Charla sobre Python');
  • 54. Universidad de Deusto . . . . ESIDE Ejemplo programación BD en Python con MySQL II # db/accesodbeventos.py import MySQLdb, time, string, _mysql, _mysql_exceptions def executeSQLCommand(cursor, command): rowSet = [] command = string.strip(command) if len(command): try: cursor.execute(command) # Ejecuta el comando if string.lower(command).startswith('select'): # si es select lines = cursor.fetchall() # recuperar todos los resultados for line in lines: row = [] for column in line: row.append(column) rowSet.append(row) except _mysql_exceptions.ProgrammingError, e: print e sys.exit() return rowSet
  • 55. Universidad de Deusto . . . . ESIDE Ejemplo programación BD en Python con MySQL III if __name__ == '__main__': db=MySQLdb.connect(host="localhost",user="deusto", passwd="deusto", db="deusto") cursor = db.cursor() executeSQLCommand(cursor, "update eventos set fecha=" + str(time.time()*1000)) rowSet = executeSQLCommand(cursor, "select * from eventos") for row in rowSet: print row del cursor  Visualizando lo siguiente: $ python accesodbeventos.py [0L, 'SEMANA ESIDE', 'ESIDE-DEUSTO', 1110133067870L, 'Charla sobre Python'] [1L, 'CURSO J2EE', 'CESINE', 1110133067870L, 'Curso sobre ...']
  • 56. Universidad de Deusto . . . . ESIDE Programación de expresiones regulares I  A través del módulo re, Python permite el uso de expresiones regulares similares a como se hace en Perl (una razón más para moverse de Perl a Python) # regex/procesaUrlConRe.py import re, urllib, sys if len(sys.argv) <= 4: print "Usage: procesaUrl <url-a-procesar> <palabra-a- reemplazar> <nueva-palabra> <fichero-html-a-crear>" sys.exit(0) print sys.argv[1] s = (urllib.urlopen(sys.argv[1])).read() # lee el contenido de una url # reemplaza todas las ocurrencias de "Artaza" por "artaza" t = re.sub(sys.argv[2], sys.argv[3], s) backupFile = open(sys.argv[4], "w") backupFile.write(t) backupFile.close() print 'Fichero ' + sys.argv[4] + ' escrito con contenido de url: ' + sys.argv[1] + ' al reemplazar palabra ' + sys.argv[2] + ' con palabra ' + sys.argv[3]
  • 57. Universidad de Deusto . . . . ESIDE Programación de expresiones regulares II # conseguir el titulo del documento HTML tmatch = re.search(r'<title>(.*?)</title>', s, re.IGNORECASE) if tmatch: title = tmatch.group(1) print 'Titulo de pagina ' + sys.argv[1] + ' es: ' + title # extraer lista de enlaces url: pat = re.compile(r'(http://[w-]*[.w-]+)') addrs = re.findall(pat, s) print 'La lista de enlaces encontrados en esta pagina es: ' for enlace in addrs: print enlace
  • 58. Universidad de Deusto . . . . ESIDE Programación de sistemas  Python permite la programación de sistema tanto accediendo a la API de Windows (http://www.python.org/windows/index.html) como a las llamadas al sistema de UNIX (módulo os)  El módulo os nos da acceso a:  El entorno del proceso: getcwd(), getgid(), getpid()  Creación de ficheros y descriptores: close(), dup(), dup2(), fstat(), open(), pipe(), stat(), socket()  Gestión de procesos: execle(), execv(), kill(), fork(), system()  Gestión de memoria mmap()  El módulo threading permite la creación de threads en Python  Revisar ejemplo del servidor web en Python  Siguiente transparencia muestra cómo usar módulo threading para recuperar el contenido de varias urls
  • 59. Universidad de Deusto . . . . ESIDE Ejemplo threads #!/usr/bin/env python import threading # threading/ejemplothreading.py import urllib class FetchUrlThread(threading.Thread): def __init__(self, url, filename): threading.Thread.__init__(self) self.url = url self.filename = filename def run(self): print self.getName(), "Fetching ", self.url f = open(self.getName()+self.filename, "w") content = urllib.urlopen(self.url).read() f.write(content) f.close() print self.getName(), "Saved in ", (self.getName()+self.filename) urls = [ ('http://www.python.org', 'index.html'), ('http://www.google.es', 'index.html') ] # Recuperar el contenido de las urls en diferentes threads for url, file in urls: t = FetchUrlThread(url, file) t.start()
  • 60. Universidad de Deusto . . . . ESIDE ¿Por qué usar XML?  Un documento XML puede ser fácilmente procesado y sus datos manipulados  Existen APIs para procesar esos documentos en Java, C, C++, Perl.. (y por supuesto Python)  XML define datos portables al igual que Java define código portable
  • 61. Universidad de Deusto . . . . ESIDE Componentes documento XML  Los documentos XML constan de:  Instrucciones de procesamiento (processing instructions – PI)  Declaraciones de tipo de documento  Comentarios  Elementos  Referencias a entidades  Secciones CDATA
  • 62. Universidad de Deusto . . . . ESIDE Ejemplo Documento XML <?xml version="1.0"?> <!DOCTYPE mensaje SYSTEM “labgroups.dtd"> <lab_group> <student_name dni=“44670523"> Josu Artaza </student_name> <student_name dni=“44543211"> Nuria Buruaga </student_name> <student_name dni=“23554521" tutor=“33456211"> Inga Dorsman </student_name> </lab_group>
  • 63. Universidad de Deusto . . . . ESIDE XML Parsing Documento XML XML DTD XML Schema Parser XML Aplicación XML
  • 64. Universidad de Deusto . . . . ESIDE XML Parsing (cont)  SAX  Define interfaz dirigido por eventos (event-driven) para el procesamiento de un documento XML  Definido por David Megginson y lista correo XML- DEV : http://www.megginson.com/SAX  DOM  Provee una representación de un documento XML en forma de un árbol  Carga todo el documento XML en memoria  http://www.w3.org/DOM
  • 65. Universidad de Deusto . . . . ESIDE Simple API for XML: SAX  Define un interfaz común implementado por muchos XML Parsers  Es el estándar de-facto para procesamiento de XML basado en eventos  SAX no es un parseador de XML  SAX2 añade soporte para XML Namespaces  La especificación de SAX 2.0/Java está en: http://www.megginson.com/SAX/Java/index. html
  • 66. Universidad de Deusto . . . . ESIDE Características de SAX  Analizador o parser SAX:  Detecta cuándo empieza y termina un elemento o el documento, o un conjunto de caracteres, etc. (genera eventos)  Gestiona los espacios de nombres  Comprueba que el documento está bien formado  Las aplicaciones necesitan implementar manejadores de los eventos notificados  SAX lee secuencialmente de principio a fin, sin cargar todo el documento en memoria  Ventaja: eficiencia en cuanto al tiempo y la memoria empleados en el análisis  Desventaja: no disponemos de la estructura en árbol de los documentos
  • 67. Universidad de Deusto . . . . ESIDE ¿Cómo funciona SAX? XML Document <?xml version=“1.0”?> <addressbook> </addressbook> <person> </person> <name>Diego Ipiña</name> <email>dipina@deusto.es</email> <person> </person> <name>Asier Perallos</name> <email>perallos@deusto.es</email> SAX Objects Parser startDocument Parser startElement Parser startElement & characters Parser startElement & characters Parser endElement Parser startElement Parser startElement & characters Parser startElement & characters Parser endElement Parser endElement & endDocument
  • 68. Universidad de Deusto . . . . ESIDE Programación en XML con SAX  Soporte para SAX en Python es ofrecido por el módulo xml.sax de la Python Library  Define 2 métodos:  make_parser([parser_list])  Crea y devuelve un objeto SAX XMLReader  parse(filename_or_stream, handler[, error_handler])  Crea un parser SAX y lo usa para procesar el documento a través de un handler  El módulo xml.sax.xmlreader define readers para SAX  El módulo xml.sax.handler define manejadores de eventos para SAX: startDocument, endDocument, starElement, endElement
  • 69. Universidad de Deusto . . . . ESIDE Ejemplo procesamiento SAX I # xml/ElementCounterSAX.py # Ejecutar: python ElementCounterSAX.py Cartelera.xml import sys from xml.sax import make_parser, handler class ElementCounter(handler.ContentHandler): def __init__(self): self._elems = 0 self._attrs = 0 self._elem_types = {} self._attr_types = {} def startElement(self, name, attrs): self._elems = self._elems + 1 self._attrs = self._attrs + len(attrs) self._elem_types[name] = self._elem_types.get(name, 0) + 1 for name in attrs.keys(): self._attr_types[name] = self._attr_types.get(name, 0) + 1
  • 70. Universidad de Deusto . . . . ESIDE Ejemplo procesamiento SAX II def endDocument(self): print "There were", self._elems, "elements." print "There were", self._attrs, "attributes." print "---ELEMENT TYPES" for pair in self._elem_types.items(): print "%20s %d" % pair print "---ATTRIBUTE TYPES" for pair in self._attr_types.items(): print "%20s %d" % pair parser = make_parser() parser.setContentHandler(ElementCounter()) parser.parse(sys.argv[1])
  • 71. Universidad de Deusto . . . . ESIDE W3C Document Object Model (DOM)  Documentos XML son tratados como un árbol de nodos  Cada elemento es un “nodo”  Los elementos hijos y el texto contenido dentro de un elemento son subnodos  W3C DOM Site: http://www.w3.org/DOM/
  • 72. Universidad de Deusto . . . . ESIDE Características DOM  Documento se carga totalmente en memoria en una estructura de árbol  Ventaja: fácil acceder a datos en función de la jerarquía de elementos, así como modificar el contenido de los documentos e incluso crearlos desde cero.  Desventaja: coste en tiempo y memoria que conlleva construir el árbol
  • 73. Universidad de Deusto . . . . ESIDE W3C XML DOM Objects  Element – un elemento XML  Attribute – un attributo  Text – texto contenido en un elemento o atributo  CDATAsection – sección CDATA  EntityReference – Referencia a una entidad  Entity – Indicación de una entidad XML  ProcessingInstruction – Una instrucción de procesamiento  Comment – Contenido de un comentario de XML  Document – El objeto documento  DocumentType – Referencia al elemento DOCTYPE  DocumentFragment – Referencia a fragmento de documento  Notation – Contenedor de una anotación
  • 74. Universidad de Deusto . . . . ESIDE Objetos relacionados con Nodos  Node – un nodo en el árbol de un documento  NodeList – una lista de objetos nodos  NamedNodeMap – permite interacción y acceso por nombre a una colección de atributos
  • 75. Universidad de Deusto . . . . ESIDE Documento XML como Árbol de Nodos <?xml version="1.0" encoding="iso-8859-1"?> <Peliculas> <Pelicula codigo='1' titulo='Lo que el viento se llevó' director='Victor Fleming' actores='Clark Gable, Vivien Leigh, Leslie Howard'/> <Pelicula codigo='2' titulo='Los Otros' director='Alejandro Amenabar' actores='Nicole Kidman'/> <Pelicula codigo="5" titulo="Malena" director="Giuseppe Tornatore" actores="Monica Bellucci, Giuseppe Sulfaro"/> </Peliculas>
  • 76. Universidad de Deusto . . . . ESIDE Documento XML como Árbol de Nodos Root Películas ...Película titulo=’Lo que el viento se llevó’codigo=1 actores=’Clark Gable, Vivien Leigh, Leslie Howard’ diirector=’Victor Fleming’ Película titulo=’Malena’codigo=5 actores=’Monica Bellucci, Giuseppe Sulfaro’ diirector=’Giuseppe Tornatore’
  • 77. Universidad de Deusto . . . . ESIDE Procesando XML con DOM  Python provee el módulo xml.dom.minidom que es una implementación sencilla de DOM  El método parse a partir de un fichero crea un objeto DOM, el cual tiene todos los métodos y atributos estándar de DOM: hasChildNodes(), childNodes, getElementsByTagName()  Para más información sobre procesamiento XML en Python ir a: http://pyxml.sourceforge.net/topics/  El módulo PyXML, que no viene en la distribución por defecto de Python, permite procesamiento un poco más sofisticado  http://pyxml.sourceforge.net/topics/
  • 78. Universidad de Deusto . . . . ESIDE Ejemplo DOM I # xml/ejemploDOM.py # Ejecutar: python ejemploDOM.py Cartelera.xml #!/usr/bin/env python import xml.dom.minidom, sys class Pelicula: def __init__(self, codigo, titulo, director, actores): self.codigo = codigo self.titulo = titulo self.director = director self.actores = actores def __repr__(self): return "Codigo: " + str(self.codigo) + " - titulo: " + self.titulo + " - director: " + self.director + " - actores: " + self.actores class PeliculaDOMParser: def __init__(self, filename): self.dom = xml.dom.minidom.parse(filename) self.peliculas = []
  • 79. Universidad de Deusto . . . . ESIDE Ejemplo DOM II def getPeliculas(self): if not self.peliculas: peliculaNodes = self.dom.getElementsByTagName("Pelicula") numPelis = len(peliculaNodes) for i in range(numPelis): pelicula = peliculaNodes.item(i) # Recuperar los attributes de cada nodo Pelicula peliAttribs = pelicula.attributes codigo = peliAttribs.getNamedItem("codigo").nodeValue titulo = peliAttribs.getNamedItem("titulo").nodeValue director = peliAttribs.getNamedItem("director").nodeValue actores = peliAttribs.getNamedItem("actores").nodeValue self.peliculas.append(Pelicula(codigo,titulo,director,actores)) return self.peliculas if __name__ == '__main__': domParser = PeliculaDOMParser(sys.argv[1]) for peli in domParser.getPeliculas(): print peli
  • 80. Universidad de Deusto . . . . ESIDE Extensible Style Language Transformations (XSLT) I  Con la diversidad de lenguajes de presentación que hay (WML, HTML, cHTML) existen dos alternativas para desarrollar las aplicaciones:  Desarrollar versiones de los procesos de generación de presentación (JSP, ASP, CGI,..) para cada lenguaje.  Desarrollar solo una versión que genere XML y conversores de XML a los lenguajes de presentación.
  • 81. Universidad de Deusto . . . . ESIDE Extensible Style Language Transformations (XSLT) II  Dos partes:  Transformation Language (XSLT)  Formatting Language (XSL Formatting Objects)  XSLT transforma un documento XML en otro documento XML  XSLFO formatea y estiliza documentos en varios modos  XSLT W3C Recommendation - http://www.w3.org/TR/xslt
  • 82. Universidad de Deusto . . . . ESIDE Operaciones entre árboles en XSL
  • 83. Universidad de Deusto . . . . ESIDE Ventajas y desventajas de XSLT  Ventajas:  No asume un único formato de salida de documentos  Permite manipular de muy diversas maneras un documento XML: reordenar elementos, filtrar, añadir, borrar, etc.  Permite acceder a todo el documento XML  XSLT es un lenguaje XML  Desventajas:  Su utilización es más compleja que un lenguaje de programación convencional  Consume cierta memoria y capacidad de proceso  DOM detrás
  • 84. Universidad de Deusto . . . . ESIDE Usando hojas de estilo XSLT  Para crear una transformación XSL necesitamos:  El documento XML a transformar (students.xml)  La hoja de estilo que especifica la transformación (students.xsl)
  • 85. Universidad de Deusto . . . . ESIDE Documento XML (students.xml) <?xml version="1.0"?> <course> <name id="csci_2962">Programming XML in Java</name> <teacher id=“di">Diego Ipiña</teacher> <student id=“ua"> <name>Usue Artaza</name> <hw1>30</hw1> <hw2>70</hw2> <project>80</project> <final>85</final> </student> <student id=“iu"> <name>Iñigo Urrutia</name> <hw1>80</hw1> <hw2>90</hw2> <project>100</project> <final>40</final> </student> </course>
  • 86. Universidad de Deusto . . . . ESIDE Hoja de estilo XSLT (students.xsl) <?xml version="1.0"?> <xsl:stylesheet version="1.0“ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="course"> <HTML> <HEAD><TITLE>Name of students</TITLE></HEAD> <BODY> <xsl:apply-templates select="student"/> </BODY> </HTML> </xsl:template> <xsl:template match="student"> <P><xsl:value-of select="name"/></P> </xsl:template> </xsl:stylesheet>
  • 87. Universidad de Deusto . . . . ESIDE Resultado de transformación  (students.html) <HTML> <HEAD> <TITLE>Name of students</TITLE> </HEAD> <BODY> <P>Usue Artaza</P> <P>Iñigo Urrutia</P> </BODY> </HTML>
  • 88. Universidad de Deusto . . . . ESIDE XSLT en Python  Herramientas para procesamiento XSLT tools en Python:  http://uche.ogbuji.net/tech/akara/nodes/2003-01- 01/python-xslt  En la siguiente url podemos encontrar adaptaciones Python de las librerías de la toolkit Gnome en C Libxml y Libxslt:  http://xmlsoft.org/python.html (Linux)  http://users.skynet.be/sbi/libxml-python/ (Windows)  El ejemplo en la siguiente página ilustra el uso de esta librería
  • 89. Universidad de Deusto . . . . ESIDE Ejemplo XSLT # Instalar fichero libxml2-python-2.6.16.win32-py2.4.exe # Ejecutar: python xsltexample.py Cartelera.xml Cartelera.xsl transform.html import libxml2 import libxslt import sys if len(sys.argv) != 4: print 'Usage: python xsltexample <xml-file> <xslt-file> <output-file>' sys.exit(0) else: styledoc = libxml2.parseFile(sys.argv[2]) style = libxslt.parseStylesheetDoc(styledoc) doc = libxml2.parseFile(sys.argv[1]) result = style.applyStylesheet(doc, None) style.saveResultToFilename(sys.argv[3], result, 0) style.freeStylesheet() doc.freeDoc() result.freeDoc()
  • 90. Universidad de Deusto . . . . ESIDE Ejemplo XML (Cartelera.xml) <?xml version="1.0" encoding="iso-8859-1"?> <Cartelera> <Cine codigo='1' nombre='Coliseo Java' direccion='Avda. Abaro' poblacion='Portugalete'> <Pelicula codigo='1' titulo='Lo que el viento se llevo' director='Santiago Segura' actores='Bo Derek, Al Pacino, Robert Reford'> <Sesion>16:00</Sesion> <Sesion>19:30</Sesion> <Sesion>22:00</Sesion> </Pelicula> <Pelicula codigo='2' titulo='Los Otros' director='Alejandro Amenabar' actores='Nicole Kidman'> <Sesion>16:30</Sesion> <Sesion>19:45</Sesion> <Sesion>22:30</Sesion> </Pelicula> </Cine> ...
  • 91. Universidad de Deusto . . . . ESIDE Ejemplo XSL (Cartelera.xsl) <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <html> <head> <style type="text/css"> table {font-family: arial, 'sans serif'; margin-left: 15pt;} th,td {font-size: 80%;} th {background-color:#FAEBD7} </style> </head> <body> <table border="1"> <xsl:apply-templates/> </table> </body> </html> </xsl:template>
  • 92. Universidad de Deusto . . . . ESIDE Ejemplo XSL (Cartelera.xsl) <xsl:template match="Cartelera"> <xsl:for-each select="Cine"> <tr> <th><xsl:text>Cine</xsl:text></th> <th><xsl:text>Dirección</xsl:text></th> <th><xsl:text>Población</xsl:text></th> <th></th> </tr> <tr> <td><xsl:value-of select="./@nombre"/></td> <td><xsl:value-of select="./@direccion"/></td> <td><xsl:value-of select="./@poblacion"/></td> <td><xsl:text></xsl:text></td> </tr>
  • 93. Universidad de Deusto . . . . ESIDE Ejemplo XSL (Cartelera.xsl) <xsl:for-each select="Pelicula“> <tr> <th></th> <th><xsl:text>Película</xsl:text></th> <th><xsl:text>Director</xsl:text></th> <th><xsl:text>Actores</xsl:text></th> </tr> <tr> <td><xsl:text></xsl:text></td> <td><xsl:value-of select="./@titulo"/></td> <td><xsl:value-of select="./@director"/></td> <td><xsl:value-of select="./@actores"/></td> </tr>
  • 94. Universidad de Deusto . . . . ESIDE Ejemplo XSL (Cartelera.xsl) <tr> <th></th> <th></th> <th><xsl:text>Sesión</xsl:text></th> <th><xsl:text>Hora</xsl:text></th> </tr> <xsl:for-each select="Sesion"> <tr> <td><xsl:text></xsl:text></td> <td><xsl:text></xsl:text></td> <td><xsl:value-of select="position()"/></td> <td><xsl:value-of select="."/></td> </tr> </xsl:for-each> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet>
  • 95. Universidad de Deusto . . . . ESIDE Resultado XSL parsing
  • 96. Universidad de Deusto . . . . ESIDE Programación de GUIs I  Tkinter es la GUI toolkit que por defecto viene con Python (http://www.python.org/doc/current/lib/module- Tkinter.html)  Basada en Tcl/tk, no tiene apariencia nativa  Es lenta pero su uso es muy sencillo  Pmw (Python meta widgets) (http://pmw.sourceforge.net/)  Componentes más elaborados encima de Tkinter  Existen otras toolkits para generación de GUIs:  wxPython (http://www.wxpython.org/)  Apariencia nativa, basado en wxWindows (multiplaforma), muy rápida  Pythonwin (http://www.python.org/windows/pythonwin/)  Solamente para Windows, usa directamente la API de Windows  PyGTK (http://www.pygtk.org/)  PyQt (http://www.riverbankcomputing.co.uk/pyqt/)
  • 97. Universidad de Deusto . . . . ESIDE Ejemplo Tkinter I # gui/tkinterwatch.py from Tkinter import * import time, sys class StopWatch(Frame): """ Implements a stop watch frame widget. """ def __init__(self, parent=None, **kw): Frame.__init__(self, parent, kw) self._start = 0.0 self._elapsedtime = 0.0 self._running = 0 self.timestr = StringVar() self.makeWidgets() def makeWidgets(self): """ Make the time label. """ l = Label(self, textvariable=self.timestr) self._setTime(self._elapsedtime) l.pack(fill=X, expand=NO, pady=2, padx=2) def _update(self): """ Update the label with elapsed time. """ self._elapsedtime = time.time() - self._start self._setTime(self._elapsedtime) self._timer = self.after(50, self._update) def _setTime(self, elap): """ Set the time string to Minutes:Seconds:Hundreths """ minutes = int(elap/60) seconds = int(elap - minutes*60.0) hseconds = int((elap - minutes*60.0 - seconds)*100) self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))
  • 98. Universidad de Deusto . . . . ESIDE Ejemplo Tkinter II def Start(self): """ Start the stopwatch, ignore if running. """ if not self._running: self._start = time.time() - self._elapsedtime self._update() self._running = 1 def Stop(self): """ Stop the stopwatch, ignore if stopped. """ if self._running: self.after_cancel(self._timer) self._elapsedtime = time.time() - self._start self._setTime(self._elapsedtime) self._running = 0 def Reset(self): """ Reset the stopwatch. """ self._start = time.time() self._elapsedtime = 0.0 self._setTime(self._elapsedtime) if __name__ == '__main__': root = Tk() sw = StopWatch(root) sw.pack(side=TOP) Button(root, text='Start', command=sw.Start).pack(side=LEFT) Button(root, text='Stop', command=sw.Stop).pack(side=LEFT) Button(root, text='Reset', command=sw.Reset).pack(side=LEFT) Button(root, text='Quit', command=sys.exit(0)).pack(side=LEFT) root.mainloop()
  • 99. Universidad de Deusto . . . . ESIDE Ejemplo de GUI con Pmw
  • 100. Universidad de Deusto . . . . ESIDE wxPython I  Basado en wxWidgets toolkit:  Creada para proveer una manera barata y flexible de maximizar la inversión realizada en el desarrollo de GUIs  Hasta Febrero del 2004, wxWidgets era conocida como wxWindows, pero Microsoft “sugirió” un cambio de nombre ...  Instalación:  http//www.wxpython.org/downloads  En UNIX requiere las librerías glib y gtk+ y wxGTK (disponible en http://www.wxwidgets.org )  Para Windows usar: wxPython2.5-win32-unicode-2.5.3.1- py24.exe
  • 101. Universidad de Deusto . . . . ESIDE wxPython II  En wxPython todas las clases están definidas dentro del módulo wx  Para crear una aplicación en wxPython hay que crear una clase que deriva de wx.App y sobreescribe el método OnInit  Toda aplicación está formada al menos de un Frame o un Dialog  Los marcos pueden contener otros paneles, barras de menús y herramientas (MenuBar y ToolBar ) y línea de estado (StatusBar)
  • 102. Universidad de Deusto . . . . ESIDE wxPython III  Los marcos y diálogos contienen controles: Button, CheckBox, Choice, ListBox, RadioBox y Slider, ...  Existen diálogos predefinidos: MessageDialog o FileDialog  A través del programa wxPythondemodemo.py se pueden ver demos  Vienen acompañadas de código fuente
  • 103. Universidad de Deusto . . . . ESIDE Ejemplo wxPython I #!/usr/bin/env python # gui/wxPythonSemanaESIDE.py __author__ = "Diego Ipiña <dipina@eside.deusto.es>" import wx class Frame(wx.Frame): """Clase frame que visualiza una imagen.""" def __init__(self, image, parent=None, id=-1, pos=wx.DefaultPosition, title='¡Hola, semaneros ESIDE!'): """Crea un Frame y visualiza imagen.""" temp = image.ConvertToBitmap() size = temp.GetWidth(), temp.GetHeight() wx.Frame.__init__(self, parent, id, title, pos, size) self.bmp = wx.StaticBitmap(parent=self, id=-1, bitmap=temp)
  • 104. Universidad de Deusto . . . . ESIDE Ejemplo wxPython II class App(wx.App): """Clase aplicación.""“ def __init__(self): wx.App.__init__(self) def OnInit(self): wx.InitAllImageHandlers() image = wx.Image('semanaeside.jpg', wx.BITMAP_TYPE_JPEG) self.frame = Frame(image) self.frame.Show() self.SetTopWindow(self.frame) return True def main(): app = App() app.MainLoop() if __name__ == '__main__': main()
  • 105. Universidad de Deusto . . . . ESIDE wxGlade  No siempre es necesario (o conveniente) crear de manera programática las interfaces en wxPython.  Hay herramientas que nos ayudarán a generar el código wxPython correspondiente:  wxGlade (http://wxglade.sourceforge.net/)
  • 106. Universidad de Deusto . . . . ESIDE Manejo de eventos en wxPython  Toda control define una serie de eventos que se lanzan cuando el usuario interactúa sobre ellos  Mirar documentación de wxWidgets (http://www.wxwidgets.org/manuals/2.5.2/wx_contents.html)  wxPython define por cada control una tabla de eventos que asocia un tipo de evento con un gestor del mismo ... wx.EVT_BUTTON(self, self.botonNuevoUsuario.GetId(), self.OnNuevoUsuario) ... def OnNuevoUsuario(self, evt): # código para crear nuevo usuario
  • 107. Universidad de Deusto . . . . ESIDE Gestores de posicionamiento en wxPython  Representados por wx.Sizer y sus descendientes en la jerarquía de clases de wxPython  Definen posicionamiento de controles en diálogos, independientes de la plataforma, teniendo en consideración las diferencias en tamaño y estilo de los controles individuales  GridSizer: dispone los controles en una matriz donde las celdas tienen el mismo tamaño  BoxSizer: dispone controles en una fila o columna  bsizer = wx.BoxSizer(wx.VERTICAL) topSizer = wx.BoxSizer(wx.HORIZONTAL) topSizer.Add(nombreUsuarioLabel, 0, wx.GROW|wx.ALL, 4) topSizer.Add(self.nombreUsuarioTxtCtrl, 0, wx.GROW|wx.ALL|wx.ALIGN_RIGHT , 4) bsizer.Add(topSizer, 0, wx.GROW|wx.ALL, 4) bsizer.Fit(self) self.SetSizer(bsizer)
  • 108. Universidad de Deusto . . . . ESIDE Dibujando gráficos en wxPython  Preciso usar un contexto de dispositivo (device context ó DC).  DC es la clase base para ClientDC, PaintDC, MemoryDC, PostScriptDC, MemoryDC, MetafileDC y PrinterDC  Se puede utilizar exactamente el mismo código para dibujar encima de cualquiera de estos dispositivos  Algunos ejemplos de las funciones disponibles para dibujar son DC.DrawLine, DC.DrawCircle o DC.DrawText.  Para optimizar el pintado de figuras geométricas, es recomendable incluir las primitivas de dibujo entre las llamadas DC.BeginDrawing y DC.EndDrawing.  El color del fondo de cada figura dibujada se puede controlar con el concepto de brocha (Brush) y el grosor y color de los bordes de cada figura con el concepto de bolígrafo (Pen).
  • 109. Universidad de Deusto . . . . ESIDE Ejemplo dibujado gráficos wxPython I dc = wx.PaintDC(self) dc.Clear() dc.BeginDrawing() dc.SetPen( wx.Pen("BLACK",1) ) dc.SetBrush( wx.Brush("RED") ) cabecera = "Total partidas jugadas: " + str(int(partidasJugadas)) (w, h) = dc.GetTextExtent(cabecera) dc.DrawText(cabecera, 320-(w/2), 70-h) (w, h) = dc.GetTextExtent("Ganadas") dc.DrawText("Ganadas", 160-(w/2), 390-h) dc.DrawRectangle(100, 350, 120, -alturaBarraGanadas) (w, h) = dc.GetTextExtent(`self.resultadoEstadisticas[0]`) dc.DrawText(‘self.resultadoEstadisticas[0]’, 160-(w/2), 350-alturaBarraGanadas-20) ...
  • 110. Universidad de Deusto . . . . ESIDE Ejemplo dibujado gráficos wxPython II
  • 111. Universidad de Deusto . . . . ESIDE Ejemplo: Tres En Raya
  • 112. Universidad de Deusto . . . . ESIDE Programación Web Python  Necesitamos instalar Apache 2.0  El módulo de Apache mod_python
  • 113. Universidad de Deusto . . . . ESIDE Servidor HTTP Apache  El servidor HTTP Apache es una herramienta software libre tanto para las plataformas UNIX como Windows NT.  Su objetivo es proporcionar un servidor web seguro, eficiente y extensible que provea servicios HTTP acorde con el estándar actual de este protocolo.  Apache es desde 1996 el servidor web más popular.  El estudio de Netcraft de Febrero del 2005 así lo atestigua, más del 68% de los portales web usan Apache.  Este servidor es un desarrollo de la Apache Software Foundation.  http://httpd.apache.org/
  • 114. Universidad de Deusto . . . . ESIDE Popularidad de Apache http://news.netcraft.com/archives/web_server_survey.html
  • 115. Universidad de Deusto . . . . ESIDE Instalación de Apache  La mayoría de las distribuciones Linux ya traen preinstalado este servidor bien en su versión 1.3 o 2.0  Nosotros utilizaremos 2.0  Instalación:  Para Windows bajar fichero .msi de http://httpd.apache.org/  Para Linux, utilizar vuestro gestor de paquetes favorito para su instalación:  Con yum: yum install httpd  Con apt-get para instalar Apache2 y PHP 4: apt-get install apache2 libapache2-mod-php4
  • 116. Universidad de Deusto . . . . ESIDE Programación Web Python  Pasos para desarrollar aplicaciones web en Python:  Instalar Apache 2.0, disponible en: http://httpd.apache.org/download.cgi  Instalar mod_python 3.1.2b: http://httpd.apache.org/modules/python-download.cgi (si tienes problemas instalando en Python ir a: http://www.lehuen.com/nicolas/download/ o http://www.modpython.org/pipermail/mod_python/2004-April/015474.html)  Modificar Apache2confhttpd.conf, encontrar otras líneas LoadModule y añadir los siguiente: LoadModule python_module modules/mod_python.so  Comprobar instalación en: http://www.modpython.org/live/current/doc-html/inst-testing.html  Configurar Apache añadiendo a httpd.conf las siguientes líneas, para dar soporte a CGIs en Python y PSPs (Python Server Pages): <Directory "<dir-donde-guardar-python-scripts>"> AddHandler mod_python .py PythonHandler mod_python.publisher PythonDebug On </Directory> <Directory "<dir-donde-guardar-paginas-psp>"> AddHandler mod_python .psp PythonHandler mod_python.psp PythonDebug On </Directory>  Usar el módulo cgi de la Python Library para programar y seguir documentación de mod_python (http://www.modpython.org/live/current/doc-html/)
  • 117. Universidad de Deusto . . . . ESIDE Ejemplo CGI I # Copiar contenido examplescgi-bin a %APACHE_HOME% # cgi-bin/python/holamundo.py # metodos de ayuda del CGI def _formatAsHTML(req, content): req.content_type = "text/html" return "<html><head><title>Hola Mundo Python CGI</title></head><body><h1>Ejemplo Python de CGI</h1><p>" + content + "</p></body></html>" def _usage(): return "Uso: Debes especificar un parametro de nombre ‘quien’, para saber a quien saludar, e.j: http://localhost:8080/cgi- bin/python/holamundo.py/diHola?quien=Diego"
  • 118. Universidad de Deusto . . . . ESIDE Ejemplo CGI II # único método público que se puede invocar al que hay que pasar obligatoriamente un parámetro def diHola(req, quien=""): if not quien: return _formatAsHTML(req, _usage()) return _formatAsHTML(req, "¡Hola " + quien + "!") # si no se especifica un metodo en la url se invoca index por defecto, # es decir http://localhost:8080/cgi-bin/python/holamundo.py def index(req, **params): paramsPassedStr = "" if params: for param in params: paramsPassedStr += (param + "n") return _formatAsHTML(req, "Unico metodo publico en CGI es diHola<br>Parametros recibidos: " + paramsPassedStr + "<br>" + _usage())
  • 119. Universidad de Deusto . . . . ESIDE Python Server Pages  Mecanismo para incluir sentencias Python en documentos HTML o XML  Similar a PHP, JSP o ASP  ¿Es buena práctica mezclar marcado y código?  Patrón de diseño MVC  Sintaxis muy similar a JSP, 4 tipos de entidades:  Código en Python delimitado por códigos de escape <% y %>.  Expresiones delimitadas por <%= y %>.  Directivas, <%@ incluye file=’nombre-fichero’>  Comentarios delimitados por los símbolos <%-- y --%>  IMPORTANTE: el intérprete de PSP recuerda la última tabulación de Python.
  • 120. Universidad de Deusto . . . . ESIDE Python Server Pages  Hay un conjunto de variables accesibles por PSP en tiempo de ejecución:  req, referencia a un objeto de tipo Request  psp, objeto de tipo PSPInstance que permite invocar métodos como redirect(location) o set_error_page(filename)  form, objeto de tipo FieldStorage  session, objeto de tipo Session
  • 121. Universidad de Deusto . . . . ESIDE Ejemplo PSP <!– /cgi-bin/psp/login.psp --> <% import tresenrayaweb import RegistroJugadoresDB if not session.has_key('registro'): session['registro'] = RegistroJugadoresDB.RegistroJugadoresDB() mensajeError = "" if form.has_key('nombreUsuario') and form.has_key('clave'): try: session['registro'].login(form['nombreUsuario'], form['clave']) psp.redirect('/cgi-bin/psp/tresenraya.psp?nombreUsuario=' + form['nombreUsuario']) except: mensajeError = 'Los detalles de login introducidos son incorrectos' saludo = 'Introduce tus detalles de logeo para jugar al Tres en Raya' # end %> <html> <h1><%= saludo %></h1> <form method="post" action="/cgi-bin/psp/login.psp"> <table> <tr><td>Nombre usuario:</td><td><input type="text" name="nombreUsuario"></td></tr> <tr><td>Contraseña:</td><td><input type="password" name="clave"></td></tr> <tr><td><input type="submit" value="Login"></td><td><input type="reset" name="Limpiar"></td></tr> </table> </form> <% if len(mensajeError): %> <p><%=mensajeError%></p> <% # end if %> </html>
  • 122. Universidad de Deusto . . . . ESIDE Ejemplo Python !/usr/bin/env python # -*- coding: iso-8859-1 -*- import MySQLdb, string, _mysql, _mysql_exceptions, tresenraya class RegistroJugadoresDB(tresenraya.RegistroJugadores): def __init__(self): tresenraya.RegistroJugadores.__init__(self) db=MySQLdb.connect(host="localhost",user="tresenraya", passwd="tresenraya", db="tresenraya") self.cursor = db.cursor() # Asegurarse que si no existe un usuario solop se añada usuarioSolop = self._executeSQLCommand("select * from usuario where nombreUsuario='solop'") if not len(usuarioSolop): self._executeSQLCommand("insert into usuario values('solop', 'solop')") self._executeSQLCommand("insert into estadistica values('solop', 0, 0, 0)") print 'Usuario solop y sus estadisticas creadas' else: usuarios = self._executeSQLCommand("select * from usuario") for usuario in usuarios: self._RegistroJugadores__jugadores[usuario[0]] = usuario[1] # recuperamos las estadísticas de partidas de un jugador estadisticasUsuario = self._executeSQLCommand("select ganadas, empatadas, perdidas from estadistica where nombreUsuario='" + usuario[0] + "'") self._RegistroJugadores__estadisticas[usuario[0]] = [int(estadisticasUsuario[0][0]), int(estadisticasUsuario[0][1]), int(estadisticasUsuario[0][2])]
  • 123. Universidad de Deusto . . . . ESIDE Ejemplo Python def _executeSQLCommand(self, command): # si la consulta devuelve resultados lo hará como una lista de tuplas, donde cada tupla # representa una fila de la tabla correspondiente, y cada elemento de la tupla una columna resultado = [] command = string.strip(command) if len(command): try: resultCode = self.cursor.execute(command) # Ejecuta el comando if string.lower(command).startswith('select'): # si es una select ... filas = self.cursor.fetchall() # recuperar todos los resultados for fila in filas: contenidoFila = [] for columna in fila: if columna == None: contenidoFila.append(None) else: contenidoFila.append(columna) resultado.append(tuple(contenidoFila)) except _mysql_exceptions.ProgrammingError, e: print e sys.exit() return resultado # sigue más código
  • 124. Universidad de Deusto . . . . ESIDE Aplicación LAMP con Python
  • 125. Universidad de Deusto . . . . ESIDE LCE Sentient Library
  • 126. Universidad de Deusto . . . . ESIDE Programación distribuida: CORBA con omniORBpy  Desde Python se puede usar tanto CORBA (omniORBpy) como servicios web (SOAPpy disponible en http://pywebsvcs.sourceforge.net/)  En este curso nos concentramos sólo en CORBA:  Download omniORBpy de: http://omniorb.sourceforge.net/  Desarrollada por Duncan Grisby en AT&T Labs Cambridge  Basada en la ORB para C++: omniORB  Descomprimir y compilar en Linux o simplemente descomprimir en Windows  Las siguientes variables de entorno son necesarias:  PYTHONPATH=<omniORBpy-install-dir>/lib/python; <omniORBpy-install-dir>libx86_win32  PATH=$PATH:=<omniORBpy-install-dir>/bin/x86_win32  LD_LIBRARY_PATH=<omniORBpy-install- dir>lib<platform>  Para compilar IDL usar: omniidl -bpython <fichero-idl- a-compilar>
  • 127. Universidad de Deusto . . . . ESIDE Ejemplo CORBA: IDL // corba/example_echo.idl module Example { interface Echo { string echoString(in string mesg); }; };
  • 128. Universidad de Deusto . . . . ESIDE Ejemplo CORBA: servidor #!/usr/bin/env python import sysfrom omniORB import CORBA, PortableServer # Import the stubs and skeletons for the Example module import Example, Example__POA # Define an implementation of the Echo interface class Echo_i (Example__POA.Echo): def echoString(self, mesg): print "echoString() called with message:", mesg return mesg # Initialise the ORB orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID) # Find the root POA poa = orb.resolve_initial_references("RootPOA") # Create an instance of Echo_ie i = Echo_i()# Create an object reference, and implicitly activate the objecte o = ei._this() # Print out the IOR print orb.object_to_string(eo) # Activate the POA poaManager = poa._get_the_POAManager() poaManager.activate() # Everything is running now, but if this thread drops out of the end # of the file, the process will exit. orb.run() just blocks until the # ORB is shut down orb.run()
  • 129. Universidad de Deusto . . . . ESIDE Ejemplo CORBA: servidor #!/usr/bin/env pythonimport sys # Import the CORBA module from omniORB import CORBA # Import the stubs for the Example module import Example # Initialise the ORB orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID) # Get the IOR of an Echo object from the command line (without # checking that the arguments are sensible!) ior = sys.argv[1] # Convert the IOR to an object reference obj = orb.string_to_object(ior) # Narrow reference to an Example::Echo objecte o = obj._narrow(Example.Echo) if eo is None: print "Object reference is not an Example::Echo" sys.exit(1) # Invoke the echoString operation message = "Hello from Python" result = eo.echoString(message) print "I said '%s'. The object said '%s'." % (message,result)
  • 130. Universidad de Deusto . . . . ESIDE SOA  Los servicios web han dado lugar a un nuevo modo de diseñar sistemas distribuídos:  Arquitecturas SOA (Service Oriented Arquitecture)  SOA = colección de servicios  Más información en http://www.service- architecture.com/  http://msdn.microsoft.com/Longhorn/understandi ng/pillars/Indigo/default.aspx?pull=/library/en- us/dnbda/html/srorientwp.asp
  • 131. Universidad de Deusto . . . . ESIDE Servicios Web  Son un estándar basado en protocolos abiertos como HTTP y SOAP  SOAP es un vocabulario XML que representa RPCs  http://www.w3.org/TR/SOAP  No necesitas ni Windows ni .NET, ni UNIX ni Java para escribir servicios web  Servicio web = aplicación que:  se ejecuta en un servidor web  expone métodos a clientes  escucha peticiones HTTP representando comandos que invocan a métodos Web  ejecuta métodos web y devuelve resultados
  • 132. Universidad de Deusto . . . . ESIDE SOAP  SOAP es un protocolo de comunicación basado en XML útil para la comunicación entre aplicaciones  Actualmente en versión 1.2, aunque la más utilizada es la 1.1  http://www.w3.org/2000/xp/Group/  SOAP es reconocido como el backbone de una nueva generación de aplicaciones multi-platforma y multi-lenguaje, denominado Servicios Web.  SOAP es un mecanismo para el intercambio de mensajes a través de Internet independiente de los lenguajes de programación  Es un protocolo de transporte  Los clientes envían una petición SOAP mediante un HTTP POST normalmente y reciben un código de respuesta (éxito o error) y una respuesta SOAP  Un mensaje SOAP es un mensaje XML que consta de un conjunto de cabeceras opcionales y de un cuerpo.
  • 133. Universidad de Deusto . . . . ESIDE Petición SOAP <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/ soap/envelope/"> <soap:Body> <getProductDetails xmlns="http://warehouse.example.com/ws" > <productId>827635</productId> </getProductDetails> </soap:Body> </soap:Envelope>
  • 134. Universidad de Deusto . . . . ESIDE Respuesta SOAP <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getProductDetailsResponse xmlns="http://warehouse.example.com/ws"> <getProductDetailsResult> <productName>Toptimate 3-Piece Set</productName> <productId>827635</productId> <description>3-Piece luggage set. Black Polyester.</description> <price>96.50</price> <inStock>true</inStock> </getProductDetailsResult> </getProductDetailsResponse> </soap:Body> </soap:Envelope>
  • 135. Universidad de Deusto . . . . ESIDE Servicios Web en Python  En la siguiente URL tenemos información sobre las APIs disponibles:  http://pywebsvcs.sourceforge.net/  Revisar artículos sobre desarrollo de servicios web en Python en:  http://www- 106.ibm.com/developerworks/library/ws- pyth5/
  • 136. Universidad de Deusto . . . . ESIDE SOAPpy - Simple to use SOAP library for Python  Requiere la previa instalación de:  XML package for Python, http://pyxml.sourceforge.net/  Hacer doble clic sobre PyXML-0.8.4.win32-py2.4.exe  Fpconst, librería para trabajar con números en coma flotante http://research.warnes.net/projects/rzope/fpconst/  Ofrece soporte para valores especiales Not-a-Number (NaN), Positive Infinity (Inf), y Negative Infinity (-Inf), parte de la especificación SOAP  Extraer fpconst-0.7.2.zip  cd <directorio-donde-se-ha-extraido-fpconst-0.7.2.zip>  Python setup.py install  SOAPpy, http://pywebsvcs.sourceforge.net/  Extraer fichero SOAPpy-0.12.0.zip  cd SOAPpy-0.12.0  python setup.py build  python setup.py install
  • 137. Universidad de Deusto . . . . ESIDE Servidor Hola Mundo import SOAPpy def hello(): return "Hello World" server = SOAPpy.SOAPServer(("localhost ", 8080)) server.registerFunction(hello) server.serve_forever()
  • 138. Universidad de Deusto . . . . ESIDE Cliente Hola Mundo import SOAPpy server = SOAPpy.SOAPProxy("http://loca lhost:8080/") print server.hello()
  • 139. Universidad de Deusto . . . . ESIDE Explicación SOAPpy  El objeto SOAProxy maneja todos los detalles internos del uso de SOAP  Crea un intermediario (proxy) entre nosotros y el servicio web final  Podemos utilizar las propiedades dumpSOAPIn y dumpSOAPOut para ver el contenido de las peticiones y respuestas SOAP
  • 140. Universidad de Deusto . . . . ESIDE Debugging con SOAPpy >>> from SOAPpy import SOAPProxy >>> url = 'http://services.xmethods.net:80/soap/servlet/r pcrouter' >>> n = 'urn:xmethods-Temperature' >>> server = SOAPProxy(url, namespace=n) 1 >>> server.config.dumpSOAPOut = 1 2 >>> server.config.dumpSOAPIn = 1 >>> temperature = server.getTemp('27502')
  • 141. Universidad de Deusto . . . . ESIDE WSDL  Un fichero WSDL contiene la siguiente información:  La URL y espacio de nombres del servicio  El tipo de servicio web  La lista de funciones disponibles  Los argumentos de estas funciones  Los tipos de datos de cada argumento  Los valores de retorno de cada función y sus tipos
  • 142. Universidad de Deusto . . . . ESIDE Obteniendo Metainformación de un Servicio Web from SOAPpy import WSDL wsdlFile = 'http://www.xmethods.net/sd/2001/TemperatureSer vice.wsdl' server = WSDL.Proxy(wsdlFile) server.methods.keys() callInfo = server.methods['getTemp'] print callInfo.inparams print callInfo.inparams[0].name print callInfo.inparams[0].type print callInfo.outparams print callInfo.outparams[0].name print callInfo.outparams[0].type
  • 143. Universidad de Deusto . . . . ESIDE Un poco de Jython  Download Jython de:  http://www.jython.org/download.html  Para instalar simplemente ejecutar: java jython-21  Usa Lift-Off Java-Installer: http://liftoff.sourceforge.net/  Algunos ejemplos de Jython en:  http://www.jython.org/applets/index.html  Documentación básica sobre Jython disponible en:  http://www.jython.org/docs/usejava.html
  • 144. Universidad de Deusto . . . . ESIDE Jython  Jython (http://www.jython.org) es una implementación open source en Java de Python que se integra de manera transparente con la plataforma Java.  Jython complementa a Java y es especialmente indicada para las siguientes tareas:  Empotrar scripts en aplicaciones Java, de modo que los usuarios finales puedan escribir scripts que añadan funcionalidad a la aplicación.  Experimentación interactiva por medio del intérprete interactivo suministrado por Jython que permite interactuar con los paquetes Java o aplicaciones en ejecución.  Desarrollo rápido de aplicaciones. Los programas en Python son típicamente entre 2 y 10 veces más cortos que los programas Java. Esto se traduce en una mayor productividad en la programación. La integración transparente de Jython y Java permite combinar estos dos lenguajes en productos.
  • 145. Universidad de Deusto . . . . ESIDE Ejemplo Jython: TresEnRaya
  • 146. Universidad de Deusto . . . . ESIDE IronPython  En Marzo del 2004 en la conferencia PyCon fue presentado IronPython (http://ironpython.com/)  Una implementación Python orientada a las plataformas .NET y Mono.  Sus características principales son:  Tan rápida como la versión estándar de Python  Integrada de modo transparente con la Common Language Runtime de .NET. Desde IronPython podemos usar las librerías de clases .NET y extender otras clases .NET  Dinámico, soporta el modo de ejecución interactivo como Python  Opcionalmente estático, se pueden compilar ficheros Python para producir ejecutables (.exes) que pueden ejecutarse directamente o incluso dlls.  Soporta código gestionado (managed code)  No finalizado, todavía en versión alfa no puede ser utilizada para producción de software.  IronPython parece una contribución prometedora que nos permitirá programar aplicaciones .NET desde la cómoda y sencilla sintaxis de Python.  ¡Mantente atento a los progresos en este proyecto.!
  • 147. Universidad de Deusto . . . . ESIDE Casos de éxito de Python  BitTorrent (http://bitconjurer.org/BitTorrent/), sistema P2P que ofrece mayor rendimiento que eMule  PyGlobus, permite la programación de Grid Computing (http://www-itg.lbl.gov/gtg/projects/pyGlobus/)  ZOPE (www.zope.org) es un servidor de aplicaciones para construir y gestionar contenido, intranets, portales, y aplicaciones propietarias  Industrial Light & Magic usa Python en el proceso de producción de gráficos por ordenador  Google usa Python internamente, lo mismo que Yahoo para su sitio para grupos  Red Hat Linux utiliza Python para la instalación, configuración, y gestión de paquetes.  Más historias de éxito de Python en: http://pbf.strakt.com/success
  • 148. Universidad de Deusto . . . . ESIDE Recursos utilizados  Compilador de Python 2.4 y documentación:  http://www.python.org/2.4/  Extensiones para Windows:  https://sourceforge.net/projects/pywin32/  Módulo de bases de datos MySQLdb 0.9.2:  http://sourceforge.net/projects/mysql-python  Base de datos MySQL 4.1:  http://www.mysql.com/downloads/  omniORBpy  http://omniorb.sourceforge.net/  Servidor Apache 2.0 (http://httpd.apache.org/)  Módulo mod_python para Apache: http://www.modpython.org  wxPython 2.5:  http://www.wxpython.org/download.php#binaries  Jython 2.1  http://www.jython.org/download.html
  • 149. Universidad de Deusto . . . . ESIDE References  Libro “Dive into Python”, http://diveintopython.org/http://diveint opython.org/  Librería de Python: http://docs.python.org/lib/lib.html