enlazando python con la realidad

Upload: aprender-libre

Post on 05-Apr-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/31/2019 Enlazando Python con la realidad

    1/4

    Enlazando Python con la realidad

    REUTILIZACINDE CODIGO

    Python, Perl, Php, Ruby todos adolecen del mismo problema, tarde o temprano tendremos que volver al

    mundo real y trabajar con una librera C. POR JOS MARA RUIZ

    Y a en los aos 70 la gente delmundo de la Ingeniera delSoftware comenz a imaginar unfuturo donde slo se avanzara. Nohabra que volver a escribir programaspara problemas ya resueltos. El famoso:No reinventes la rueda. Comenzaron ahablar de objetos y componentes.

    Desgraciadamente esta visin del futu-ro se pareca demasiado a esa otra en laque todos vamos en cohetes al trabajo ycomemos en una hamburguesera queorbita alrededor de la Tierra. La realidades ms extraa quin se imaginaba unordenador en cada casa y todos conecta-dos mundialmente?

    A da de hoy el cdigo ms reutiliza-do es que viene en forma de libreras,ya sea de funciones o de objetos. Pero lamayor parte de estas libreras, y espe-cialmente en el mundo de Linux, hansido programadas en C o C++. Estoslenguajes, debido a mltiples factores,han sido los ms populares para el des-arrollo de libreras y sistemas, y hoy porhoy siguen siendo insustituibles enmuchos mbitos. De C se destacaba suportabilidad (es muy sencillo encontrar

    o crear un compilador de C para unanueva arquitectura) mientras que deC++, su balance entre portabilidad ycapacidad para grandes diseos.

    En este artculo vamos a ver cmopodemos hacer uso de una pequealibrera C desde Python a travs de unejemplo grfico.

    Nuestra librera OpenGL en CLa librera que vamos a utilizar va a pro-veer una serie de funciones que nos per-miten manipular objetos 3D a travs deOpenGL. A que suena rimbombante? Enrealidad no es tan difcil. No entraremosen detalles respecto a OpenGL, peroaclararemos un poco qu es.

    OpenGL es un estndar mundial crea-do por SGI (Silicon Graphics Interactive)para el desarrollo de aplicaciones 3Dinteractivas. Esto traducido a la inform-tica domstica significa juegos!.Todos los juegos multiplataforma queutilicen 3D estn programados utilizan-do OpenGL (DirectX, la otra alternativa,slo funciona bajo plataformasMicrosoft, o sea en sistemas Intel conWindows).

    OpenGL tiene un diseo simple, losobjetos se componen de vrtices (untringulo tiene 3 vrtices) y estos vrti-ces definen reas que pueden tener unaserie de propiedades como puede sercolor o brillo. Una vez definidos los obje-tos pasamos a crear una serie de funcio-nes que sern llamadas cuando se pro-duzcan eventos. OpenGL utiliza un bucleinfinito que, bsicamente, se dedica arecoger un evento, por ejemplo, la pulsa-cin de una tecla por parte del usuario,para, a continuacin, llamar a la funcinque se dedica a gestionarlo. As de sim-ple.

    Evidentemente hacer un videojuego3D es una tarea muy complicada, pero labase es esa, hacer que las imgenes enpantalla reaccionen a eventos que se dis-paran en cualquier momento y que lareaccin sea en tiempo real, o sea, que elusuario no perciba demora en el tiempode reaccin. Todos hemos actualizadonuestra tarjeta grfica alguna vez paraque la sensacin, a ms frames porsegundo mejor, fuese ms realista.

    En el Listado 1 (descargable desde [5])podemos ver un programa OpenGL muy

    Python DESARROLLO

    57Nmero 09W W W. L I N U X - M A G A Z I N E . E S 57

  • 7/31/2019 Enlazando Python con la realidad

    2/4

    compli-cados que slo

    deben ser usados porexpertos, y la mayor parte

    del personal de Los lamos soncientficos con poca preparacin en pro-gramacin. As que tenemos potentsi-mas libreras C y Fortran desarrolladasen lenguajes que no son capaces de usarsus destinatarios.

    Qu hicieron los ingenieros de Loslamos para simplificar el uso de estaspotentes herramientas de clculo? Puesse dedicaban a crear libreras que permi-tiesen manejarlas desde lenguajes msexpresivos, como pueden ser Perl oPython. Este proceso, a la vez que labo-rioso, es altamente repetitivo, de manera

    que decidieron no volver a tener quepasar por l. Desarrollaron SWIG que, deforma casi automtica, genera todo elcdigo necesario para utilizar desde mul-titud de lenguajes de alto nivel (desdePython hasta OCaml pasando por Java oC#) libreras de C.

    Lo decasi automtico es esencial. Slotenemos que generar un fichero de inter-faz (acabado en extensin.i) y SWIGgenerar un fichero_wrap.c que compilaremos junto al original paracrear la librera. De esta manera obten-dremos una librera dinmica (esosficheros.so que podemos ver a miles en

    /usr/lib ), as como una librera en el len-guaje de destino. En nuestro caso eselenguaje ser Python.

    El programa OpenGL.En el Listado 1 vimos un programa deejemplo en OpenGL. Es bsicamente uncubo, que gira y responde a eventos.Tiene una serie de propiedades que nopodemos alterar, como la velocidad degiro o el color. En el Listado 3 (descarga-ble desde [5])veremos la librera equiva-lente necesaria para nuestros propsitos.Examinmosla.

    Para comenzar, al ser una librera nopuede tener funcin main , as que lahemos renombradoarranque() . Se hanincorporado nuevas funciones con elobjetivo de poder modificar algunas

    caractersticas del objeto (color, veloci-dad, ttulo de la ventana).OpenGL (ver [2] en recursos) se com-

    pone de las libreras GL, GLU y GLUT.Esta ltima es muy importante, pero des-graciadamente la librera GLUT estndartiene un defecto ( o problema, segncomo se mire). La funcin

    glutMainLoop() es el bucle infinito degestin de eventos. Se entra en ella perojams se sale. Cuando se dispara el even-to que provoca la salida del bucle, el pro-grama acaba. Cualquier cosa que ponga-mos detrs de la llamada a

    glutMainLoop() no se ejecutar jams.Eso no parece muy lgico no? y si

    quiero poder arrancar el gestor de even-tos, pararlo y volver a arrancar? Comono somos los nicos con este problema(casi todo el mundo piensa que es unproblema ;) unos valientes, en la mejortradicin del software libre, han creado

    FreeGLUT (ver [3] en Recursos para msinformacin). Bsicamente es igual aGLUT solo que, entre otras cosas, nos

    permite salir del bucle interno de glutMainLoop() pero sin que finalice elprograma.

    Y por qu queremos que ocurra esto?Pues porque necesitamos una librera,queremos que la funcin arranque()vuelva al programa principal (que sernuestro intrprete de Python) una vezque finalice su ejecucin, en lugar definalizar todo el programa.

    Este un un problema tpico que nospodemos encontrar al crear libreras paraPython usando libreras C. A veces loque queremos usar son las funciones deun programa ya existente (por ejemplo,imagina poder acceder a las funcionesque tiene Mozilla o Firefox para RSS oanlisis de HTML), as que los pasossern: elimina los puntos de salida delprograma (generalmente losexit() ) y eli-mina elmain .

    As ya tendremos nuestra librera, listapara ejecutar SWIG sobre ella.

    El archivo de interfaz paraSWIGSWIG (ver [4] en Recuros) necesita unarchivo que le diga qu funciones y defi-niciones de datos exportar a Python. Este

    simple, peroque ser la base para

    nuestra librera. Para compilarlo debere-mos ejecutarmake listado1 en el mismodirectorio en que est, copiando a esedirectorio el contenido del Listado 2(descargable desde [5])a un fichero lla-mado Makefile.

    Y qu hace nuestro programa? Puesnuestro programa base genera un cubo3D con texturas y lo gira sin parar hastaque pulsamos la tecla 2. Entonces lo

    detiene, comenzando a girar de nuevocuando pulsemos la tecla 1. Con los tresbotones del ratn podemos cambiar elngulo en el que gira el cubo.

    Si compilamos el programa tal cualobtendremos un ejecutable que podre-mos usar. La velocidad a la que gire elcubo depende de la potencia del equipode cada uno.

    Ahora necesitamos algo para pegarcdigo C con Python, y ese algo esSWIG.

    SWIGSWIG es una aplicacin desarrollada en1995 en el departamento de FsicaTerica del Los lamos NationalLaboratory (ver [1] en Recursos). Fue alldonde se desarroll la primera bombaatmica y desde entonces ha sido uncentro puntero en investigacin a nivelmundial. El objetivo era el de reducir lacomplejidad de muchas aplicacionescientficas donde es obligado el uso delenguajes de bajo nivel, como C oFortran. Desgraciadamente con estos len-guajes es muy complicado, por ejemplo,desarrollar GUI que a da de hoy sonimprescindibles. Tambin son lenguajes

    DESARROLLO Python

    58 Nmero 09 W W W. L I N U X - M A G A Z I N E . E S

  • 7/31/2019 Enlazando Python con la realidad

    3/4

    Python DESARROLLO

    59Nmero 09W W W. L I N U X - M A G A Z I N E . E S

    para aislarcdigo espec-fico paraSWIG respec-to de las libre-

    ras origina-les.Y bueno,

    casi hemosacabado, slonos quedadeclarar lostipos de datos

    y cabeceras necesarias. Podemos ver lasdefiniciones en el Listado 4 (descargableen [5]). Bsicamente son las cabecerasde las funciones que queremos usardesde Python con la palabra externdelante. Esta palabra le dice a SWIG queson funciones que existen en un ficheroexterno.

    Las palabras mgicasYa tenemos casi lista la pocin, ahoraslo tenemos que usar las palabras mgi-cas del Listado 5 (descargable en [5]).ste muestra un fichero Makefile que yausamos para compilar el Listado 1, ahoratenemos que ejecutar:

    > make

    Y se realizar la ejecucin de las rde-nes:

    swig -python listado3.igcc -c -fPIC listado3.c $(INCS)gcc -c -fPIC listado3_wrap.c U $(PYINCS) $(INCS)gcc -shared listado3.c U listado3_wrap.c -o _listado3.so U $(INCS) $(PYINCS) $(LIBS) U $(PYLIBS)

    El primer comando genera el ficherolis-tado3_wrap.c , as como listado3.py . Hayuna opcin,-python que podramos cam-biar por-perl o -java. Esta opcin contro-la el lenguaje que se utilizar para gene-rar la librera.

    Pero claro, estos ficheros noson ms que cdigo,

    hay que compilarlos. De eso se encarganlos tres siguientes comandos. El primerocompila nuestra librera, el segundo losficheros generados por SWIG y el tercerolo une todo para generar la librera din-

    mica.Esos$(INC) o PYLIBSson opciones decompilacin guardadas en variables decontrol en el Makefile, varan de sistemaen sistema, pero las que aparecen en elListado 5 son las ms genricas.

    Nueva libreraPor increble que parezca hemos acaba-do, ya tenemos nuestra librera. Si mira-mos en el directorio en el que hemosestado realizando todas las accionesveremos un fichero llamado_listado3.so .Es una librera dinmica que puede sercargada en cualquier momento. A quesperamos? Arranquemos nuestro intr-prete de Python:

    > pythonPython 2.4 (#2, Apr 3 2005, U 22:24:02)[GCC 3.4.2 [FreeBSD] 20040728] U on freebsd5Type "help", "copyright", U "credits" or "license" for more U

    information.>>> import listado3>>>

    Con la ordenimport acabamos de cargarla librera y la tenemos disponible parasu uso. Comencemos con la accin mssimple, arranquemos el programa con lasopciones por defecto:

    >>>listado3.arranque()

    Cuando pulsemos INTRO aparecer unaventana en la pantalla con un objeto quese mueve a gran velocidad. Es nuestrocubo, lo que ocurre es que se muevedemasiado rpido. Si pulsamos la tecla2, el cubo se detendr, para ponerlo denuevo en movimiento debemos pulsar1.

    fichero se parece mucho a los ficheros decabeceras (o headers , mirar en

    /usr/include para ver unos cuantos) deC. El fichero comienza con la sentencia:

    %module listado3

    Que declara el nombre del mdulo ydebe ser igual al nombre de nuestralibrera C. Este nombre ser exportado acada lenguaje de manera que se corres-ponda con la estructura de organizacinque en l exista. En el caso de Python elnombre del mdulo se correspondercon un paquete.

    El resultado final de la ejecucin deSWIG ser un fichero llamadolista-

    do3_wrap.c . Es un fichero en lenguaje C,que define una serie de funciones quenos permitirn acceder a la libreralista-do3.c definidas enlistado3.i .

    Algunas de las definiciones que pon-dremos en listado3.i devuelven datos detipos definidos en OpenGL, por lo quetendremos que decirle a SWIG que en elfichero listado3_wrap.c debe incorporarla cabecera:

    #include

    Esto se hace mediante la declaracin:

    %{#include %}

    Entre los smbolos%{ y %} podemosintroducir cualquier declaracin extra oincluso cdigo que no exista en el ficherolistado3.c . Digamos que es una manera

    Figura 1: El cubo inicial tal y comose ve en la ventana del programa.

    Figura 2: Con las teclas podemosmodificar su posicin y giro.

  • 7/31/2019 Enlazando Python con la realidad

    4/4

    DESARROLLO Python

    W W W. L I N U X - M A G A Z I N E . E S

    Si pulsamos, con el cubogirando, con los botonesdel ratn sobre la venta-na, veremos que cadabotn cambia la direc-

    cin de giro del cubo enun sentido distinto.Cuando nos aburramos delcubo, o estemos mareadossi nuestro ordenador es muyrpido, pulsaremosq y la ven-tana desaparecer. Volveremos aver el prompt>>> de Python. Esto yaes todo un logro, hemos ejecutado unafuncin C que interacta con OpenGLdesde Python!. Pero an as apenashemos hecho nada, tambin lo podra-mos haber hecho con un script BASH!

    Vamos a interactuar ms con la libre-ra. Si miramos el fichero de interfazlis-tado3.i que est en el Listado 4 veremoslas funciones que estn disponibles parasu uso desde Python. Cambiemos lavelocidad de giro de manera que poda-mos ver el cubo.

    >>> listado3.setTiempoEspera U (10000000)>>> listado3.arranque()

    Para no complicar el cdigo (deberahaber usado nanosleep de la librera Cestndar) se ha introducido un bucle queitera un nmero determinado de vecesen la funcin display() de listado3.c .Esta funcin es invocada por OpenGLpara dibujar en pantalla los objetos, si seintroduce un retraso en ella tardar msen realizar su trabajo. Eso se traduce enque podremos ver mejor el cubo girandosi hacemos que el retraso sea el adecua-do.

    En nuestro sistema, un valor de10.000.000 de iteraciones hace que elcubo se vea girar de manera suave.Evidentemente al ser un bucle, dependede la velocidad del sistema. No es lamanera ms elegante de introducir unretraso, pero s la ms simple y corta(nuestras pginas son limitadas).

    La variableespera en listado3.c es detipo INT. Eso significa que su valor mxi-mo ser un poco ms de 4.000.000.000qu ocurre si introduzco un retraso de5.000.000.000?

    >>> listado3.setTiempoEspera U (5000000000)Traceback (most recent call U

    last):File

    "", line1, in ?OverflowError: argumentnumber U 1: long int too large to U convert to int>>>

    Python se queja!, diciendo que la asig-nacin no se puede realizar. Un fallo deeste tipo en un programa C nos hubierallevado a un fallo irreversible que aborta-ra el programa. Pero en Python no, sim-

    plemente llegamos de nuevo al intrpre-te. Esta es una de las razones por las quees interesante utilizar Python sobre libre-ras C, eliminamos muchos errores fata-les porque Python verifica por nosotroslos tipos de datos y es capaz de recupe-rarse de los errores.

    Juguemos con los colores del cubo. Elcubo tiene 6 caras y lo normal sera darleun color a cada cara, pero en OpenGL sele dan colores a los vrtices. Como elcubo tiene 8 vrtices tenemos que asig-nar 8 colores. Qu color tendr el cuboen el centro de una de sus caras si cadavrtice tiene un color? Pues siguiendo lajerga de OpenGL tendr un color inter-polado, una mezcla de los 4 colores delos vrtices.

    Una de nuestras funciones nos permitedefinir el color de los vrtices(setColor() ), as que vamos a hacer quelas caras sean de color gris. A un vrticele damos color negro y al siguiente blan-co. En el Listado 5 podemos ver un pro-grama que asigna colores blanco y negroalternativamente a los vrtices. El resul-tado no es del todo gris, por qu?

    Porque depende de la manera en quefueron definidos los vrtices. Los vrti-

    ces 0 y 1no tienen

    porqu estar enel sentido correc-

    to. Se puede jugarcon el cdigo del

    Listado 5 para intentarconseguir otros colores.

    Conclusin

    No resulta tan complicado acceder amiles de libreras en C desde Python, enla propia documentacin de SWIG apare-ce como ejemplo generar una libreraPython de manera casi automtica parala famosa librera GD de dibujo 2D.Seguro que la prxima vez que veamos

    una nueva librera para Python nos pre-guntaremos si los autores han usadoSWIG, puede que incluso lo pudiramoshaber hecho nosotros ;) s

    Jos Mara Ruiz actualmente est realizando el Proyecto Fin de Carrera de Ingeniera Tcnica enInformtica de Sistemas mientras estudia Fsica. Lleva 8 aos usan- do y desarrollando software libre y, desde hace dos, se est especia- lizando en FreeBSD. Pedro

    Orantes est cursando 3 de Ingeniera Tcnica en Informtica de Sistemas y en sus ratos libres toca en un grupo de msica.

    E L A U T O R

    [1] Los lamos National Laboratory:http://www.lanl.gov

    [2] OpenGL:http://www.opengl.org [3] Proyecto FreeGLUT:http://freeglut.

    sourceforge.net

    [4] Proyecto SWIG:http://www.swig.org [5] Descarga de los listados de este art-

    culo: http://www.linux-magazine.es/ Magazine/Downloads/09

    RECURSOS

    Nmero 0960