Sei sulla pagina 1di 7

Python 121.

qxd

17/12/04

01:06

Pgina 36

MIDDLEWARE

Pensando en Python (y IV):


XML, Java e IA
DIEGO LZ. DE IPIA GZ. DE ARTAZA (profesor del
Departamento de Ingeniera del Software de la Facultad
de Ingeniera (ESIDE) de la Universidad de Deusto)

Acabamos esta serie sobre Python


examinando su capacidad para el
procesamiento de XML
e introduciendo Jython, la
implementacin Java de Python.
Tambin discutiremos una
implementacin ms inteligente del
juego de tres en raya que usa un
algoritmo de inteligencia artificial.
Introduccin

XML define
datos portables
y Python define
el cdigo fuente
SOLO PROGRAMADORES n 121

36

En los ltimos aos el estndar XML (eXtensible


Markup Language) se ha establecido como el principal mecanismo para el intercambio de datos entre
aplicaciones. XML es un metalenguaje que permite
disear otros lenguajes. Algunos ejemplos de lenguajes derivados de XML son WML, MathML o
XHTML. Con XML cualquiera puede desarrollar su
propio lenguaje de etiquetas adecuado al tipo de
aplicacin que ms le convenga. Un documento XML
puede ser fcilmente procesado y sus datos manipulados, por medio de APIs estndar disponibles en lenguajes como Java, C, C++, C# y, por supuesto,
Python. En esencia, XML define datos portables, al
igual que Python o Java definen cdigo portable.
Por otra parte, el lenguaje de programacin Java ha
experimentado desde su nacimiento en 1995 un crecimiento extraordinario. En los ltimos 10 aos Java
no slo ha ido madurando como lenguaje de programacin si no que gracias al ofrecimiento gratuito por
parte de Sun de la JDK (Java Development Kit) su
adopcin ha sido espectacular. Como resultado ha
habido numerossimas contribuciones de cdigo
abierto que facilitan el desarrollo de cualquier problema informtico que podamos concebir. Jython, la
implementacin Java de Python, fue creado para
poder aprovechar todas estas contribuciones del
mundo Java y tener acceso a su funcionalidad desde
la elegante sintaxis de Python.
En este artculo describiremos cmo programar aplicaciones que usan XML y acceden a paquetes des-

arrollados en Java desde Python. Concluiremos con


una discusin del algoritmo de inteligencia artificial
MiniMax que permitira a la mquina ser un contrincante de entidad en el juego de tres en raya.

XML
En las prximas lneas vamos a hacer un repaso de la
tecnologa XML, aunque este tema ha sido tratado
con profundidad en ediciones anteriores de Slo
Programadores. Si el lector quiere ampliar lo aqu
expuesto, puede consultar los nmeros 110, 111, 114,
115 y 116.
XML no es slo un lenguaje de lenguajes, es tambin
un conjunto de tecnologas que permiten su representacin y procesamiento, tales como XPath, XLink,
XPointer o XML. La especificacin de XML 1.0 puede
encontrarse en la direccin de Internet
http://www.w3.org/TR/REC-xml. Un documento XML
est estructurado en los siguientes componentes:
z Instrucciones de procesamiento (processing
instructions PI). Las PI son instrucciones para
el procesador del documento XML. El prlogo
del documento es una PI obligatoria:
<?xml version=1.0 encoding=iso-8859-1?>
z

Declaraciones de tipo de documento.


Especifican la estructura y sintaxis de un documento XML a travs de una gramtica bien en
la forma de un DTD (Document Type
Definition) o un Schema. Se declaran en un
documento en el siguiente modo:
<!DOCTYPE <elemento-raz> SYSTEM
<fichero-con-dtd>

A travs del DTD una instancia de un documento puede ser validada contra la gramtica
que define los elementos y posicin de los mismos en un documento.
Comentarios. Sirven para realizar anotaciones
tiles al autor del documento. Un ejemplo sera:
<! Esto es un comentario >

