Wiki XML a HTML, no way

Python — Sábado 16 de Febrero de 2008, 11:40

El otro día comenté sobre la Wikipedia Offline, y en el sexto comentario apuntaron a unos parsers de terceros para pasar de XML a HTML.

Si uno pudiera tener un xml2html.py que armara el HTML a mostrar al usuario a partir del XML original, los volúmenes de datos a manejar en todas las etapas del proyecto serían bastante menores.

Me alegré bastante cuando encontré mwlib, una biblioteca hecha en Python para parsear los artículos XML y generar el HTML. El primer día de trabajo en PyCamp 2008 lo pasé tratando de usar esto.

El XML que publica Wikimedia, con sólo los artículos, templates y etcéteras en la última versión (y no todas las discusiones, ni todo el historial) pesa 1.7GB, con lo cual era imposible abrir el XML con herramientas de fácil uso como ElementTree. Pero Chipaca hizo un parseador en SAX (que va recorriendo el XML gradualmente, y no tiene que cargarlo entero en memoria), que yo luego modifiqué un poco y dejé en articleExtractor.py.

Ya pudiendo separar el artículo, me puse a jugar con la biblioteca mwlib en si, para convertirlo a HTML. Acá me encontré con algunas sorpresas, pero luego de hacer algunos análisis durante un par de horas, las pudimos descartar.

Una era que teníamos la dependencia de latex, para transformar texto en formato MathML en una imágen con la fórmula matemática en si. Vimos sin embargo que en el XML teníamos el MathML, y como Firefox es capaz en sí de parsear esto y mostrarlo como corresponde, decidimos que no era un problema.

El otro punto era la dependencia en PIL, la biblioteca de manejo de imágenes de Python. Como el tratamiento de las imágenes, qué incluir y cómo era todo un tema aparte, decidimos no preocuparnos acá hasta que llegue el momento.

Y finalmente, teníamos una dependencia de perl, para crear unas imágenes de linea de tiempo. Tuute estuvo buscando un montón y realmente apenas hay de estas imágenes en la wikipedia en español. Encima, la utilización de esta capacidad en la biblioteca está complicada, porque necesita usar unos directorios en particular, y cosas así. Entonces, decidimos "tocar" la biblioteca para que directamente no use esto.

Finalmente, entonces, éramos capaces de traducir el XML a HTML. El proceso es bien simple, si se fijan el código de xml2html.py es bastante simple. ¡Y genera un HTML bastante piola! Sin embargo, dá algunos errores y me puse a ver qué pasaba.

Una de los primeros detalles es que no encontraba algunas categorías. Y esto era porque en el XML, al ser en español, están los tags como "categoría", y no como "category". Luego de revisar durante un buen rato como cambiarle el locale al parser antes de laburar, encontré que esto estaba bastante chancho: están hardcodeados en los programas estos tags para inglés y alemán, pero nada más. Feo, sucio. Pero agregué algunos en castellano y seguí experimentando. El HTML ahora se parecía más al original.

Otro gran detalle es que no encontraba unos templates. Nuevamente con la ayuda de tuute, encontramos que los templates están en el .xml grandote que teníamos: el template otrosusos era un artículo allí llamado "Plantilla:Otrosusos" (nótese el cambio de minúscula a mayúscula).

Acá me di cuenta que para más o menos poder seguir generando la info, tendríamos que extraer estas Plantillas de forma previa, para poder alimentársela al parser. Como el parser y el resto están preparados para conectarse a una base de datos como la de wikipedia, había que: o generar una base de datos similar, o seguir tocando la biblioteca para que acepte las cosas de otra forma.

En el mismo proceso, actualicé el archivo xml, ya que antes de venir para acá había bajado la última versión pero por error seguía usando la versión anterior. Y aparecieron nuevas categorías, lo que implicaría seguir modificando la mwlib a mano, no sólo ahora, sino en el futuro, :(.

En función de todos estos drawbacks y dependencias, entendimos que no podríamos pasar de XML a HTML en el momento de servirlos, en la máquina del usuario final, sino que debíamos generar una especie de htmls reducidos y más simples, de manera de procesar y guardar HTMLS de forma similar a la idea original del proyecto, pero con volúmenes más simples.

Pero luego estuvimos viendo como iba creciendo el HTML que estábamos generando (todavía faltaba incorporarle los templates), y consideramos los tamaños relativos con respecto a los HTMLs estáticos que la misma Wikipedia genera (y que eran la fuente de datos originalmente).

Entonces, luego de analizarlo, con Alecu y Tuute decidimos que este camino no nos llevaba a ningún lado, y decidimos que no valía la pena seguir explorándolo.

Wikipedia para todos

Python — Lunes 04 de Febrero de 2008, 17:07

¿Cuál es la idea?

Wikipedia Offline, o CDPedia, es un proyecto de PyAr que arrancó hace un par de años.

El proyecto basicamente es armar un CD (originalmente, al menos, hoy en día podríamos armar también un DVD, por la cantidad actual de información) que contenga toda o gran parte de la wikipedia en español.

Al tener toda la info en el disco, no es necesario estar conectado a internet para hacer uso de la Wikipedia, lo que permitiría la utilización de este conocimiento en lugares donde la conexión es complicada, cara, o directamente inexistente. Apuntamos también a minimizar los recursos necesarios para hacer uso de esta herramienta, de manera que se pueda utilizar en computadoras más o menos básicas. En resumen, nuestro objetivo es que se pueda utilizar la wikipedia en las escuelas de todo el pais, aunque tengan computadoras viejas y no estén conectadas a internet.

Al CD se lo puede utilizar de dos maneras. Una es sin instalación alguna: con sólo tener un navegador web instalado en la máquina, uno pone el CD y comienza a usarlo directamente. La otra manera es realizando la instalación.

Este último método tiene el único costo de tener que tener espacio libre en el disco rígido, pero también algunas ventajas importantes:

- Velocidad: Todas las consultas se harán sobre el disco rígido y no sobre el CD, lo cual es más rápido. También es probable que al instalar expandamos algunas estructuras de datos, que en la consulta directa al CD tenga que hacerse en el momento.

- Accesibilidad: En el momento de la instalación (o más adelante, existe la opción), se puede crear un índice completo de la wikipedia. Esto permitiría realizar búsquedas en el cuerpo de los artículos y no sólo en los títulos.

- Reutilización: Una vez instalado el producto, se puede prestar o regalar el CD a otra persona, y que lo utilice como quiera.

Es importante recalcar que alentamos y recomendamos la distribución de los CDs armados, de manera que la información sea accesible por más gente. Otro detalle es que el producto debe correr en los tres principales entornos de usuario final: Linux, Windows y Mac.


Laburando

Mi idea es aprovechar el Campamento Python a realizarse en Córdoba del 15 al 18 de Febrero para trabajar en este proyecto. Recuerden traer el 7z instalado, para poder comprimir y descomprimir archivos en este formato, y  (que deberían encontrar acá, pero no sé por qué en este momento no están todos).

El mismo estuvo bastante tiempo abandonado, luego de unos esfuerzos iniciales, y apenas lo retomamos Alecu y el que suscribe el día del Taller de Software Libre, dónde retomamos un poco el hilo del desarrollo. El repositorio está acá y tienen más info del proyecto acá (aunque hay que revisarla y retrabajarla).

Cabe acotar que los esfuerzos iniciales se vieron truncados ante la imposibilidad de lograr un objetivo que era demasiado ambicioso, que versaba sobre los requerimientos mínimos de la máquina donde este producto debía correr. Es por eso que ahora no tenemos estos requerimientos, sino que la idea es hacerlo, y luego ver qué máquina se necesita (y optimizar lo que corresponda si no estamos satisfechos en ese aspecto).

El principal inconveniente que encontramos al retomar el proyecto es que cuando arrancamos con el mismo, el dump estático de la wikipedia (que es con lo que trabajamos como fuente de datos, un archivo que libera la Wikipedia y que para español se llama wikipedia-es-html.7z) pesaba 1559 MB y tenía adentro 171 mil archivos, y cuando lo revisamos con Alecu el otro día pesaba 8757 MB y tenía adentro 759 mil archivos. Por esto tuvimos que modificar algunas herramientas que trabajaban con ese archivo expandido, para que trabajen directamente con el comprimido.

El otro problema con el que nos enfrentamos es que ahora es imposible meter toda la info en un CD, y que o tenemos que usar un DVD, o tenemos que recortar la info de alguna manera. Tengan en cuenta que todo esos archivos son solamente los htmls, y no las imágenes...


Partes del proyecto

Para que varias personas puedan trabajar en el proyecto como equipos separados, rearmé la estructura del mismo en función de tareas separadas que no interacúan demasiado entre sí, sino que bastaría con definir con qué termina una etapa y qué tomaría la siguiente para trabajar.

La primera etapa toma el archivo crudo obtenido de la wikipedia, y deja la info resultante para trabajar. La segunda etapa toma esta información, genera los datos complementarios necesarios (cómo estructuras de índices, por ejemplo), y arma la info final consultable. La tercera etapa es la que permite consultar esta info, instalar el producto, etc, y deja como resultado final el .iso listo para quemar en los discos.

Paso a detallar, entonces, qué tenemos en cada etapa del proyecto, y qué faltaría, de manera de que todos podamos ir pensando con anterioridad al campamento qué hacer en cada etapa, y luego allí podamos discutirlo.


Primera etapa, o Preproceso

La fuente de info aquí es el archivo que ya deberíamos tener bajado en el disco, más las imágenes que bajaríamos luego, y un dato importante que viene de la segunda etapa del proyecto, y es el tamaño máximo que deberíamos ocupar en el disco.

Los pasos en esta etapa, a groso modo, son:

- Agarrar los htmls del archivo: deberíamos tener el archivo ya bajado de antes!
- Descartar aquellas páginas que no queremos: algunas páginas se descartan siempre (discusiones de usuarios, etc.), otras en función de un análisis más elaborado que está recortando nuestra información.
- Limpiar las páginas que sí queremos: cuando decidimos quedarnos con ese html, no queremos todo ese html.
- Bajar las imágenes en los tamaños deseados: al final, luego de ver el tamaño que ocupa el texto que decidimos guardar, bajamos las imágenes que correspondan.

Con respecto a descartar las páginas, cómo dije recién tenemos dos grupos:

- Descartar según tipo: En función del tipo de página y de cuanto ocupan todas aquellas de ese tipo, debemos decidir si guardarlas o no. Para esto, primero hay que realizar un análisis previo, decidir qué grupos conservar, y filtrar. En config.py tenemos el archivo de configuración de qué quedarnos y qué no. La estadística que figura en ese archivo sale de correr makeLista.py. Tenemos también el programa SearchAndDestroy.py que utiliza la info de config antedicha y limpia el archivo comprimido (tener en cuenta que este programa no fue actualizado, por lo que intenta descomprimir el archivo, lo que seguramente nos traerá problemas a nivel de espacio de disco; tenemos que adaptarlo para que vaya retirando del .7z sólo lo que corresponde).

- Descartar información: Como todo no entra en un CD (y posiblemente, dentro de un tiempo, tampoco en un DVD), tenemos que prever alguna forma de descartar información válida (o sea, páginas reales, que de alguna manera determinamos que son menos importantes que las que queremos guardar). El punto álgido aquí, obviamente, es cómo saber qué páginas son más importantes que otras. Hemos discutido varias alternativas, como sacar estadísticas sobre tráfico real (con el problema de que esta info es muy dificil de conseguir), o utilizar las votaciones de calidad de las páginas (con el problema de que hay muy pocas evaluadas de esta manera). La mejor solución encontrada hasta ahora es ponerle puntos a cada página en función de cuantas otras páginas apuntan a esta (algoritmo que hemos dado en llamar Peishranc, ver el programa peishranc.py); esto tiene la ventaja de que seguramente estamos evaluando popularidad (cuanta más puntas para llegar a una página, es más probable qué lleguemos a ella), de alguna manera calidad (es más probable que una página buena esté muy referenciada), y encima es el método que mejor asegura una buena navegación en la wikipedia offline (si eliminamos las páginas menos referenciadas, minimizamos la posibilidad de que alguien haga click a una página que no incluimos).

Luego de hacer toooodos estos análisis, hay que evaluar cual es el peso de las páginas que decidimos conservar, y evaluar qué imágenemos ponemos para terminar de llenar la capacidad que nos indicaron al principio. Podemos poner imágenes para todas las páginas, o sólo para aquellas con peishranc más alto, pero en cualquier caso las tenemos que bajar en el momento (el archivo completo pesa como 100 GB), y achicarlas en tamaño ya que es mejor poner muchas imágenes más chicas que pocas en tamaño original (atención: ver si no es posible bajarlas directamente del tamaño deseado). Ver el programa convertidor.py, que va jugando con un conjunto de imágenes hasta que todas ocupan un tamaño determinado.


Segunda etapa, o Armado

En esta segunda etapa debemos armar las estructuras complementarias de la información que nos dejaron. El índice de los títulos es la estructura más obvia a armar. Pero también debemos proveer un programa que genere un índice completo de la info de la wikipedia para el momento de la instalación.

Es responsabilidad de esta etapa generar también los programas o interfaces que permitan la utilización de estas estructuras adicionales, especificando de forma clara (bah, la API) para que la interfaz de usuario final permita acceder a la información necesaria.

Con respecto al full text index, hay un programa cdpindex.py que ya exploró algo de esto, pero no sé en qué estado está (preguntarle a Lucio).

Un número interesante que sacamos de esta segunda etapa es el overhead que le ponemos a la info cruda, a nivel estadístico. Por ejemplo, podríamos ocupar un 20% más.


Tercer etapa, o Aplicación

Esta es la etapa que tiene que manejar distintos sistemas por separado:

- Server web para servir las páginas, modificándolas para que apunten a el mismo servidor y no a la web (ver si esto es mejor hacerlo antes). Ver el server.py.

- Página principal: Es la primera que ve el usuario final al arrancar el sistema, y permitiría buscar en la wikipedia, ver algún artículo al azar, posiblemente ver algunos recomendados (en función del peishranc) o el historial del usuario, etc. También permitiría instalar el producto, si lo estamos usando desde CD o DVD.

- Instalador: Permite copiar toda la info al disco duro, armar los accesos directos correspondientes, generar estructuras de datos adicionales si el usuario decide hacerlo en ese momento, etc.

Tanto el servidor web como el instalador (¡especialmente el instalador!), tienen que ser multiplataforma.

El espacio que ocuparían estos sistemas debería ser bastante estático. Con este dato, y en función del overhead de la etapa 2, podríamos indicar un número bastante acertado para que la primera etapa se acote a si misma.


Conclusiones

Hay mucho laburo para hacer. Pero antes que nada, debemos decidir bastantes detalles.

El sistema no es sencillo. Implica procesar una alta cantidad de datos, bajar muchas imágenes de la red, armar estructuras de datos complejas, servir páginas web, e instaladores multiplataforma.

Pero es un desafío super interesante, y sé que Python Argentina está a la altura del mismo (aunque nos lleve tiempo, je).

¡Ahí vamos!

Python Bug Day, la experiencia

Python — Domingo 20 de Enero de 2008, 04:29

Como les había comentado, ayer tuvimos esta actividad en la que muchos desarrolladores y usuarios de Python nos juntábamos virtualmente en un canal de IRC y nos aprestábamos a aplastar cucarachas.

Bueno, no explicitamente aplastar cucarachas, pero sí matar bichos. ¿Eh? Bueno, trabajar con los bugs de Python, :)