Elementos. Aportan estructura semntica al


documento. Se delimitan por etiquetas de
apertura y cierre o vienen sin elementos interiores (etiquetas vacas como <br/>). Las etiquetas de apertura y las vacas suelen venir

Python 121.qxd

17/12/04

01:06

Pgina 37

MIDDLEWARE

Pensando en Python (y IV): XML, Java e IA

acompaadas de atributos, que parametrizan el elemento.


Referencias a entidades. Sirven para
insertar un determinado contenido definido previamente. Por ejemplo:
<!ENTITY Empresa Universidad de
Deusto>...<pie>Creado por &Empresa;
</pie>

Secciones CDATA. Contienen texto que


no queremos sea procesado por el parser
de XML. Por ejemplo:
<![CDATA[<saludo>Hola, mundo!
</saludo>]]>

Las razones fundamentales del xito de XML


son:
z Permite etiquetar los datos con su significado (self-describing data).
z Estructurar la informacin de acuerdo a
las necesidades de la aplicacin.
z Tratar automticamente la informacin a
travs de procesadores libremente disponibles, que se ajustan a APIs estndar.
XML es la base de una nueva generacin de
aplicaciones web, siendo un estndar para el
intercambio de datos. Entre otras cosas XML
se utiliza como formato de datos en sitios web
para separar contenido y presentacin, como
medio de comunicacin para el intercambio
de datos entre organizaciones o para la transmisin de mensajes en servicios web (SOAP).

Procesamiento XML
La popularidad de XML estriba en no tener que
crear un nuevo compilador por cada lenguaje de
representacin de datos que queremos disear.
Las herramientas que llevan a cabo la validacin
lxica y sintctica de los documentos y su transformacin en una representacin manejable por
programas vienen ya dados. A cambio, los diseadores de nuevos tipos de documentos XML
slo deben seguir las restricciones que un documento XML bien formado debe cumplir:
z Debe tener un prlogo.
z Debe tener una etiqueta (elemento) raz.
z Las etiquetas se hallan correctamente
anidadas.
z Se usan caracteres vlidos y bien aplicados.
z Los valores de los atributos vienen encerrados entre comillas.
La industria utiliza tres estndares principales para el procesamiento de documentos
XML: SAX, DOM y XSL. A continuacin, pasamos a describirlos en ms detalle.

Procesamiento de XML con SAX


SAX es el estndar de facto para el procesamiento de XML basado en eventos. Fue definido
por David Megginson, siendo su especificacin
disponible en http://www.megginson.com/SAX.
No es un analizador XML, si no que define una
interfaz comn implementada por los analizadores XML SAX. Un analizador SAX genera un
evento por cada componente significativo del
documento detectado. Por ejemplo el comienzo
o final del documento, o el comienzo y final del
elemento. Un programador que usa SAX debe
implementar manejadores de los eventos notificados. SAX opera sobre un documento leyendo
secuencialmente de principio a fin, sin cargar
todo el documento en memoria. Presenta como
principal ventaja una gran eficiencia en cuanto
al tiempo y la memoria empleados en el anlisis.
La principal desventaja de SAX es que tenemos
que mantener estado intermedio, a diferencia
de otros estndares como DOM.

Procesamiento de XML con DOM


Un documento XML es para DOM un rbol de
nodos, donde cada nodo representa a un elemento XML. Los elementos hijos y el texto
contenido dentro de un elemento son subnodos. La especificacin DOM es un estndar
W3C disponible en http://www.w3.org/DOM/.
La principal ventaja de DOM es que permite
acceder a datos en funcin de la jerarqua de
elementos, as como modificar el contenido
de los documentos e incluso crearlos desde
cero. La principal desventaja es el coste en
tiempo y memoria que conlleva construir el
rbol. A diferencia de SAX que efecta una
pasada del documento de izquierda a derecha y de arriba abajo, carga todo el documento XML en memoria. Para documentos
largos la demanda de memoria puede ser
ingente. Como consecuencia de ello, DOM no
es adecuado para efectuar procesamiento de
XML en dispositivos empotrados con poca
capacidad de cmputo y memoria.