Bug! 

Algunos desarrolladores, los días anteriores se habían tomado el trabajo de marcar algunos bugs como fáciles, de manera de tener puntos accesibles por dónde empezar. Esto les permitió a varias personas que nunca habían trabajado con el código fuente de Python hacerlo por primera vez sin que se sintieran frustrados por la complejidad del mismo, ni estén dos semanas para terminar una corrección.

Yo me levanté temprano, y más allá de una hora que corté para comer, le pegué derecho hasta las cinco. Mi idea era dedicar todas esas horas para buscar y cerrar algunos bugs propios míos, pero hice algo más productivo: ayudar a otros.

En el canal había un montón de gente, y algunos desarrolladores más experimentados en Python: Andrew Kuchling, Georg Brandl, Gregory Smith, Christian Heimes, y el que suscribe. Lo que principalmente hacíamos era dar indicaciones y soporte, pero como tenemos derecho de commit, también revisábamos algunos parches que preparaba la gente e incorporabamos ese trabajo al proyecto

Yo creo que la gente nueva aprendió bastante, ya que hubo mucho diálogo en el canal. Algunas preguntas se repitieron bastante durante el día:
  • ¿Qué hay que tocar para arreglar un bug? Arreglar el código, armar los casos de prueba, modificar si es necesario la documentación, y editar el archivo NEWS.
  • ¿Cual es la mejor manera de preparar un parche? Hacer un svn diff.
  • ¿Dónde se agrega la noticia del cambio en el archivo NEWS? Al principio.
  • ¿Cual es la versión para 2.6, y cual es 3.0? La 2.6 es el trunk, directamente; 3.0 es branches/py3k.