Procesamiento de XML con XSL


Dada la diversidad de lenguajes de presentacin (WML, HTML, cHTML), existen dos alternativas para desarrollar aplicaciones basadas en pginas:
z Desarrollar versiones de los procesos de
generacin de presentacin (JSP, ASP,
CGI,..) para cada lenguaje de marcado final.
z Desarrollar slo una versin que genere
XML y conversores de XML a los lenguajes de presentacin.

El lenguaje de programacin XSL fue diseado para responder al segundo enfoque, y el


lector debera ser conocedor de ello, pues
XSL-FO es objeto de nuestro estudio desde
hace unos meses. XSL consta de dos partes:
z XML Stylesheet Transformation Language
(XSLT)
z XSL Formatting Language (XSL-FO)
XSLT es el componente de XSL que transforma un documento XML en otro documento
XML. XSL-FO formatea y estiliza documentos en varios modos. La especificacin de
XSLT se encuentra disponible en
http://www.w3.org/TR/xslt. Las principales
ventajas de XSLT son:
z No asume un nico formato de salida de
documentos.
z Permite manipular de muy diversas
maneras un documento XML: reordenar
elementos, filtrar, aadir, borrar, etc.
Las desventajas de XSLT son:
z Su utilizacin es ms compleja que un
lenguaje de programacin convencional.
z Consume bastante memoria y capacidad
de proceso, usa DOM por debajo.

Programacin XML en Python


Para ilustrar el poder de Python en la programacin de aplicaciones XML vamos a considerar el fragmento de cdigo XML del listado
1. Este listado corresponde a la cartelera de
todos los cines en una ciudad. Por cada cine
listado, incluimos las pelculas que se muestran en l y los horarios de sus sesiones.

Procesamiento SAX en Python