Y así varias más. Hay un buen FAQ para desarrolladores acá.

El resultado final fue muy exitoso: se cerraron 38 issues. Lo mejor, desde mi punto de vista, es que dos miembros de PyAr (John Lenton y Juanjo Conti) participaron y hasta enviaron parches que fueron commiteados, solucionando un problema cada uno, :).

Como experiencia, fue muy productiva tanto para el proyecto como para los desarrolladores. Y además, fue muy divertido, :D

Python bug day

Python — Martes 08 de Enero de 2008, 09:48

El próximo 19 de Enero, sábado, se realizará un Python Bug Day.

¿Qué es esto? Basicamente un ataque de lleno y frontal para cerrar bugs y patches de Python, todos de forma más o menos coordinada.

Dura todo el día, aunque es normal que la gente labure más o menos de 9 a 15 (hora local de cada uno).

Los participantes se encuentran en el canal #python-dev, en irc.freenode.net, y por allí se coordina quién agarra un bug, los cambios que se van haciendo, se piden opiniones, etc.  Normalmente se arranca de una lista de sugerencias, pero se puede trabajar sobre el bug o patch que deseen.

Más info, procedimientos, enlaces, aquí.

Va a estar divertido.

PHP no sabe sumar

Python — Lunes 17 de Diciembre de 2007, 09:45

Hace rato que quería hacer este post. Más que nada, como referencia, porque luego comento esto y no me acuerdo exactamente estas lineas, entonces me es más fácil apuntar a este post y listo.

Si ejecutamos el siguiente script en PHP, intentando sumar 3 y 058...
<?
$r = 3 + 058;
echo $r."n";
?>
..., el tipo muestra "8".

La realidad es que estamos haciendo algo mal, pero PHP te oculta el error, sigue como si nada, y el programa sigue trabajando con fruta.

"Ningún error debería pasar silenciosamente", dice el Zen de Python. Si ejecutamos esa suma en Python, encontramos que dá un error. A partir de ese error vemos que realmente tenemos un problema en lo que queríamos hacer.

Pero PHP no da error. Contesta el resultado de la suma. Un resultado equivocado. Ergo, PHP no sabe sumar.

Noticias Python por 4

Python — Jueves 06 de Diciembre de 2007, 07:25

Intro a Py grabada

Roberto Allende filmó mi charla de "Introducción a Python" en el CDC 2007, en Luján. Su post, aquí.

Lamentablemente justo esa no me gustó como la dí, ya que me complicaron el schedule.

Ya que estamos, felicito a Roberto por entrar a la Plone Foundation.


Haciendo que los chicos programen abierto

He hablado varias veces del Google Summer of Code (acá, acá y acá); una de las limitantes de este proyecto es que está apuntado a estudiantes universitarios, para que en sus vacaciones de verano trabajen en algún proyecto en particular.

Ahora Google se despacha con un nuevo programa: el Concurso de Participación Altamente Abierta (Highly Open Participation Contest). El mismo es un esfuerzo para atraer estudiantes pre-universitarios al desarrollo open source. Como se trata de menores, no habrán pagos puntuales por proyectos grandes, sino que ahora hay una lista de tareas: si los chicos completan esas tareas participan por premios y recompensas de Google.

Más info del concurso, acá. La Python Software Foundation está en este programa, con esta lista de tareas para Python.


Python en XKCD

XKCD es una especie de historieta geek que me encanta. Reproduzco aquí la edición de hoy:




Facundario

Desde un tiempo atrás me tomé la costumbre de tirar, cuando entro al canal de Python Argentina en IRC, alguna frase producto de mi desvariado cerebro.

A la gente le gustó, e incluso perrito666 se tomó el trabajo de hacer una recopilación automática de las mismas, la cual dió en llamar Facundario Enterprise Edition (versión extra apulentada).

Y bueno, che, es lo que hay, :)

Humos y arbolitos

Python — Martes 20 de Noviembre de 2007, 17:32

O árboles y humitos: Este post es el par de mi lado del post Python más rápido que Java que escribió Humitos hace algunos días.