El soporte para SAX en Python es ofrecido por
el mdulo xml.sax de la librera estndar de
Python (http://docs.python.org/lib/modulexml.sax.html). Este mdulo define una funcin
principal, make_parser(), a travs de la cual
crea y devuelve un objeto de tipo XMLReader,
que corresponde con un procesador SAX. La
definicin de esta clase se encuentra en el
mdulo xml.sax.xmlreader. El mdulo
xml.sax.handler define manejadores de eventos para SAX. Para asignar un manejador de
eventos a un procesador SAX se invoca el
mtodo setContentHandler(handler), donde
handler es una referencia a un objeto que
implementa la interfaz xml.sax.hander.
ContentHandler. Esta interfaz define mtodos
tales como startdocument o endelement
que son invocados cundo se genera un even37

SOLO PROGRAMADORES n 121

Python 121.qxd

17/12/04

01:06

Pgina 38

MIDDLEWARE

LISTADO 1

peliAttribs.getNamedItem(codigo).

Documento Cartelera.xml

<?xml version=1.0 encoding=iso-8859-1?>


<Cartelera>
<Cine codigo=1 nombre=Guridi Zinemak direccion=San Prudencio
poblacion=Vitoria-Gasteiz>
<Pelicula codigo=1 titulo=Malena
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>
...
</Cartelera>

nodeValue

Permiten recuperar el contenido del atributo cuyo


nombre se pasa al mtodo getNamedItem. La
figura 2 muestra el resultado de tal procesamiento. Puede verse este ejemplo en el fichero
ejemploDOM.py incluido en el CD-ROM.

Procesamiento XSLT en Python


XSLT es un lenguaje de transformacin de documentos XML muy potente y complejo que
requerira para comprenderlo una serie de artculos por si mismo. Hay varias implementaciones
XSLT en Python. Para una discusin sobre las
alternativas disponibles remitimos al lector a
http://uche.ogbuji.net/tech/akara/nodes/200301-01/python-xslt. Nosotros nos hemos decantado por los bindings Python de las libreras XML
de Gnome libxml2 y libxlt. Versiones Windows de
las mismas pueden encontrarse en http://
users.skynet.be/sbi/libxml-python/. Los rpms de
estas libreras para su instalacin en UNIX pueden encontrarse en http://rpmfind.net/
linux/rpm2html/search.php?query=libxml2python y http://rpmfind.net/linux/rpm2html/
search.php?query=libxslt-python, respectivamente. El Listado 4 muestra cmo transformar
un documento XML en un documento HTML por
medio de XSLT (documento xsltexample.py disponible en el CD-ROM). Al aplicar a
Cartelera.xml la hoja de XSLT, Cartelera.xsl,
incluida tambin en el CD-ROM, se obtiene la

cin correspondiente
a las pelculas encontradas en el mismo. El
mtodo DOM principal que se utiliza es
getElementsByTag
Name(<nombre-elemento>), que dado el
nombre de un elemento recupera todas
Figura 1. Ejecucin del programa ElementCounterSAX.py
las instancias del
aplicado a Cartelera.xml.
mismo encontradas
to al entrar en una parte significativa del docu- en un rbol DOM. El atributo de un elemento
mento. El listado 2 muestra un ejemplo de DOM attributes se usa para recuperar los atricdigo Python que procesa el fichero butos de cada elemento pelcula. Las sentenCartelera.xml para contar el nmero de ele- cias en la forma:
mentos y atributos XML encontrados en l.
LISTADO 2
Procesamiento del fichero Cartelera.xml usando SAX
Tanto el documento XML (Cartelera.xml) como
el script Python (ElementCounterSAX.py) estn
# Uso: python ElementCounterSAX.py Cartelera.xml
disponibles en el CD-ROM que acompaa a la
import sys
from xml.sax import make_parser, handler
revista. La figura 1 muestra el resultado de la
class ElementCounter(handler.ContentHandler):
ejecucin de este script.
def __init__(self):

Procesamiento DOM en Python


Python provee en el mdulo xml.dom.minidom una implementacin sencilla de DOM. La
funcin parse de este modulo genera a partir
de un fichero un objeto DOM. Este objeto tiene
todos los mtodos y atributos caractersticos del
estndar DOM. Por ejemplo: hasChildNodes(),
childNodes o getElementsByTagName().
Para ms informacin sobre procesamiento
DOM XML en Python se recomienda visitar la
pgina http://pyxml.sourceforge.net/topics/. La
distribucin PyXML, no incluida por defecto en
la distribucin estndar de Python, implementa un procesador de DOM ms completo.
El listado 3 usa el estndar DOM para procesar
el fichero Cartelera.xml y obtener la informa-

SOLO PROGRAMADORES n 121

38

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

Python 121.qxd

17/12/04

01:06

Pgina 39

MIDDLEWARE

Pensando en Python (y IV): XML, Java e IA

LISTADO 3

Procesamiento del fichero Cartelera.xml usando DOM

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*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 = []
def getPeliculas(self):
# Si no hemos ya recuperado las pelculas en el documento ...
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
# crear un nuevo objeto de tipo pelcula
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

LISTADO 4

Procesamiento del fichero Cartelera. XSLT

# Ejecuta: python xsltexample.py Cartelera.xml Cartelera.xsl Cartelera.html


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

pgina web de la figura 3. El listado 5 contiene


slo un pequeo fragmento de la hoja de estilo
Cartelera.xsl.
Una hoja XSLT es un documento XML bien formado que tiene como elemento raz el elemento
xsl:stylesheet. Este elemento contiene un conjunto de xsl:templates, o plantillas de transformacin que asocian un fragmento del documento XML de entrada con otro del documento
XML de salida. En la especificacin de XSLT
http://www.w3.org/TR/xslt, puede encontrarse
una minuciosa descripcin de este lenguaje.

integra de manera transparente con la plataforma Java. Jython complementa a Java y es especialmente indicada para las siguientes tareas:
z Empotrar scripts en aplicaciones Java, de
modo que los usuarios finales puedan escribir scripts que aadan funcionalidad a la
aplicacin.
z Experimentacin interactiva por medio del
intrprete interactivo suministrado por
Jython que permite interactuar con los
paquetes Java o aplicaciones en ejecucin.
z Desarrollo rpido de aplicaciones. Los programas en Python son tpicamente entre 2
y 10 veces ms cortos que los programas
Java. Esto se traduce en una mayor productividad en la programacin. La integracin
transparente de Jython y Java permite
combinar estos dos lenguajes en productos.
Existen otros lenguajes de scripting que se
integran transparentemente con Java como
Jacl, implementacin en Java de Tcl, Rhino,
implementacin en Java de JavasScript o
BeanShell. Sin embargo Jython se distingue de
otras alternativas por:
z Compilacin dinmica de Jython en bytecodes de Java (conduce al mayor rendimiento posible).
z Habilidad para extender las clases Java en
Jython.
z Compilacin esttica opcional, que permite la creacin de applets, servlets y beans.
Lo hace a travs de la herramienta jythonc
que transforma ficheros .PY en .CLASS.
z Uso del lenguaje Python que combina
poder con simplicidad sintctica, soportando el modelo orientado a objetos de Java.
Las herramientas de compilacin/ejecucin de
Jython son disponibles en http://www.
jython.org/download.html. Para instalarlo simplemente hay que ejecutar el comando java jython21, que lanzar el instalador de Jython. Como
prerrequisito, la mquina donde se instale debe
tener preinstalada una mquina virtual de Java. Si
no se dispone de ella, puede ser obtenida desde
http://java.sun.com/j2se/1.4.2/download.html.

Programacin en Jython
Jython bsico
Jython (http://www.jython.org) es una implementacin Open Source en Java de Python que se

La figura 4 muestra una sesin interactiva de


Jython. Para ejecutar el intrprete de Jython

Figura 2. Ejecucin del programa EjemploDOM.py aplicado a Cartelera.xml.

39

SOLO PROGRAMADORES n 121

Python 121.qxd

17/12/04

01:06

Pgina 40

MIDDLEWARE

simplemente hay que escribir en la lnea de


comando jython. El ejemplo muestra cmo
el usuario puede crear una instancia de la
clase Java java.util.Random para obtener
una serie de nmeros aleatorios. Este ejemplo ha sido prestado de http://www.jython.org/docs/usejava. html. Como observamos en la figura, para crear una instancia de
una clase Java se usa la convencin de
Python, es decir una funcin con el nombre
de la clase no precedida del operador new.
En la invocacin de mtodos de clases Java
desde Jython hay que tener en cuenta la
conversin de los tipos de datos de Python a
Java, y cuando se reciben resultados lo
opuesto, es decir, la conversin de tipos de
datos Java en Python. Dado que Python y
Java definen casi los mismos tipos de datos
primitivos, apenas hay nunca problemas
durante esta tarea de coercin (conversin
de tipos de datos).

3.- Tres en Raya modo


grfico en Jython
con acceso a base
de datos MySQL.

Tres en Raya modo


texto en Jython

Nuestra implementacin
original de Tres en Raya en
modo texto, a la que llamamos tresenraya.py, requiere mnimos cambios
para ser ejecutable en
Jython. Tan solo debemos
aadir dos variables globales True y False con los
valores 1 y 0, respectiva3. Pgina web resultante de aplicar Cartelera.xsl a
mente. Esto es debido a que Figura
Cartelera.xml.
Jython no soporta todava
el tipo booleano de Python. Hemos incluido la ver- listado 6 muestra el constructor de la clase
sin modificada de este script en el CD-ROM bajo JuegoTresEnRayaJythonGUI, incluida en el CDel nombre tresenrayajython.py. Las dos nicas ROM bajo el nombre tresenrayajythongui.py,
Transformando la aplicacin Tres
lneas que difieren del script original presentado en junto con la implementacin del mtodo
la primera entrega de este curso son:
onClick. La lgica principal de esta aplicacin
en Raya en una aplicacin Jython
est gobernada por el mtodo jugar no incluido
True = 1
Qu mejor manera de evaluar el potencial de
por falta de espacio pero disponible tambin en el
False = 0
Jython que retomar nuestra conocida aplicacin
CD-ROM. La clase JuegoTresEnRayaJythonGUI
del Tres en Raya y aplicar los cambios requeridos La ejecucin de este script Jython se presen- hereda de tresenrayajython.JuegoTresEnRaya,
para poderla ejecutar en Jython. Vamos a dividir ta en la figura 5.
que es la clase base del juego. En el constructor de
esta tarea de transformacin en tres fases:
Tres en Raya modo grfico en Jython
esta clase: (1) se obtiene una instancia a la imple1.- Tres en Raya modo texto en Jython.
El siguiente paso en la transformacin del juego mentacin de la clase del registro de jugadores
2.- Tres en Raya modo grfico en Jython Tres en Raya en Jython es crear la interfaz grfica que guarda datos en un mapa persistente, (2) se
con acceso a mapa persistente.
del mismo usando el paquete Swing de Java. El invoca al constructor de la clase base y (3) luego
simplemente se crea un Frame donde se coloLISTADO 5
Fragmento hoja de estilo Cartelera.xsl
can los botones correspondientes a las casillas del
tablero de tres en raya.
<?xml version=1.0 encoding=iso-8859-1?>
Obsrvese lo sencillo que es en Jython asig<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version=1.0>
<xsl:output method=html/>
nar un manejador de eventos a un botn:
<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>
<xsl:template match=Cartelera>
<xsl:for-each select=Cine>
<tr>
<th><xsl:text>Cine</xsl:text></th>
<th><xsl:text>Direccin</xsl:text></th>
<th><xsl:text>Poblacin</xsl:text></th>
<th></th>
</tr>
...
</xsl:stylesheet>

SOLO PROGRAMADORES n 121

40

button = swing.JButton(self.icono
Vacio, actionPerformed=self.onClick)

Si hubiramos efectuado una traduccin


literal del cdigo Java a Jython hubiramos
necesitado el siguiente cdigo:
class action(awt.event.ActionListener):
def onClick(self,event):
# la implementacin del manejador
button = swing.JButton(self.iconoVacio)
button.addActionListener(action())

Tres en Raya modo grfico con acceso a


BD en Jython
El tercer y ltimo ejercicio de transformacin que
hemos realizado ha sido convertir la clase
RegistroJugadoresDB que vimos en la tercera
entrega a Jython. En esta ocasin no usamos la

Python 121.qxd

17/12/04

01:06

Pgina 41

MIDDLEWARE

Pensado en Python (y IV): XML, Java e IA

Figura 4. Sesin interactiva de Jython.

DB API de Python, si no que JDBC para acceder a


la base de datos que creamos en la tercera entrega. El script SQL de creacin de la base de datos
tresenraya ha sido incluido en el CD-ROM
junto con las instrucciones de cmo ejecutar este
script en MySQL. El listado 7 muestra un fragmento de la clase transformada a la que hemos
denominado RegistroJugadores DBJython.
Como las otras variedades de registros de jugadores que hemos implementado deriva de la
clase base RegistroJugadores. Si se desconoce la
manera de interactuar con JDBC se recomienda
al lector que repase los contenidos de los nmeros 105, 106 y 107 de Slo Programadores y/o
que visite la pgina http://java.sun.com/products/jdbc/. En pocas palabras, en el constructor
de esta clase se carga el driver JDBC para MySQL
(disponible en http://www.mysql.com/products/
connector/j/) en memoria, se obtiene una conexin a la base de datos tresenraya y luego se
utiliza esa conexin para ejecutar comandos

LISTADO 6

(Statements) SQL. Las figuras 6 y 7 corresponden a


pantallazos de la versin
Jython del juego Tres en
Raya en modo grfico.

IronPython: Python
para .NET

En Marzo del 2004 en la


conferencia PyCon fue pre- Figura 5. Sesin interactiva de tresenrayajython.py.
sentado IronPython (http://
ironpython.com/), una implementacin Python z Dinmico, soporta el modo de ejecucin
orientada a las plataformas .NET y Mono. Las
interactivo como Python.
caractersticas principales de IronPython son:
z Opcionalmente esttico, se pueden comz Tan rpida como la versin estndar de
pilar ficheros Python para producir ejecuPython.
tables (.EXE) que pueden ejecutarse direcz Integrada de modo transparente con la
tamente o incluso DLLs.
Common Language Runtime de .NET. Desde z Soporta cdigo gestionado (managed code).
IronPython podemos usar las libreras de z No finalizado, todava en versin alfa no
clases .NET y extender otras clases .NET.
puede ser utilizada para produccin de
software.
Clase JuegoTresEnRayaJythonGUI
En definitiva, IronPython parece una contribucin prometedora que nos permitir programar aplicaciones .NET desde la cmoda y
sencilla sintaxis de Python. Mantngase
JOptionPane
atento a los progresos en este proyecto.

import java
from java import awt
from javax import swing
from javax.swing import
...
class JuegoTresEnRayaJythonGUI(tresenrayajython.JuegoTresEnRaya):
def __init__(self):
registro = tresenrayajython.RegistroJugadoresPersistente()
tresenrayajython.JuegoTresEnRaya.__init__(self, registro, solop, solop)
self.frame = swing.JFrame(Juego Tres en Raya,
visible=1, windowClosing=self.exit)
gridSizer = awt.GridLayout(3,3)
self.frame.getContentPane().setLayout(gridSizer)
self.iconoMaquina = swing.ImageIcon(Images\\x.PNG)
self.iconoUsuario = swing.ImageIcon(Images\\o.PNG)
self.iconoVacio = swing.ImageIcon(Images\\blank.PNG)
self.buttons = []
for i in range(9):
button = swing.JButton(self.iconoVacio, actionPerformed=self.onClick)
button.setBackground(awt.Color.WHITE)
self.frame.contentPane.add(button)
self.buttons.append(button)
self.frame.pack()
...

def onClick(self, event):


indexButtonClicked = self.__get_index_button_clicked(event.getSource())
if self.buttons[indexButtonClicked].getIcon() == self.iconoVacio:
if not self.__jugar(indexButtonClicked):
self.resetGame()
self.__resetTablero()
...

El algoritmo MiniMax
No quera concluir esta serie sobre Python, en la
que el juego Tres en Raya nos ha ayudado a
entender tantos conceptos, sin proponer un algoritmo ms sofisticado referente a la eleccin de
casillas por la mquina. En definitiva, muchos de
vosotros os habris preguntado cmo hacer que
la mquina piense y elija la mejor casilla en cada
momento. Este razonamiento es posible a travs
del algoritmo de inteligencia artificial, MiniMax.

Figura 6. Jugando al Tres en Raya con la


versin Jython.

41

SOLO PROGRAMADORES n 121

Python 121.qxd

17/12/04

01:06

Pgina 42

MIDDLEWARE

LISTADO 7

Clase RegistroJugadoresDBJython.py

from java import lang


from java import sql
import tresenrayajython, string, sys
class RegistroJugadoresDBJython(tresenrayajython.RegistroJugadores):
def __init__(self):
tresenrayajython.RegistroJugadores.__init__(self)
try:
lang.Class.forName(org.gjt.mm.mysql.Driver)
except Exception, e:
print Se ha producido un error en la carga del driver, e
try:
url = jdbc:mysql://localhost:3306/tresenraya
self.con = sql.DriverManager.getConnection(url,tresenraya,tresenraya)
except Exception, e:
print Se ha producido un error en el establecimiento de la
conexion con la base de datos, e
# Asegurarse que si no existe un usuario solop se aada
usuarioSolop = self._executeSQLCommand(select * from usuario where
nombreUsuario=solop)
...
def _executeSQLCommand(self, command):
# si la consulta devuelve resultados lo har como una lista de tuplas,
# cada tupla es una fila de la tabla, y cada elemento de la tupla una columna
resultado = []
command = string.strip(command)
if len(command):
try:
stmt = self.con.createStatement()
if string.lower(command).startswith(select): # si es una select ...
rs = stmt.executeQuery(command)
metadata = rs.getMetaData()
# recupera todas las filas
while rs.next():
# recupera todas las columnas
contenidoFila = []
for i in range(1, metadata.getColumnCount()+1):
try:
columnType = metadata.getColumnType(i)
contenidoColumna = None
if columnType == sql.Types.INTEGER:
contenidoColumna = rs.getInt(i)
elif columnType == sql.Types.VARCHAR:
contenidoColumna = rs.getString(i)
else:
contenidoColumna = rs.getObject(i)
contenidoFila.append(contenidoColumna)
except Exception, e:
print e
break
resultado.append(tuple(contenidoFila))
else:
stmt.execute(command)
except:
raise uExcepcion producida en ejecucion de comando + command
return resultado

Antes de explicar el algoritmo es necesaria


una breve introduccin a rboles de bsqueda. Un rbol de bsqueda es una notacin
para representar bsquedas. La figura 8
representa uno de estos rboles. Los cuadrados son conocidos como nodos y representan puntos de decisin en la bsqueda. Los
nodos estn conectados por ramas. La bsqueda comienza en el nodo raz, en la parte
superior de la figura. En cada punto de decisin, los nodos para cada posible camino de
bsqueda son generados, hasta que ms

SOLO PROGRAMADORES n 121

42

decisiones no sean posibles. Los nodos al


final de la bsqueda son los nodos raz.
El algoritmo MiniMax considera la existencia
de dos jugadores, el MAX y el MIN. Un rbol
de bsqueda es generado, depth-first,
comenzando con la posicin actual del juego
hasta la posicin final del juego. Luego, la
posicin final es evaluada desde el punto de
vista de MAX. A continuacin, los nodos interiores del rbol son rellenados de abajo a arriba con los valores evaluados. Los nodos que
corresponden al jugador MAX reciben el

Figura 7. Versin Jython de la pantalla de


estadsticas.

mximo valor de sus hijos. Los nodos del


jugador MIN el mnimo de sus hijos. Los valores representan cmo de bueno es el movimiento. El jugador MAX tratar de elegir el
movimiento que maximice el valor al final.
Sin embargo, el jugador MIN, mientras tanto,
seleccionar los movimientos que son mejores para l, minimizando en todo lo posible el
resultado de MAX.
Para ms detalles sobre este algoritmo y otros
basados en IA recomendamos permanecer atentos a las novedades que incluir Slo
Programadores en los prximos meses. En el CDROM ofrecemos una implementacin de la aplicacin de Tres en Raya que hace uso de MiniMax.

Conclusiones
Aqu acabamos nuestro recorrido por el lenguaje de programacin Python. Confo que a
lo largo de estas cuatro entregas el lector haya
podido descubrir el potencial de este gran lenguaje de scripting que combina a la vez potencia y sencillez. La aplicacin de tres en raya
que hemos ido desarrollando tan solo ha mostrado cmo implementar en Python la funcionalidad correspondiente a las tareas programticas ms tpicas: programacin grfica, de
acceso a bases de datos, web y XML. Por falta
de tiempo no hemos podido descubrir otras
muchas reas en las que Python tambin
juega un papel destacado. Espero que, tras lo
descrito en esta serie, el poder de Python os
acompae en vuestras prximas tareas de
programacin.

Figura 8. Ejemplo de rbol de bsqueda.

Potrebbero piacerti anche