Arranquemos desde el principio... una mañana en la que entra Humitos al canal IRC de Python Argentina (#pyar en irc.freenode.net), y plantea el problema de cual es la mejor estructura de datos para armar un autocompletador de palabras. Esto es, a partir de un diccionario de palabras, que estructura las guarda mejor para que cuando uno ponga joye, el sistema sugiera joyel, joyelero, joyero y joyer.

Yo pensé en un árbol con una letra por nodo. Al toque, le sugirieron que usase un árbol Trie. Yo, que como no soy informático no conozco muchos nombres, fui a revisar qué era un árbol Trie (acá hay una explicación piola, acá una más formal).

La cuestión es que un árbol Trie era lo que yo pensaba que era: un árbol con una letra por nodo. Por ejemplo, para las palabras que usé antes:



Perfecto. Humitos tenía la tortura de tener que hacer esto en Java para la facultad, así que luego de llorar un rato puso manos a la obra. Iba como "reportando" en el canal de PyAr, e hizo un par de preguntas. Yo, viendo que era dificil discutir el tema desde lo abstracto, me tomé un rato e hice una implementación en Python y se la pasé.

Salió bastante derechita. Basicamente hice una clase Nodo que mantenía la letra, los ramas hijas, y un flag para indicar que hasta ahí llegaba la palabra. Parecía andar, tanto que Humitos termino implementando casi lo mismo en Java.

Al otro día, sin embargo, Humitos me dió dos malas noticias. La primera, era que el sistema este consumía mucha memoria... para el diccionario de más de 80 mil palabras, ¡¡el árbol armado ocupaba 180 MB!!. Como efecto secundario, tardaba mucho en armar la estructura en memoria (como 7 segundos); lo bueno era que la búsqueda en sí era super rápida.

Por un lado lo mejoré usando __slots__ (para que cada objeto Nodo ocupe menos memoria, algo sólo relevante cuando uno tiene tantos y tantos objetos). Por otro lado, encontré y solucioné una ineficiencia importante: tenía un nodo casi al pedo en cada hoja del árbol. Con estas dos correcciones, el sistema pasó a ocupar 55 MB en memoria, y tardaba 4 o 5 segundos en levantar.

Hasta acá, todo bien.

Pero luego, Humitos se dió cuenta de que tanto su programa como el mío tenían algunos problemas en aquellas palabras que simultaneamente eran completas y parte de otras. Siguiendo con el ejemplo anterior, tenemos allí dos casos de estos: joyel es palabra completa, pero a su vez parte de joyelero; lo mismo con joyer y joyero (por otro lado, joye, por ejemplo, es sólo parte de otras palabras, no una palabra completa por si misma).

El problema era tan sutil que se mostraba en algunos casos y en otros no, dependiendo del órden de las letras (y esto era provocado por la forma en que armábamos la estructura palabra por palabra).

Estuve como tres horas en la oficina peleándome con esto, pero luego tuve que hacer otras cosas (trabajar, bah) y no lo pude solucionar. El código se iba complicando y complicando, y no le encontraba la vuelta.

Esa noche era el concert de uno de los jardines de Moni, así que tuve como media hora de auto hasta allá. En esa media hora el cerebro trabajó tranquilo, y me di cuenta de tres cosas....

Por un lado debía dejar de usar clases para el Nodo, una estructura de diccionarios debía de servir si encontraba la manera de marcar el fin de las palabras. Por otro lado, en lugar de ir armando la estructura palabra por palabra, seguramente sería más fácil a nivel de código el armarla teniendo todas las palabras y recorriéndolas por "columnas" de letras.

Esas eran optimizaciones, pero también se me ocurrió un cambio más fundamental. En los finales de las palabras, en muchos casos seguramente la estructura pierde forma de árbol frondoso y como que le quedan "ramas peladas". En estos casos, en lugar de almacenar secuencias de nodos, es mucho más eficiente guardar el resto de la palabra y listo.

Para verlo mejor, les redibujo el ejemplo anterior, pero bajo este concepto:



Como es una especie de Trie degenerado, excusándome bajo una incapacidad total a la hora de los nombres, y considerando que la versión anterior me tenía un poco frustrado, lo terminé llamando Fucked Trie.

Llegué al concert bastante antes que los padres, pasaron 40, o 45 minutos antes de que se ocupara el salón. Ese tiempo lo pasé codeando tirado en un rincón, e implementé el 95% de lo que sería la solución final. Le terminé de dar un par de retoques el lunes o el martes pasado, en Brasil, donde le corrí el profiler y optimizé un par de detalles.

El producto final tarda menos de un segundo en cargar, ocupa sólo 18 MB de memoria, y hace las busquedas en 60 micro segundos, centenares de veces más rápido que antes... ¡una preciosura! El código, junto con el diccionario de palabras, acá.

Agitado comienzo de fin de semana

Python — Lunes 05 de Noviembre de 2007, 04:08

El viernes a la noche arrancamos el fin de semana dando una charla en el ITBA: "Python más rápido que C", invitado por Macarse. Teoricamente la iba a dar con Lucio, pero tuvo un problema con el auto y no pudo llegar, así que dí la charla solo... el público algo frío, y yo dí la charla demasiado rápido (nunca la había "pensado" dar sólo), pero bien.

Luego de la charla, con Moni fuimos a comer algo a la costanera, cerca de casa, y nos fuimos a dormir temprano, porque el sábado iba a ser un largo, largo día.

El sábado nos levantamos 6:30, nos bañamos y preparamos todo para salir hacia Luján, donde se haría el Ciclo de Charlas Unlux 2007. Mariano y Marcos llegaron a tiempo a casa, pero Qwerty nunca apareció ni llamó. Lo esperamos hasta las ocho, y nos fuimos.

Llegamos bastante temprano, ya que la idea era armar el stand de PyAr. Nos encontramos en seguida con Paula, una de los organizadores, y luego con Ezequiel (no me crucé con Tomás hasta más tarde). Con Mariano colgamos la bandera (que luego Alecu cambió de lugar, con valederas razones), y presentamos los folletos que había hecho.

Estos folletos los había preparado durante la semana, con ayuda de Gustavo, bajo una idea originalmente discutida con Mariano, y la verdad que quedaron muy bien:



Me perdí la primer charla, sobre Asterisk, porque el que la daba no llegó a tiempo. Así que me quedé en el stand hasta que llegó la hora de mi charla. Pero la charla anterior, de Franco Iacomella, había tenido un problema con el proyector, y se atrasó un poco. Pero el tipo, en lugar de apurarse un poquito, y tratar de redondear la charla, se tomó todo el tiempo del mundo, como si no hubiera nadie esperándolo, y me entregó el Auditorio 25 minutos tarde.

Yo no podía tomarme toda mi hora, porque la gente tenía planeadas otras cosas que hacer luego del horario de finalización de mi charla, así que hice mi presentación apurado y enojado por la falta de respeto del tipo este.

Luego comimos en una parrillita justo afuera de la Universidad, un poco a las apuradas porque a las dos ya tanía otra charla que dar: "Python más rápido que C". Sí, la misma que había dado el día anterior, parece que está de moda, jejeje. Esperaba poder darla con Lucio, pero no llegó a que le arreglaran el auto temprano (no porque se demoraron en arreglarlo, él se levantó tarde y no llegó, :( ).



A diferencia de la del día anterior, esta salió muy bien: habían como 25 asistentes (más de lo que esperaba), y se mostraron interesados. Por mi parte el tener la experiencia del día anterior ayudó muchísimo a la dinámica de la charla, y me salió muy bien. Los últimos cinco minutos estuvieron complicados, porque justo se cortó la luz. La laptop seguía con la batería, pero sin proyector, tuve que improvisar un poquito.

Obviamente, yo no tuve ningún problema, pero los que sufrieron son los organizadores, ya que la energía eléctrica se había cortado en toda la Universidad. Pero le pusieron muchísima onda, reorganizaron las charlas a aulas con más luz ambiental, y lo supieron llevar adelante.

Mi última charla del día fue justamente "a laptop sin proyector"; la daba Efraim, y se llamaba "Procesamiento de imágenes con software libre". Mucho de lo que mostró ya lo conocía, pero aprendí muchas cosas nuevas, estuvo bien.

Luego estuve un rato vagando por la zona de registración, charlando con gente, haciendo sociales, bah. Por suerte más tarde volvió la energía eléctrica, y se pudo planificar mejor el cierre de la jornada. En función de lo que había pasado, los chicos decidieron hacer el cierre del evento, y luego poner dos charlas más que habían quedado sueltas.



De ahí partimos algunos a cenar todos juntos. Algunos bastantes, porque terminamos siendo como treinta en la pizzería. La pasamos muy bien, charlamos a morir, y dije unas palabras para homenajear a los coordinadores y todo, :). Pueden ver fotos de todo el día acá.

Con Moni, de ahí, partimos hacia Pilar, donde nos esperaba la fiesta de un casamiento (bueno, no nos esperaba, es una forma de decir...). La fiesta era del casamiento de Silvia y Gustavo (Silvia fue directora de Moni en un jardín, hace un año).

La fiesta estuvo muy linda, y aunque nosotros estábamos destruídos, nos terminamos yendo bastante tarde de allí. Luego a casa, y a dormir, que sólo teníamos el domingo para descansar, :)

Viernes y sábado, charlas

Python — Lunes 29 de Octubre de 2007, 04:59

El viernes Lucio y yo tenemos una cita en el ITBA para dar nuevamente nuestra charla "Python más rápido que C", invitados especialmente en el marco de charlas que se dan periódicamente en tal establecimiento.

El sábado, sin embargo, ¡hay conferencia todo el día! Nos convoca el Ciclo de Charlas Unlux 2007, "Conectando puntos", en la Universidad de Luján, auspiciado por Python Argentina, :)



Es un día completo de charlas de todo tipo, donde Python tiene varios espacios asignados (miren el cronograma), como nos tienen bien acostumbradas las últimas conferencias de Software Libre.

Allí daremos nuevamente la charla antedicha. Pero también daré nuevamente mi "Introducción a Python", con algunas pequeñas modificaciones resultantes de comentarios luego de la presentación en CaFeConf 07.

Pueden encontrar ambas charlas aquí. Tengan en cuenta que pueden browsear esos directorios con el navegador, pero también pueden hacer un checkout anónimo con Subversion (si no entendieron nada después de la última coma, descártenlo y usen el browser para entrar en esa dirección :) ).

Por otro lado, estoy preparando una sorpresita para Luján, veamos si puedo llegar :)

Decimal, binario y el asado

Python — Viernes 21 de Septiembre de 2007, 10:48

Resulta que era sábado a la noche, no tenía mucho que hacer porque Moni estaba en Bariloche, y hubo una pregunta interesante en la lista de PyAr. Y la respuesta me salió bastante bizarra, en general fue bastante comentada. Motivado por un comentario en la reunión del otro día, la busqué y la releí (por primera vez). Y como me causó gracia, la rescato acá. La pregunta era por qué al redondear 39.285714285714285, el usuario no veía un 39.29, sino algo raro:

> Sin redondear:
>
> >>> chargeandprop("EEARGPLRGKGDQKSAVSQKPRSRGILH")[1]
> 39.285714285714285
>
> Con round a 2 decimales:
>
> >>> round(chargeandprop("EEARGPLRGKGDQKSAVSQKPRSRGILH")[1],2)
> 39.289999999999999

El detalle acá es que te están mostrando un número binario en su forma decimal. ¿Por qué en forma decimal? Porque hace rato que tenemos 10 dedos en las manos, y contar en esa base nos es natural. ¿Por qué el número es binario? Parecerá arcaico a esta altura, pero seguimos teniendo procesadores que trabajan en forma binaria: a nivel de silicio la FPU (floating point unit) de tu micro guarda el nro en binario.

Hagamos una analogía, para que resulte más fácil de entender. Viene tu sobrinito de 12 años, y te dice "tío, tío, enseñame algo que no entiendo de matemática". Vos, envalentonado por demostrar tus conocimientos, y viendo que es la única manera de salvar el fin de semana luego de que Argentina haya perdido 3 a 0 en la Copa América, le contestás "Obvio, lo que quieras". Entonces tu sobrino te da un lapiz y un papel y te dice... "escribí 'un tercio'".

Vos sonreís, aunque una gota resbala sobre tu frente, temiendo lo peor, y le escribís, con suspenso, un "1/3". El nene, casi como un enviado del diablo (no reconocés tanta maldad en sus ojos), sonrie levemente, sabiendo que caiste en su trampa, y que a partír de ahí él seguira subiendo y vos en decadencia, y te dice "no, pero con coma".

Entonces, vos, con una cintura hábil, luego de tantos años de enfrentarte con la AFIP, le escribís un "0,3...". Y cuando casi empezás a explicarle el significado de los tres puntos, el te sacude un lapidario "no, pero hasta el final". Ahí vos sabés que perdiste, de que no hay una maldita manera de escribir infinitos 3, y menos en una sola hoja, y le contestás "no, nene, las gallinitas no hablan", y te vas a revisar como anda el asado.

Ok, el procesador hace algo parecido, pero en binario. Cuando vos en decimal le decís redondeame un "39.285" a dos decimales, el tipo intenta anotar un "39.29" en su lápiz y papel binario, pero no puede.  Aunque a nosotros, *ese* nro nos resulta fácil, a él no, porque a nivel binario no tiene suficientes dígitos para escribirlo.

Quizás porque esté programado así, o quizás porque no tiene un asado que atender, la FPU hace su mejor esfuerzo y guarda internamente el número más cercano al "39.29". Y eso es:

>>> 39.29
39.289999999999999


Acá entra Python, quien en el intérprete interactivo, te muestra "la realidad posta posta, patente patente" (en inglés esta frase es distinta). Escribir directamente el nro, es como llamar a la función repr(), quien es lo más fiel posible con el ordenamiento de los átomos en el Universo:

>>> repr(39.29)
'39.289999999999999'


Ahora, si vos querés ser engañado, podés decirle a Python que te muestre algo más humano. ¿Cómo le decís que te convierta un objeto a su representación en cadena de texto de una forma más "humana"? Con str():

>>> str(39.29)
'39.29'


Ahí, lo que hace Python, sabiendo en parte cómo funcionan las FPU de nuestra época, y en parte porque aunque vayas ahora a revisar el asado los chorizos están quemados y los chinchulines te apagaron el fuego, es "redondear" ese nro a los quinces dígitos decimales.

Notar que el statement "print" llama automáticamente a str() para convertir los objetos a mostrar:

>>> print 39.29
39.29

Python tickets

Python — Lunes 10 de Septiembre de 2007, 12:16

En Python decidimos hace tiempo irnos de SourceForge. El primer paso fue migrar el repositorio de código, desde ahí a nuestro server. Y hace algunos días, terminamos migrando el tracker.

O sea, sacamos toda la administración de bugs y parches y los pusimos en nuestro server, manejándolos con Roundup (adivinen con qué está hecha este administrador, ;).

Yo tenía una herramienta que iba a SourceForge y hacía un resumen de los tickets (había hablado de eso acá). Obviamente la tuve que cambiar, y acabo de terminar de hacerlo.

Como ahora los bugs y parches están en la misma lista (son, genéricamente, tickets), quedó genericamente un sólo resumen. Obviamente, dejé este link en la barra derecha...

Python 3000

Python — Viernes 31 de Agosto de 2007, 09:06

Acaba de salir, calentito calentito recién salido del horno, el primer alfa de Python 3.0.

Lo pueden buscar aquí.

Pensar que hace un par de años se hablaba de esto como algo en el futuro, no del todo probable. Ahora está ahí, al alcance de la mano.

Yo ya lo instalé, :D

Powered by LifeType