miércoles, noviembre 26, 2008

Heritrix vs Nutch


Enlazando con el post anterior, ahí va este.
Como ya dije, me llevé una muy buena impresión de Heritrix. Esto unido a que no soy fun de Java, me hizo en un primer momento pensar que Heritrix era el mejor producto... Pero no es el caso...
Como ya he indicado en el post anterior, como almacena Heritrix los datos tiene su pega...
Es por ello que he procedido a buscar en la web comparaciones entre ambos...
En este post, adjunto lo que he encontrado.

De [1] (ojo, del 2005):
"The primary aim of Heritrix is to be an "archival crawler" --
obtaining complete, accurate, deep copies of websites. This
includes getting graphical and other non-textual content.
Resources are stored exactly as they were received -- no
truncation, encoding changes, header changes, etc.


Recrawls of the same URLs do not replace prior crawls in any
sort of running page database.


The focus has usually been dozens to hundreds of chosen
websites, but has begun to shift to tens of thousands or
hundreds of thousands of websites (entire national domains).


Crawls are launched, monitored, and adjusted via a (fairly
complex) web user interface, allowing flexible (and sometimes
downright idiosyncratic) definition of what URLs should be
visited and which should not.


My understanding is that with the Nutch crawler's alternate
aims, some of the things it does differently are:
- only retrieves and saves indexable content
- may truncate or format-shift content as needed
- saves content into a database format optimized for
later indexing; refetches replace older fetches
- run and controlled from a command-line
- emphasizes volume of collection under default conditions,
rather than exact satisfaction of custom parameters


I'm not up-to-date on the Nutch crawler, I could be missing
important features or distinctions.


It'd be nice to converge parts of the crawlers' architectures,
for example to share link-extraction or trap-detection
techniques."

Me preocupa sobre lo que dice que almacena y no nutch. Tengo que hacer pruebas de esto...

De [2] (del 2008):
"Here are a (few) dimensions that may help
with your investigation:

+ The Nutch crawler operates in a stepped, batch fashion. It runs
through a list of generated URLs fetching each individual URL until the
list is done. You then generate the next list to run after running
analysis of the most recent fetch. Heritrix just runs fetching until it
runs out of URLs that fit its defined scope.
+ The Nutch crawler is a MapReduce job. This means that distribution is
just a matter of adding nodes and tasks (Tasks are retried if they fail,
etc.). Heritrix distribution is the divvying up of the crawl-space
outlined above (but from what I've heard, on big crawls folks just don't
bother with the sort-and-insert step reasoning that eventually every
individual crawler will trip over its URLs if its let run long enough).
If a heritrix instance crashes, recovery is manual involving either the
rerunning of a pseudo-crawl 'journal' or revivification using the last
'checkpoint'.
+ Heritrix has more crawling features -- knobs and switches -- than the
crawler in Nutch and it is more 'dogged' about fetching content than
Nutch given its roots in an Archiving organization.

The latter feature you may not want and regards the former, its easy
enough adding whats missing given Nutch is pluggable, open source."

Como indican, la forma de distribuir el trabajo es totalmente diferente.
Voy a terminar el post, con dos graficos que muestran las arquitecturas de ambos crawlers:


Nutch



Heritrix





Notas:
  • Consultando el API de Heritrix, puedo comprobar que hay mas de un 'processor' de escritura. Aparte de el de por defecto, ARCWriterProcessor , tenemos: Kw3WriterProcessor, MirrorWriterProcessor, WARCWriterProcessor (este formato parece que no ha pasado de la etapa experimental).
  • Si realmente queremos acceder al crawler store desde python, quizás sea mejor opción Heritrix, aunque nos toque hacer un WriterProcessor a medida.
  • El siguiente link explica como funciona Heritrix. Tomado del Developer Manual.

martes, noviembre 25, 2008

Open Source Crawlers


Estoy echando un vistazo a ver que que hay disponible Open Source, para crawlear.
Este post es un miniapunte, de lo que seguramente sea un artículo mas largo...

El punto lógico de entrada para mirar... pues la wikipedia.
He intentado encontrar algo mas allá... pero realmente no he encontrado nada interesante.

Sin hacer un análisis muy exhaustivo, os puedo decir que los tres principales candidatos a considerar serían (*1):
Los dos últimos son java, mientras que el primero creo es C.
nuch, está bien, porque es un producto con bastante apoyo, una documentación posiblemente por encima del resto (por ser de apache).

La alternativa sería hacer nosotros el crawler, pero esto sería una solución sólo a llevar a cabo si no nos queda mas remedio, ya que no es un tema trivial.

nutch
En principio no lo iba a considerar, por no haber entendido correctamente su arquitectura.
Pensaba que no tenía un crawler-store independiente de los indices. Pero no es así.
Si que lo tiene, y al igual que heritrix, en formato comprimido. Son lo que llaman segmentos.
Realemente lo que se almacena son objetos java, serializados y comprimidos.

httrack
El primero ya lo había usado para crawlear sites pequeñitos, pero aquí estamos hablando de usarlo para hacer crawleos potentes, de la web.
Todavía no lo he probado en serio en esta faceta, ya que sólo lo había usado en windows, y como he indicado para hacer crawleos de sites.
Pero el core del crawler es una librería con lo cual siempre vamos a poder acceder a ella desde python (esto siempre lo tengo en el punto de mira ;).

De hecho ya hay un módulo python disponible, httrack-py, que permite implementar ciertos callbacks en python.
Pero si lo que queremos es integrar completamente la librería en python, me temo que no vamos a tener nada disponible... Eso si, siempre podemos hacer nuestros propios bindings; para ello disponemos del código fuente...

El producto la verdad, está bastante documentado.
Ya para acabar indicar que lo que nos interesa realmente, no es la estructura de mirroring que genera el comando (al estilo de wget, vamos...) sino los datos cacheados.
Estos datos estan en unos tar.gz, a los cuales tendremos que acceder a través de una librería ya que directamente casi seguro nos van a dar problemas en la descompresión...

Total... que para poderlo usar algún desarrollo vamos a tener que hacer...

heritrix
El que esté detras de este crawler archive.org, ya es una garantía de que el producto va a estar bien.
La documentación es un poco pobre, pero para lanzar una prueba básica te apañas.
Indicar que tuve problemas para lanzarlo en windows, pero en linux ninguno.
El interfaz para la configuración es web (el crawler corre un servidor web de configuración), y soporta la gestión de crawlers distribuidos.

A la hora de definir el 'job' de crawleo, tenemos muchas opciones a configurar. Es aquí donde la documentación es mas pobre. Seguramente tengamos que recurrir al API java y a la documentación para desarrolladores para ampliar el tema. La de usuario no lo cubre.

Como resultado del crawleo se guardan los documentos en unos archivos ARC, comprimidos. De todo el proceso se van generando datos. Que podemos consultar tando desde el GUI, como desde diferentes archivos.

Con la instalación, se incluye el comando arcreader, que nos permite acceder a los contenidos de los archivos arc.
En la web, se indica que hay readers/writers en python para los archivos ARC, dentro de la herramienta hedaern

Conclusión
No tengo nada claro que producto usar. Es una conclusión inconclusa...
En principio descartgaría httrack, ya que su función es mas limitada. Está mas bien diseñado para crawlear sites, en lugar de la web. Pero es un producto que fácilmente podemos integrar con python.

Con respecto a los otros dos... dificil cuestión. Heritrix, me ha parecido realmente potente.
Tanto por la forma de trabajar como por todos los datos que te ofrece.
En este aspecto me ha llamado mas la atención que nutch. También es posible nutch te muestra esa información, pero de momento no haya accedido a ella, ya que sólo lo he lanzado modo comando.
Quizás el mayor problema de heritrix, es que está orientado a conseguir una imagen de la web en un momento dado. Si recrawleamos, un mismo documento, no va a sustituir a la versión anterior.
Estaría duplicado (*2).

Heritrix tiene una ventaja con respecto a nutch, y es que el formato del crawler-store es tal que podriamos acceder desde cualquier lenguaje. Por el contrario al crawler-store de nutch sólo podemos acceder desde java, ya que lo que se almacenan son objetos java serializados y comprimidos.
Con ambos productos, podemos extraer documentos vía comando.

(*1) Son los que me han parecido mas usables
(*2) al menos con el comportamiento por defecto; y creo que sin defecto, ya que los archivos ARC llevan implicito un timestamp. Para poder decidir si un documento está en un crawler-store o no habría que recorrelos enteros...


jueves, noviembre 06, 2008

Manejando HTML entities

Estoy haciendo un pequeño proyecto personal en python, para lo cual estoy parseando html con BeatifulSoup. Me he decantado por él por los siguientes motivos:
  • Probarlo mas a fondo
  • No quiero tener dependencias que no sean python (descartado entonces lxml/libxml2)
  • No necesito la solución más rápida
Sobre BeatifulSoup ya postearé alguna cosilla...
Pero este post va sobre el manejo de entidades de html. Al tratar el texto con BeatifulSoup, no me las transformaba a texto unicode. Por lo que me puse a indagar...
Por lo que he podido ver en el rato que he estado buscando parece que no hay nada en las librerías estándares para pasar entre entidades html y cadenas. Se me hace raro...

Enseguida encuentras que en el módulo htmlentitydefs, que tiene las definiones que necesitas pero no tiene ninguna función que realice el trabajo... Se me hace raro...

Buscando un poco mas encontré un thread, donde proporcionan como hacerlo (vamos..., que no vamos a reinventar la rueda...): Convert from unicode chars to HTML entities [encode][decode].

Pero BeatifulSoup, ya se encarga de ello, si pasas en el constructor el parámetro adecuado.

soup = BeautifulSoup(data,convertEntities=BeautifulStoneSoup.HTML_ENTITIES )


Mas info aquí.

miércoles, noviembre 05, 2008

Corriendo Linux en el portatil

Necesito tener disponible un linux... Y las alternativas que tengo son:
  • que me den algun usuario en alguna máquina
  • utilizar algun hosting (que ya tengo)
  • instalarme linux (descartado, ya que no puedo permitirme enredar a ese nivel con el portatil; ya me cargué el XP en un par de ocasiones....)
  • usar cygwin
  • usar vmware
Y la opción ganadora es... vmware. Además tenemos dos versiones que son forfree: vmware player y wmware server.
De momento para lo que yo quiero me bastaría con el wmware player (ya que no necesito más de un SO virtual; si necesitame mas de uno tendría que usar wmware server, o pillar un workstation piratilla; porque no voy a pagar por ello...).

sábado, noviembre 01, 2008

Pasando pagina...


Ayer, viernes 31 fue mi último día de trabajo en el 'proyecto' (averigua) que me ha tenido ocupado unos 3 añitos... Se dice pronto...

Puedo decir, que personalmente ha sido el mas gratificante, a pesar del tiempo que he estado en él. Seguramente podría haber estado otros 3 añitos. ¡Ojo! con esto no quiero decir que no haya habido crisis... que ha habido unas cuantas (en una apuntito estuve de largarme...). Pero ya se sabe... lo malo se olvida y perdura lo bueno. Y lo bueno es que me lo he pasado bien, he tenido unos compañeros geniales y hemos aprendido mucho.

Hasta ahora le mejor experiencia había sido cuando con 2 compañeros desarrollé NQOS en Dycsa.
En parte se repite la historia, aunque de distinta manera. No he logrado ver a ambos sistemas en producción. Con NQOS porque fuimos a parar a otra compañía, como la mayor parte de la empresa (despachados a Indra).

En el caso de averigua, se repite un poco la historia. Un equipo pequeño, y lo dejo antes de que realmente esté en producción. Si es que alguna vez lo llegara a estar...
Y el problema no es del proyecto, que es lo que da mas pena, sino de factores externos, interés en él real, la existencia de enemigos en la casa... en fin... muchas cosas que al final nada tienen que ver con la calidad del producto.
El 'adolestente' que es ahora, no ha tenido una infancia fácil. Nació en la familia de un buscador, y estaba destinado a tener un futuro en esa familia.
Pero la vida da muchas vueltas y antes de llegar a la 'adolescencia' se tuvo que buscar la vida por su cuenta, o perderla... como pasó con el buscador.
Fruto de esas vueltas es que en este momento, no este en un estado mas saludable; pero es lo que tiene la calle... hay que buscarse la vida... y sobrevivir siempre pendiente del enemigo no es fácil... (ni que decir tiene que es mucho mejor criarte arropado en una familia que te quiere y te guía).

No se que será de su futuro, pero no pinta bien. De momento se queda al 'trantran', con un equipo mínimo para subsistir, hasta que decidan darle cerrojazo por completo, o para que se den cuenta de que 'averigua mola'. O mejor... sean capaces de darle uso; en fin...

La verdad... que mal funcionan las empresas españolas. Son de lo peor! No llegan a apostar al 100% con ideas novedosas, no apuestan por la gente, racanean siempre con eso, y luego se gastan la pasta en chorradas, o maquinas que luego no usan; guerras internas, envidias, directores que no valen para lo que hacen,... en fin.. un asco.

Una pena para los que abandonamos el barco ahora, sobre todo para su ideólogo y yo; ya que somos de los que quedabamos, los que sentamos la base de lo que es ahora la criatura (en cuanto arquitectura, que en cuanto a lingüistica hay mucha chicha, y esa no era mi guerra).

Pero por otro lado, se abren nuevo horizontes. ¿Cual será el próximo reto? No espero mucho de la consultora en la que trabajo. ¿Intentará meterme ahora en cualquier gena, con tal de dejar de ser un coste para ella... ?
Si pasas por aqui de vez en cuando, y lees estas lineas y sabes de algo que me pudiera intersar, pues dedirte que estoy en modo 'escuchar ofertas interesantes' ;).

Building Scalable Web Sites

Building Scalable Web Sites, de Cal Henderson, es el libro que me tengo ahora entre manos.
Me quedé con la copla de él, leyendo el blog de kirai, y una dia de estos me dio el pronto y lo pillé en amazon.

Por lo visto los capitulos estrella, son el 8 y sobre todo el 9. Podeis leer críticas sobre él en el link de amazon, o también en slashdot.

El libro está bien escrito y cubre muchos temas de desarrollo web. El código escrito está principalmente en php (pongamos un 95%), pero no importa si no usas php, ya que lo importante no esta en el código...

Aquí podeis acceder a prácticamente todo el contenido del libro.

Desde mi punto de vista (y sin haberlo leido todavía entero) es de lectura recomendable. Pero mejor echar un vistazo a las críticas de amazon y slashdot...

Y unos links para acabar...

viernes, octubre 24, 2008

Descriptors y Decorators

Hay un post de Ian Bicling sobre como usarlos en combinación.
En dicho post hay unas referencias a un HowTo sobre Descriptors (interesante leer los comentarios) y a un nuevo tutorial sobre Decorators de Bruce Eckel.

Antes de comentar al respecto postear dos referencias mas sobre Bruce: una en la que habla sobre la que será su próxima publicación, Python 3 Patterns and Idioms; y otra que la que habla porque no habrá un Thinking in Python (es interesante además porque da unas referencias a otros libros).

Bueno volviendo al tema del post...
Realmente puedes leer sobre los descriptors, pero realmente para pillarlos hay que trastear con ello y leerlo con muchaaaa calma (y lo ideal sería probando los ejemplos). Pero bueno.... El tutorial sirve para pillar la idea.

El de los descriptors por el contrario si que es sencillo. Y son muy muy potentes.
Una de las cosas que eché de menos cuando empecé con python es el poder tracear las entradas y salidas de funciones o métodos. Esto típicamente se hace en C/C++ con macros.
Pues bien... con descriptors es posible hacerlo.

El pero es que con los descriptors en principio pareceque que tienes que modificar el código fuente. Pero no!!! Aunque es la forma evidende de usar los descriptors no es la única, ya que todo el mecanismo es dinámico. De hecho... esto se podría hacer sin los descriptors, ya que todo en python es dinámico...
Que quedo con la copla para experimentar con ello en un futuro...

miércoles, octubre 22, 2008

Usando webkit desde python

Antes de nada comentar que no lo he probado, pero me gustaría...
Se puede usar webkit desde python a bravés de pywebkitgtk.

Relacionadas, parte de pywebkitgtk, veo que también existen Pyjamas and python-qt4-webkit.

Intentando investigar un poquito sobre este tema... que he encontrado este post de comp.lang.pyhon (enfocado principalmente a ejecutar javascript, pero relacionado):

"pyv8 is the newest addition: http://advogato.org/article/985.html

it's a python wrapper around google's v8 javascript execution
library.

then there's pykhtml: http://paul.giannaros.org/pykhtml/

it's a python wrapper around KHTML, providing very convenient access
to KDE's HTML capabilities: what pykhtml does is "pretends" that the
GUI part of KDE doesn't exist, so you can run your program as a
command-line shell; it will execute the javascript, which you will
have to wait a bit for of course; then you can walk the DOM tree
(using pykhtml bindings) using pykhtml.DOM.getElementById() and
getElementsByTagName("a") etc. etc. looking for the URLs.

there's even an AJAX example included which does 1-second polling of
the DOM model, waiting for a spell-checking web site to deliver the
answer.

then there's webkit, with the new glib bindings:
https://bugs.webkit.org/show_bug.cgi?id=16401

which are then followed up by python bindings to _those_ bindings:
http://code.google.com/p/pywebkitgtk/issues/detail?id=13

this will also allow you to execute arbitrary javascript - again, it's
similar to KHTML and in fact webkit really _is_ the KDE KHTML code
(JavaScriptCore, KJS etc) but forked, improved, etc. etc.

unfortunately, the glib bindings are tied - at three key and strategic
locations - to gtk at the moment, which will take _very_ little work
to "un"tie them [pay me and i'll do the work], so you would need to
create a blank gtk window - just like is done with pykhtml, behind the
scenes.

it would be a very simple task to create a "dummy" - console-based -
port of webkit, providing an array of callbacks which you must hand to
the library. at the moment, the design of webkit is not particularly
good in this respect: there are three ports, gtk, wx and qt, which are
heavily tied in to webkit. it would be a _far_ better design to be
passing in a struct containing function callbacks (rather a lot of
them - about eighty!) and then what you could do is have a "console"-
based port of webkit, which would do the job you needed.

alternatively, if you don't mind wrapping a binary application with
e.g. Popen3 then look at the webkit DumpRenderTree application, paying
particular attention to using the --html option. you won't have any
control over how long the javascript is executed for. after an
arbitrary and small period of time, DumpRenderTree _stops_ executing
the javascript and prints out the HTML DOM model (in a non-html-layout
fashion - it's used for debugging and testing purposes but will
suffice for your purposes).

so, as it stands, pywebkitgtk is _no worse_ than pykhtml, but with a
little bit of tweaking, the "gtk" could be removed from "pywebkitgtk"
and you'd end up with... ohh... call it "pywebkitglib" ... which would
be much better as a stand-alone library, for your purposes

then there's also "spidermonkey", which is mozilla's javascript
engine. i haven't investigated this option: haven't had a need to.

then there's also PyXPCOMExt, which is embedding python into mozilla,
and from there you have PyDOM, which allows you access to the DOM
model of the mozilla "thing". so, if you don't mind embedding your
application into XULRunner, you've got a home for executing your app
and obtaining the urls, post-javascript-execution.

the neat thing about PyXPCOMExt is that you have complete and full
access to python - so your app can make external TCP and UDP sockets,
you can embed an entire _server_ in the damn thing if you want (you
could embed... python-twisted if you wanted!) you can access the
filesystem - anything. absolutely anything. reason: the _entire_
python suite is embedded into the browser. every single bit of it.

that's about all i've been able to find, so far. there might be more
options out there. not that there aren't enough already :)

all of them will allow you complete and full access to execution of
javascript, including AJAX execution. which is why you'll need to do
that "polling" trick in many instances. "

lunes, octubre 20, 2008

Pasar de pdf a texto/html

Para extraer el texto del pdf, se de dos aplicaciones que funcionan bien:
Por lo visto en una etapa del pipeline de fast (de las que vienen disponibles), se usa xpf (no lo puedo asegurar al 100%).
Nosotros en cierta ocasión usabamos el segundo (¿o fue pdf2html?). Porque nos daba mejores resultados.

Si quieres hilar mas fino, y no depender de una aplicación externa existe Poppler.
Parece que ha habido un amago de hacer bindings a python para poppler...
Uno de los peor de poppler es que no hay documentación.

Dentro del paquete poppler-utils, hay utilidades de conversión.
He visto que existe el paquete pyPdf.

viernes, octubre 17, 2008

Primer curso python impartido


Bueno... ayer se acabó el primer curso python.

No se como habrá resultado, ya que es dificil verse desde fuera (estaría genial poderse ver grabado, para corregir posibles defectos). Pero creo que en general ha estado bien.
Aparte de mi exposición, el material desde luego si que creo que está bastante bien.
Tras la experiencia del curso, quizás podría retocar alguna cosa (muy poca), o por mi parte mirar con mas detalle alguna referencia. Pero la verdad... para un curso de 12 horas, poco mas puedo ampliar. El tiempo está muy bien ajustado ya.

Lo malo, pero esto ya es típico de los cursos dentro de una empresa, quizas un poco de falta de interés por algun alumno (bueno es la percepción desde el lado del profesor). Pero vamos.... esto es algo de esperar. Pero con que haya ya sólo uno con interés es suficiente. Aún así, la gente con menos interés ha podido ver de que va esto de python...

El peor día fue el primero, en el que empecé con un poco de tensión, pero una vez superada el resto bien.
El último día me lleve un chasco. Hice una demo sobre como con joins() la concatenación de cadenas es mas eficaz que usando el operador '+'. Y no fue así. Los tiempos salieron similares.... [1]

A la presentación que tenía preparada le añadí contenido de la presentación de Gustavo Picón, para hacerla mas amena. Sobre todo para el comienzo.

El hacer un curso en python, es realmente muy sencillo, por la interactividad que te permite el interprete.
A la hora de escoger ejercicios para realizar por el alumno, hay dos opciones: hacer muchos ejercicios sencillos, o hacer menos pero mas complejos (no por la dicitultad del problema, sino por que consitas en hacer aplicaciones que realmente hagan algo).
Me decidí por la segunda opción.
En cuanto a la teoría indicar, que la aproximación al contenido ha sido la de pensar, según mi experiencia que debería tener. Y a partir de ahí elaborarlo, tirando de distintas fuentes y metiendo muchas referencias externas.
Lo mas sencillo hubiera sido fusilar algo ya existente, pero no me interesaba esta aproximación (mucho mas cómoda para mi). Ahora cualquiera con interés puede ver libros, u otras presentaciones y el contenido será diferente.

Al final el curso está dividido en 4 partes correspondientes a 4 dias (3 horas por dia):
  • Teoría, jugar un poco con python
  • Ejercicio 1 y explicación
  • Teoría, comienzo de Ejercicio 2
  • Explicación ejercicio 2, y practica libre
Durante la realización de los ejercicios, he mostrado mas cosillas...

Ya para acabar, indicar que en la web hay muchas presentaciones (incluso videos). Ahí va un listado de presentaciones de guido.
Y el enlace a la presentación del curso: El mundo de python.

Notas:
[1] Efectivamente, hay novedades que no sabia sobre esto. Por lo visto desde CPython 2.4 según What's New in Python 2.4: "String concatenations in statements of the form s = s + "abc" and s += "abc" are now performed more efficiently in certain circumstances. This optimization won't be present in other Python implementations such as Jython, so you shouldn't rely on it; using the join() method of strings is still recommended when you want to efficiently glue a large number of strings together."

jueves, octubre 16, 2008

NTLM Authorization Proxy Server

Relacionado con el firefox, ya comenté hace tiempo de una extensión interesante. MM3-ProxySwitch. Es interesante si necesitamos cambiar frecuentemente de proxies.

Otra utilidad muy util es un script en python que te permite autentificarte ante un proxy NTLM.
Si tenemos el MS Proxy Server y no estamos en el dominio, con firefox será un infierno navegar, ya que nos pedirá que nos autentifiquemos con cada petición. Este script, NTLM Authorization Proxy Server, lo soluciona.
Su autor Dmitry Rozmanov.

He indagado en Pypi, pero no está. Eso si, me he encontrado otro proxy disponible.

domingo, septiembre 28, 2008

Singleton

Necesitaba encontrar un ejemplo sobre uso de metaclases en python, y me decanté por el patrón Singleton, ya que había visto algo.
Resumiendo... la mejor solución actual es usando metaclases y es:

class Singleton(type):
def __init__(cls, name, bases, dct):
cls.__instance = None
super(Singleton,cls).__init__(cls, name, bases, dct)

def __call__(cls, *args, **kw):
if cls.__instance is None:
cls.__instance = super(Singleton,cls).__call__(cls, *args,**kw)
return cls.__instance


No se si tiene algun problema, ya que no estoy nada puesto en metaclases. Para acabar unas referencias comentadas:
  • wiki-es: donde ví la implementación de metaclases. Pero el cçodigo aquçi incluido varia en que usa super.
  • wiki-en: no tiene la opción de metaclass
  • Gary Robinson, implementa un singleton siguiendo unas ideas de aquí. No he tenido tiempo de mirarlo. Pero lo dejo anotado, ya que puede merecer la pena echarle un ojo.

viernes, septiembre 26, 2008

Google Moderator

Leo en genbeta sobre una aplicación sobre Google App Engine, Google Moderator.
Veo que están metiendo preguntas para Guido sobre python.

Python popularity

Me he encontrado con este blog, donde incluyen unos gráficos sobre la evolución de los lenguajes para el desarrollo de proyectos open-source. La fuente es un sitio llamado ohloh.

Python va evolucionando muy favorablemente. Otro gráfico de mi interés.

viernes, septiembre 12, 2008

Webkit vs Gecko

Hay un post en barrapunto sobre una comparativa entre WebKit y Gecko.
Me ha congratulado leer algún comentario sobre Gecko que cuadra totalmente con lo que yo ví una vez que intenté evaluar si nos podia servir para un proyecto:
  • no había documentación por ningún lado
  • la organización del codigo es un cristo, no está nada modularizado, aparte que la cantidad de codigo de la base es... brutal!!!
Vamos... que te descargas el código de Mozilla y no sabes ni por donde entrarle...
El artículo (el de dosideas) está muy bien, y es corto.

sábado, septiembre 06, 2008

Google Chrome

La novedad de la semana... ¿Y será la última de septiembre? Seguro que no... ya que es el decimo aniversario de google.
Hay un post relacionado de dirson que también está muy bien, va sobre una encuesta sobre los productos de google.
Hay muchas cosas por leer entorno a Chrome, pero todavía no he tenido mucho tiempo...
Por de pronto comentar que el comic, está relamente bien. Redomendable su lectura.

Ya un detalle super geek. Tras instalarmelo me aparece un artículo de Ian Bicking, como en los marcadores y como los mas visitados...
Es curioso... porque en el usuario que uso habitualmente no lo tengo ni en favoritos. Tendré que revisar el usuario admin...

sábado, agosto 30, 2008

Directorio de programación

En python.es surgió la idea de crear un directorio de blogs sobre python.
No había compartido nunca el enlace enl a lista, pero bueno... la verdad es que ya tengo unos cuantos contenidos en python que pueden ser interesantes.
El link irá a parar a directorioprogramacion.blogspot.com.

Habrá que echarle un ojo a ver como crece su contenido.. .

jueves, agosto 28, 2008

lxml

Ya he mentado en algun post anterior este parser de xml/html, pero no había tenido ocasión de probarlo.
En el proyecto ahora tenemos que manejar unos xml y hasta la fecha habíamos usado libxml2... Era el momento de cambiar... y la verdad es que está muy bien. Y bien documentado.

Ahí van unos enlaces:
  • la web. Que incluye un enlace a el manual (pdf). En formato html se acompaña con el código fuente. En la propia web hay más documentación en formato html, incluyendo el api.
  • Otro tutorial.
  • Y por supuesto tiene lista de correo [archivo].

jueves, agosto 21, 2008

Shutdown programado en windows

Hoy he aprendido un comando superutil:

shutdown -s -t [tiempo]

Te sirve para programar un shutdown en windows. Es muy util, imaginaros que habeis dejado descargandose algo y os quereis ir a la cama...
Con /? podeis ver el resto de opciones.

HTTrack

Hacía mucho que no usaba un Web Spider (o crawler). Y aprovechando que para el proyecto estamos usado HTTrack, lo he probado para un uso personal.

La verdad... esta muy bien. El único pero que le hemos visto es que no puedes obtener un mapeo entre las direcciones web, y las locales.

Se puede usar tanto para Linux, como para Windows.
Y ya lo que me ha sorprendido es que hay disponible una librería python, para usarlo desde python: httrack-py.

En linux, recordar que podemos usar para para los mismo wget.
En la wikipedia, podeis encontrar muchos mas crawlers.

martes, agosto 19, 2008

ConfigParser

Modulo muy útil para manejar ficheros de configuración en formato clave/valor y con secciones.
Vamos... al estilo de los .ini de windows.

Dentro del módulo se definen 3 clases:
  • RawConfigParser
  • ConfigParser
  • SaveConfigParser
RawConfigParser establece el interfaz básico. Una cosa en la que no había reparado es que al constructor se le puede pasar un diccionario con valores por defecto.

Yo hasta la fecha había usado ConfigParser, pero se te puede quedar corta...
El comportamiento de los métodos get() es que si una clave no existe te da una Excepción.
Nosotros hemos ampliado el interfaz con una variante de los métodos para que si una clave no existe, te devuelva el valor que le pasas por defecto. Vamos... similar que lo que puedes hacer desde el constructor, pero a nivel de método.
Lo que si que soporta son 'interpolaciones'. Es decir, el poder usar valores de variables como valores de otras variables dentro del mismo fichero de configuración.

Otra ampliación que le hemos metido es el poder hacer sustituciones en los valores a partir de variables del entorno. Para esto usamos el formato ${varname}. La verdad... Se podría haber hecho con las interpolaciones, usando el argumento opcional 'vars'.

SafeConfigParser simplemente modifica el método ser() para garantizar que el valor pasado sea un string.

jueves, agosto 14, 2008

Chuletilla para subversion

Estaba ya usando desde hacía tiempo subversion, pero la verdad... tampoco había leido demasiado sobre el mismo...
He ido tirando con mis conocimientos (básicos) sobre CVS. Pero notaba mis carestías, por lo que me dispuse a leer los capítulos 1,2 y 3 del siguiente libro. Se lo recomiendo a cualquier que esté trabajando con subversión; o que vaya a trabajar... Se lee rápido.

A continuación una chuletilla de cosas extraidas del susodicho..

Una vez hecho el checkout, el ciclo de trabajo típico es como sigue:
  • Update your working copy
    • svn update
  • Make changes
    • svn add
    • svn delete
    • svn copy
    • svn move
  • Examine your changes (estos comandos se pueden usar sin conectividad con el repositorio)
    • svn status
    • svn diff
      • Se puede usar un programa externo
    • svn revert
  • Merge others' changes
    • svn merge
    • svn resolved
      • elimina los ficheros temporales, cuando hay un conflicto
  • Commit your changes
    • svn commit
Otros comandos útiles son lo que te permiten examinar los ficheros (Examining history)
    • svn log
    • svn diff
    • svn cat
    • svn list
Y finalmente otros comandos:
    • svn import
    • svn cleanup
Notas:
  • Revisiones
    • Subversion lets you refer to these revisions by number, keyword, or date.
      • Con el date, si queremos sacar lo mas cercano a una fecha (incluyendola) hay que mete el día posterior
    • Las revisiones no van asociadas a archivo. Es decir si haces un checkout o un update de una revisión, te va a sacar todo lo que haya en esa rama con esa revisión (lo que hay en el HEAD, es decir lo mas actual con respecto a la revisión solicitada).
  • Se pueden hacer copias con 'history'
  • Los archivos pueden tener propiedades asociadas. Al ejecutar el comando se puede pedir que se ignoren.
  • Y por supuesto hay muchos comandos mas... Todo bien cubierto en el documento enlazado...
Y ya para acabar del todo, unos ejemplos de uso del comando status (muy útil y que no estaba acostumbrado a usar):

  • svn status --verbose --> saca info de todo, aunque no haya cambiado
  • svn status --show-updates --verbose --> este ya contacta repositorio
  • svn status -u -v --> la versión corta
  • svn status -vu | grep "*" --> nos indica que no tenemos actualizado con respecto el repositorio

viernes, agosto 08, 2008

Web Frameworks

En la lista de python últimamente han salido varios hilos sobre desarrollo web en python.
Especialmente interesante este: [1][2]
Aunque hay alguno mas: [3][4]

Los links son del archivo web.

lunes, julio 07, 2008

Revisitando urls

Python tiene la función urlparse que permite obtener los diferentes componentes de una url.
Ejemplo:

(scheme,netLoc,path,parameters,query,fragment) = urlparse( url )

Vamos a ver que contiene cada parte....:

  • scheme: Pues el esquema... ta claro.
  • netLoc: La localización de red... (ojo! incluye el puerto)
  • path: El path
  • query: La query (lo que va después de ?)
  • fragment: Esto es lo que va tras '#', al final de la url.


Si en la parte de la query ya tratamos los parametros, entonces ¿para que sirve parameters? Pues por lo visto son parámetros que pueden llevar cada 'segmento' del path. Eso si, no lo he visto en la vida.

Referencias:

¿Para Alma?

Suena muy fuerte el rumor de que Alma Technologies va a comprar a mi empresa....
Supongo que pronto sabremos algo.
Como cosa interesante el comentar que en Alma tienen un grupo dedicado a temas de tecnologías de búsquedas. Tienen un producto: SearchBox.

miércoles, junio 25, 2008

Desde luego navegapolis me está gustando mucho. Espero sigan en la misma linea...
Su último post: Directivos sin talento.

martes, junio 24, 2008

Futuro de python vs perl

De comp.lang.python: Python 3000 vs Perl 6.

Avances en C++

Aunque hace siglos que no toco C++, hay que estar al tanto..
Veo en el blog de Herb Sutter una entrada sobre unos cambios interesantes: Type Inference vs. Static/Dynamic Typing.

Un cambio en el lenguaje muy prometedor.
Gracias a ese post he llegado a una librería que desconocía: POCO.

Y ya para acabar aquí unos links a unas charlas (que no he visto, pero me gustaría) sobre el futuro de C++.

jueves, junio 19, 2008

Outsourcing

En Ingenieros de Primera tienen un artículo majetón sobre el Outsourcing : Aplicación del Outsourcing en las "Tecnologías de la Información".
Mucho mejor que los de la wikipedia [es][en].

Lo que no definen son algunos de los terminos usados: CIO (este no tengo claro a que se refiere exactamente), ROI, CTO.

martes, junio 10, 2008

refs refs refs

Hacia tiempo que Ian Bicking no publicaba nada. Acaba de publicar un post sobre Erlang.
Lo interesante ya no es el post en si, sino la cantidad de referencia que suelta en él, a saber:
  • Monkey path: "is a way to extend or modify the runtime code of dynamic languages (e.g. Smalltalk, Javascript, Ruby, Perl, and Python) without altering the original source code."
  • Bencode: "is the encoding used by the peer-to-peer file sharing system BitTorrent for storing and transmitting loosely structured data."
  • JSON: "(JavaScript Object Notation) is a lightweight data-interchange format." En dicha página hay muchas referencias sobre JSON y Python.
  • WebOb: "WebOb provides objects for HTTP requests and responses"
Y como no vamos a desvelar todas las cosillas interesantes... pues mas enlaces en el post...

CSV en python

Python tiene un modulo para manejar CSVs: csv [PEP].
Buscando un poco seguro que podeis encontrar otras implementaciones. Está bien que la librería incorpore este manejo de archivos ya que es bastante común.

Una cosa interesante que tiene, son los dialectos. Veamoslo con un ejemplo:


>>> import csv
>>> csv.list_dialects()
['excel-tab', 'excel']

Como podeis ver, el módulo incorpora dos dialectos para escribir/leer csv's del agrado de excel. Y es que hay que decir que no hay un estandar sobre CSV.

El hecho de estar mirando esto es porque estoy implementando un reader y andaba pensando si reutilizar este... En principio estoy por la labor... Si hay algo implementado mejor reutilizarlo ¿no?.
Lo que si que necesito de todas todas es un recubrimiento...
En principio hay dos cosas que me llaman la atención:
  • Si al consctructor del DictReader se le pasan los campos, si el fichero tiene cabecera, la lee como una línea normal ¡Ojo!. Si no se pasan los campos toma la primera linea como claves para el diccionario.
  • El constructor es muy flexible en su uso, a la hora de pasarle los parámetros.
  • El modulo tiene una clase para intentar deducir el formato de un csv: Sniffer.
Veamos un ejemplo:


#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

import csv
import sys


class midialecto(csv.Dialect):
delimiter = 'þ'
quotechar = '"'
lineterminator = '\r\n'
doublequote = True
skipinitialspace = True
quoting = csv.QUOTE_MINIMAL

csv.register_dialect("midialecto", midialecto)


campos = ['campo1','campo2']
f = open("ejemplo.csv","r")

# A descomentar la que mas nos guste
#
#dr = csv.DictReader(f,campos,None,None,'midialecto')
#dr = csv.DictReader(f,dialect='midialecto',fieldnames=campos)
#dr = csv.DictReader(f,dialect='midialecto')


for row in dr:
print row.keys()
print row.values()
sys.exit()


En el anterior ejemplo (descomentar una de las lineas que crean el 'dr') se imprime la primera línea que se lee del fichero, y se aborta.
Con los 3 constructores podemos ver la flexibilidad en la construcción, y como se comporta ante la presencia del argumento 'fieldnames' (si no se pasa => la primera linea se usa para formar las claves del diccionario).
Los parámetros que definen el formateo, pueden pasarse incluso en un diccionario.
Me han comentado en una entrada, y he creido conveniente crear la etiqueta 'lingüística'.
Para que haya contenido sobre el tema ahí van dos links de la wikipedia :p:

jueves, junio 05, 2008

Garbage Collector revisited

He mejorada el programita de marras del post anterior. Ahí va la nueva versión:


#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
import gc
#gc.set_debug(gc.DEBUG_LEAK) # Será necesario ponerlo para rastrear los leaks
# a no ser que invoquemos explicitamente a collect()

#------------------------------------------------------------------------------
class MiList(list):
def __del__(self):
# El método del nos sirve, aparte de para sacar una traza
# para que el objeto sea uncollectable. Sin el __del__
# el recolector es capaz de recolectarlo correctamente.
print "En el __del__"

#------------------------------------------------------------------------------


# Collectable
print "-----> Collectable"
l = MiList()
del l
print "collect:", gc.collect()
print "garbage:", gc.garbage

#------------------------------------------------------------------------------

# Prueba de que con una lista normal no hay problema
# Pero que curioso que el metodo collect() devuelve 1
print "-----> Con una lista"
l2 = []
l2.append(l2)
del l2
print "collect:", gc.collect()
print "garbage:", gc.garbage

#------------------------------------------------------------------------------


# Uncollecable
# He metido dos instancias, para ver como collect() devuelve 2
# Y aparecen ambos en 'garbage'

print "-----> Uncollectable"
l = MiList()
l.append(l)
#l.pop() -> Con solo meter esto se resuelve el ciclo!!!
del l


l3 = MiList()
l3.append(l3)
del l3

#------------------------------------------------------------------------------

# ¿como ver dichos objetos que con Uncollectable?
print "collect:", gc.collect()
print "garbage:", gc.garbage # uncollectable objects ¡¡¡no muestra nada!!!
# A no ser que activemos por ejemplo el flact DEBUG_LEAK
# O hayamos invocado explicitamente a collect() ¡Ojo!



Por cierto... la faq de python tiene pinta de estar muy bien. Me lo anoto como lectura futura.

Un ejemplo:

4.15 Why isn't all memory freed when Python exits?

Objects referenced from the global namespaces of Python modules are not always deallocated when Python exits. This may happen if there are circular references. There are also certain bits of memory that are allocated by the C library that are impossible to free (e.g. a tool like Purify will complain about these). Python is, however, aggressive about cleaning up memory on exit and does try to destroy every single object.

If you want to force Python to delete certain things on deallocation use the sys.exitfunc() hook to run a function that will force those deletions.

Ejemplo de uncollectable object

Quería mostrar a una compi de curro, como funcionaba el tema del recolector de basuras, con lo cual me hice el siguiente programilla:


#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
import gc
#gc.set_debug(gc.DEBUG_LEAK)

class MiList(list):
def __del__(self):
print "En el __del__"

# Collectable
print "-----> Collectable"
l = MiList()
del l
print "garbage:", gc.garbage

# Uncollecable
print "-----> Uncollectable"
l = MiList()
l.append(l)
#l.pop() -> Con solo meter esto se resuelve el ciclo!!!
del l

# ¿como ver dichos objetos que son Uncollectable?
print "garbage:", gc.garbage # uncollectable objects ¡¡¡no muestra nada!!!
# A no ser que activemos por ejemplo el flact DEBUG_LEAK


Si en el segundo bloque no hacemos el pop() vemos que si ponemos el flag DEBUG_LEAK, nos aparecerá el objeto 'uncollectable' en el atributo 'garbage'.
Por defecto no aparece.
Si se nos da una situación como esta, hay que resolverla a mano.

Lo de hacer el ejemplo con una clase que herede de List, en lugar de hacerlo con listas, es para mostrar cuando se invoca el método __del__.

El método __del__ se invocará antes de que se destruya el objeto, pero ¡ojo! si lo invocamos explicitamente no significa que se vaya a destruir y dicha memoria se vaya a liberar.

Otro apunto sobre la liberación de la memoria en python. La memoria se devolverá al gestor de memoria de python, que no significa que se libere al SO.

miércoles, mayo 28, 2008

Organizaciones sobre gestión de proyectos

Leyendo sobre Scrum veo que hay 3 organizaciones en el campo de la gestión de proyectos:
  • PMI (Project Management Institute) [wiki]: dan la certificación PMP.
  • IPMA (The International Project Management Association)
  • PRINCE2 [wiki]. En primer lugar existía la metodología prince2, y despues se creó la organización.
Hay organizaciones para tó, hoygan. Y como no las tres certifican.

martes, mayo 27, 2008

Scrum

Pos ahora resulta que en mi proyecto vamos a usar la metodología Scrum [en].
Aquí os podeis descargar un libro sobre scrum. La web [navegapolis] parece interesante.... le tendré que echar un ojo...

miércoles, mayo 14, 2008

[Python-es] Preguntas de iniciado

Hay un hilo actual en python-es bastante interesante. Tengo que releerlo con calma, pero debido a un comentario de hoy, me veo en la necesidad de enlazarlo y copiar el comentario. Me ha paracido interesante.

"La preocupación por los supuestos peligros producto de la flexibilidad
de los lenguajes dinámicos es un mito sostenido las empresas de
software que pretenden convertir el arte de la programación en una
industria de producción en masa.

Pero tal y como señala Paul Graham
(http://www.paulgraham.com/knuth.html), programar es un arte. Y cuando
los programadores entienden esto, en contra de las ansias de
beneficios rápidos y sistemáticos de los accionistas de las empresas,
logran disfrutar su trabajo y hacerlo más rápido y con mayor calidad.

El problema es que los programadores artistas no tienen influencia en
los pensum de estudio de las universidades como si lo tienen las
grandes empresas como Sun y Microsoft, haciendo creer a la gente que
cuestiones ridículas como los getters y setter de Java son buenas
prácticas.

Es llamativo como profesores universitarios que no han desarrollado un
sistema completo enseñan como si fuese una religión los mecanismos de
encapsulación de un modo que entorpece terriblemente la productividad
de los programadores.

Python es un excelente lenguaje programación orientada a objetos, como
también lo es Ruby, y representan un verdadero salto evolutivo en
comparación con despropósitos como C++ y Java. Lo único que oculta esa
verdad es el enorme poder econñomico manifestado a travñes de
estrategia de lobby que siga permeando tanto al academia como a las
empresas."

La web enlazada paulgraham.com merece echarle una visita.

martes, mayo 06, 2008

Paper a leer

Estoy leyendo un 'paper' que todo Arquitecto Software debería leer: Architectural Styles and the Design of Network-based Software Architectures.

Se trata de la tesis doctoral de Roy Fielding.

miércoles, abril 23, 2008

Joomla

Hoy creo lo escuché por primera vez: Joomla [wiki] [otra][articulo].
Por lo visto es un CMS open source que están usando en yell.
En la wikipedia tienen un directorio de CMS open source, y una lista de CMS.

Desarrollados python tenemos:

jueves, abril 17, 2008

Java World


Que mundillo este de los Javeros... Tan lleno de siglas. Mundo en el que yo mas o menos me he mantenido al margen.

Tengo que reconocer que no me apasiona el lenguaje, ya que cuando surgió yo era muy de C++ y eso marca... Jeje.
Sin embargo el que ahora me apasiona es Python. Curioso... ¿Porque? Porque Python está mucho mas alejado de C++ que Java. Java es como que se queda a medio camino...
Mira si dejas ya un lenguaje como C++, lo dejas con todas las consecuencias. Eso si, está bien que apareciese Java y que exista. Tiene un nicho claro.

Hace tiempo estuve trasteando un poco con Java y CORBA, y realmente respecto a manejar CORBA con C++ es una gozada. Pero tras conocer python y volver a tocarlo, tengo mas fundamentos para ver que realmente se queda a medio camino. Hay que teclear mucho...

Un lenguaje como Python también tiene sus desventajas, pero para desarrolladores digamos 'avezados', que hagan buen uso de él, es una gozada.

Bueno... tras esta introducción a continuar con el típico post mio de recopilar enlaces que traten de un tema determinado...
Post que claramente tiene su origen en el curso que estoy haciendo... que me está sirviendo y mucho para refrescar estos temas.
Bueno al lio...

El curso que estoy haciendo es una introducción a J2EE. Bueno y ni siquiera eso, ya que que se quedan fuera los EJBs, u Enterprise Java Beans (que no confundir con los Java Beans). O los WebServices (esto ya si que es un cristo...), por mencionar un par de cosas. Vamos... que vemos solo parte realmente web, la que se ejecutarça en el servidor web.



Los EJBs son objetos distribuidos, mientras los Java Beans son objetos java reutilizables que deben implementar un determinado interfaz.

¿Entonces que es lo que vemos en el curso? Pues básicamente Servlets (que sería el equivalente a los Applets en un navegador, pero en el servidor) y JSPs . Bueno también las TagsLibs, y lo que de tiempo al final. Parece poco, pero es muy practico y ya se sabe... la practica lleva tiempo...

Sobre los JSPs... Los JSPs es una tecnología que te facilita la generación de Servlets (lo que se genera, dinámicamente, es un Servlet). Te facilita la integración de codigo Java (o no Java) con otro contenido (típicamente html). Vamos... es como si fuera una especie de template.

Como herramientas usamos.... adivina, adivinanza... Tomcat, Apache, y Eclipse.
Si usasemos EJBs ya no serviría Tomcat, ya que Tomcat sólo un contenedor de Servlets. Necesitaríamos un servidor de apliaciones, y seguramente habríamos usado JBoss, que es posiblemente el mas extendido.

Aunque los Servlets y las JSPs es la base del desarrollo web en Java, la tendencia es a usarlos poco directamente. La gente suele usar frameworks, siendo el mas oido struts (que es una implementación del patrón MVC).

Los frameworsks también tienen sus peros; siendo el principal el que mientras las cosas van bien, todos contentos, pero cuando van mal... a ver quien es el guapo que pilla que es lo que va mal.
Pero claro... como estos javeros lo que no quieren es tirar lineas de código... ;).

Contra esta tendencia a la complejidad y embarullar todo un poco han surgido cosillas como los POJO. También como reacción a lenguajes que vienen pisando fuerte: python y ruby.

Ya sobre como se da el curso en si...
Pues está bastante bien. Teoría la justa, la necesaria; y a practicar, que es como realmente se aprende.
Me preguntaba el cheriff si lo que estabamos viendo era la Pet Store... ¡Pues no! Estamos integrando una aplicacioncilla superchorra que se ha currado el profe. Y cuando digo integrando es realmente eso: nos dedicamos a montar la 'cola' entre el diseño web y la capa de negocio. Ambas cosas ya las tenemos hechas.

En Java BluePrints [wiki], aparte de la Pet Store, hay otra aplicación demo, la Java Adventure Builder Reference application; pero que no es tan popular. Los downloads.
Ummmmm, habrá que hacer una Python Pet Store ;)...

Y con esto y un bizcocho hasta mañana a las ocho (nunca mejor dicho).

miércoles, abril 16, 2008

Mas sobre PHP

Continuando un post anterior. Y tras este empape en tecnología web, no podia faltar leer algo mas sobre PHP.

No ya sobre como es el lenguaje, sino sobre su posición frente otras alternativas. Resumiendo:
  • PHP: es el lider en muchos sitios populares. Se podría decir que es el lider a desbancar. El que debería escoger alguien que quiera montare algo web, sin experiencia en desarrollo.
  • Java: gracias a la gran labor comercial que se ha hecho con él tiene un nicho enorme. Tiene ventajas sobre PHP, a cambio de complejidad. Este le gustaría mas a un Ingeniero Software, por el lenguaje y framework en si. Si ya estudiamos otros temas... puede que no. Los desarrollos son lentos y complejos. Un Ingeniero con PHP debería hacer las cosas tan correctamente como con Java, sólo necesitaría metodoloría.
  • RoR: Nueva alternativa. Le gusta a los Javeros.
  • Python: ¿tiene futuro? Si lo tiene será por el lenguaje en sí.
El nicho que debería ocupar python sería el que tiene Java ahora mismo, pero metiendose incluso en el nicho de PHP. ¿Será esto posible? Dificil lo tiene.
Por lo que he podido leer PHP está muy fuertemente afianzado. Bueno a los links... Vía barrapunto he leido unos artículos interesantes:

Parseando html

Hace tiempo estuvimos decidiendo que parser usar, para procesar el html en mi proyecto actual. En su momento fue una labor nada sencilla. Había dos requisitos básicos: tenía que ser rápido y se tenía que tragar html defectuoso. El ganador fue libxml2.

Hoy me he encontrado un blog muy interesante, el de Ian Bicking. En su blog tiene un artículo reciente sobre el parseo de html. En dicho artículo llega a la conclusión de que el mejor parser es lxml.

Llega a la misma conclusión que llegué yo, pero bajo unos requerimientos diferentes.

Sería interesante probar cuanto tiempo ganamos usando libxml2 y nuestras propias estructuras de datos frente a usar directamente lxml.

martes, abril 15, 2008

Documentando código

En el blog ya puse alguna mas entrada sobre documentación de código, al menos para python.
He visto en la wikipedia que tienen una comparativa de generadores de documentación.

BDs libres

El otro día comentaba sobre BDs para almacenar pares de datos.
Para completar ese post ahí va uno para reseñar algunas de las BDs que disponemos for free:
La diferencia entre SQLite y las otras dos, es que las otras con sistemas cliente-servidor y SQLite es una libreria.
Con todo lo reseñados ya tenemos un abanico lo suficientemente amplio para escoger la solución que mas nos convenga... ¿no?

viernes, abril 11, 2008

Web framewoks



Este post viene por mi inquietud al respecto por varios motivos:
  • Me gustaría hacer algo en la web
  • Voy a dar un curso sobre J2EE. Realmente no me interesa NADA todo lo que tenga que ver con Java, pero si lo considero educativo. Tengo que aprovechar que dadas las circunstacias del proyecto ahora puedo... Ademas en mi proyecto actual si tenemos un servicio web montado con tecnología J2EE.
  • Ayer JJ tras comentarle sobre lo de google, me volvió a hablar de RoR.


Si nunca has desarrollado para web (como yo) y tienes la libertad absoluta para hacerla, ¿con que lenguaje y framework hacerlo? La verdad... ambas cosas están relacionadas.
Empezando con el lenguaje, ¿que usar? php, ruby, java, perl, python, ...
Luego para cada lenguaje puedes disponer de varios frameworks, para liar mas la cosa...

Lo que si parece estar claro es que el dominante en los sitios populares es php.
Otra cosa curiosa es que los desarrolladores de Java tienen predilección por ruby y su RoR (Ruby on Rails). Como en este caso JJ.

Sobre python, entre los númerosos frameworks (a ver si encuentro un artículo bueno que los compare) que tiene el que parece está teniendo bastante tirón es django.
Sobre python no voy a profundizar, ya que será motivo para otro post.

Mi curiosidad se centra en RoR. A ver que hay detrás. Entonces que mejor que echar un vistazo a lo que hay por la red:


Notas finales:
  • Al buscar la imagen, encontré esta página, que compara también php, java y ruby.
  • Estas comparaciones hay que tomarlas con recelo ya que en muchos casos no son objetivas.
  • Visto lo visto, como que paso ni de mirar mas fondo RoR.

jueves, abril 10, 2008

Autotools

¿Quien no conoce el famoso script configure?
Parece mentira que hasta la fecha nunca haya tenido que hacer uno. Pero creo que va siendo el momento...
Aprovechando que tenemos un momento de parón en el proyecto y la ocasión perfecta.
Estoy generando un rpm que tienen dependencias de unas librerías externas y claro... no está nada bien el tener rutas a piñón... Estoy ante la ocasión perfecta.
Pongamonos a ello...

Las principales herramientas de autotools son:
  • automake [wiki]: nos permitirá generar mejores makefiles, mas portables, ...
  • autoconf [wiki]: es la que nos va asegurarnos que disponemos de todo lo necesario. Usa para ello macros escritas en M4. Existe un repositorio de macros, por si necesitamos macros aparte de las que ya acompañan al paquete.
  • libtool [wiki]: Por lo visto si lo que queremos es generar una libreria, la necesitaremos.
En principio, creo me voy a limitar a usar autoconf, y a mantener el makefile a mano.

Una cosa superinteresante de automake es que te detecta las dependencias dinámicamente. Cuando haces un makefile a mano, son estáticas, ya que tu las tienes que meter en las reglas. O bien montarte tu dicho mecanismo. Pues bien... automake esto te lo da.

Este post lo iré actualizando sobre la marcha..

Pares clave-valor persistentes

Para almacenar persistentemente pares clave-valor disponemos de GDBM - The GNU database manager. La cual es la reimplementacion de dbm para gnu.
Como no podia ser de otra manera tenemos un módulo en python para hacer uso de ella.

Otra implementacion es bdb.

Como otros almacenamientos persistentes tenemos:

Mondrian Code Review On The Web


Creo que fue en el video sobre Google App Engine, donde escuché sobre Mondrian.
Aprovechando que ahora tengo tiempo lo he estado viendo... y merece la pena verlo.

La charla, impartida por Guido, empieza mostrando lo que usaban antes de que implementaran Mondrian, lo que aporta Mondrian y sus ventajas. Básicamente usaban varios scripts.
Ah! antes de nada comenta sobre la filosofía de trabajo. Parte de él es hacer reviews del código fuente.

Hacer revisiones es una alternativa a la xp. Eso si con el mismo objetivo, mejorar la calidad. ¿Donde he visto yo estas practicas? ¿En ningún sitio?

Gracias al video me enterado de cosillas, como por ejemplo que prácticamente no usan branches, y que como sistema de control de versiones usan Perforce [wikipedia][site].

Lo que hace en pocas palabras
Lo que tienen ahora es una aplicación web que gestiona todo el tema de las reviews.
Como desarrollador te revisan y revisas. En la pantalla puedes ver en 2 paneles codigo antiguo y nuevo, poner comentarios....
Ademas se hace uso del correo para enviar notificaciones, ...
Todas estas cosillas siempre se guardan, usandose para ello BigTable+GFS.
Lógicamente también tienen que acceder al servidores de Perforce, y a los entornos de los usuarios (soportan SSH y NFS).

Como lo hacen
Guido comenta que casi podría correr en una maquina, ya que casi todo el trabajo pesado se hace fuera (Perforce, GFS, rendering de html), pero que lo tienen montado en dos maquinas: una para el mail server y otra para el web server.

Y como no podría ser de otra manera usan python a saco: el mail server es wsgiref (multithread y estandard) y el mail server smtpd.py (monothread).

El interfaz es html+css, usando las templates de django, y como no podía ser de otra manera, usan AJAX.

Para hacer los diffs usan la librería de python difflib.

Tanto smtpd, como wsgiref y difflib son módulos estándares de la distribución de python.

miércoles, abril 09, 2008

Visual Test


Hablando ayer con mi futura cuñaaaaaaaa, le comentaba que hace años mil yo usaba Visual Test para la automaticación de pruebas de interfaces graficas.

El motivo de la conversación era porque estabamos generando .avi's a parter de dvds. El problema de dejar lanzado un lote de generaciones es que si te sale un popup, por algun problema o alerta, el proceso se para (usamos autogk). Le comenté que eso se podría solventar con un script realizado con visual test, y de ahí este dejavú.

La verdad es que era supercomodo de usar. Te grababas las accciones y automáticamente se generaba un script. Script que luego podrias adaptar.
Con N de estos scripts te montabas ya una batería de pruebas. Era la caña...

Me he quedao sorprendido de, ya no sólo que pasara a ser de Rational, sino que Rational ha pasado a ser de IBM.

Esta es la lista de los productos de rational.
Y como no, el sucesor de visual test está: IBM Rational Robot.

Referencias:
Actualización
  • Para la automatización en unix, disponemos de expect.
  • Como no podia ser de otra manera hay un flavour en python: pexpect.
  • Y una par de herramientas for free para windows: autohotkey y autoit.

martes, abril 08, 2008

Google App Engine

He flipado un poco cuando lo he visto en barrapunto. Esto puede ser un buen empujón para python y django.

Este artículo lo cuenta muy clarito.
Y os recomiendo ver los videos en youtube del Campfire One: Google App Engine.

De momento su uso está cerrado, pero puedes indicar que te avisen cuando vuelvan a ofrecer el servicio. De momento para probar y enredar se puede usar el SDK en local.

La idea de todo esto, es desarrollar y olvidarte del manteniento de la aplicación online, de cuanta maquina necesitas, cuanto espacio en disco, el que este online 24x7,.... Google se ocupa de todo esto.
¿Interesante verdad?
Bueno... la chicha:
Relacionado:
  • Big Table.
  • AWS: "AWS offers into a singular package: storage like S3, auto-scaling and processing power like EC2, and a datastore like SimpleDB." (Simple db: BD hecha en java).

jueves, abril 03, 2008

Python IDEs

Jonathan Ellis comenta que a raiz de un post en un blog ha estado organizando el listado de los editores python 'reales' existentes.
También hay un listado de editores que tienen algún soporte para python, pero que no pueden ser considerados editores 'reales'.

La diferencia entre los primeros y los segundos está principalmente en las facilidades que te den para hacer introspección, depuración y ayuda a la codificación.

martes, marzo 18, 2008

RAID for dummies

Bueno... tras leer sobre RAID (debido al NAS que me he pillado) ahí van unas notas breves:
  • Del RAID 2 y 3 nos podemos olvidar.
  • RAID 0. Los datos se reparten en varios discos. Acceso más rapido tanto en lectura como escritura. No hay redundancia.
    • JBOD: No es realmente RAID 0, pero es parecido. Sirve para ver varios discos como uno solo.
  • Con RAID 1 (data mirroing) tenemos un disco espejo. Con lo cual es la redundancia más cara. No ganamos velocidad en lectura pero si en escritura (normalmente).
  • RAID 4: división por bloques on un disco dedicado a la paridad.
  • RAID 5: se usa mucho, porque se obtiene redundancia a bajo coste. Es mas lento en escritura, ya que hay que calcular los bloques de paridad, que se van escribiendo (es importante estudiar el tipo de acceso de escritura para saber si nos va a liminar). Son necesarios 3 discos. Puede recuperarse ante el fallo de un disco. Pero no ya de un fallo de un segundo disco.
Estos son los clásicos. Pero hay mas:
  • RAID 6: protege ante fallo de dos discos.
  • RAID 5E y 6E
  • RAIDs anidados.
  • .../...

miércoles, marzo 05, 2008

Compartiendo un fichero entre procesos

Imaginaros que se os da la situación en la cual necesitais compartir un archivo entre procesos.
Vamos a ver que opciones tenemos:

[1] Usar como lock un archivo que creamos. Se puede usar la llamada os.open() para crear un archivo en exclusiva. El proceso que lo pueda crear tiene via libre para usar ya el fichero que nos interesa. Hay que tener cuidado con proporcionar los mecanismos para no dejar el lock por ahí.

[2] Usar los mecanismos que nos proporciona el OS para bloquear ficheros. Llamada fcntl.lockf().

A continuación voy a copiar dos scripts que demuestran su uso. Ejecutar en primer lugar uno.py e inmediatamente dos.py en otro terminal.
En estos scripts se hace un open() se bloquea el archivo y despues un close().
Una alternativa seria el tener siempre el open() hecho y simplemente hacer el lockf(). Supongo que esto funcionaría pero no lo he probado.

Ya para acabar, comentar la importancia de hacer el seek() en el segundo script para poder escribir en lugar adecaudo del fichero.

uno.py

import os
import fcntl
import time

#--- Creamos el fichero
h = open("kk.txt","w")
h.write("hello\n")
h.close()

#--- Ahora lo abrimos bloquendolo

h = open("kk.txt","a")
fcntl.lockf(h.fileno(),fcntl.LOCK_EX)
print "Hemos pillado el lock y n os vamos a dormir"
time.sleep(15)
print "escribimos"
h.write("hello\n")
print "Tam: ", h.tell()
#h.flush() -> He procado sin el flush y funciona correctamente,
# pero con el, podría ser mas seguro.
# Adicionalmente está la llamada os.fsync().
# Si queremos mas control en el modo de apertura de los
# ficheros tenemos que usar la llamada os.open().
# Por ejemplo si los queremos crear en exclusiva.
print "Liberamos el lock y cerramos"
fcntl.lockf(h.fileno(),fcntl.LOCK_UN)
h.close()

dos.py

import os
import fcntl
import time



#--- Abrimos
#
# Nota: Si usamos LOCK_NB en lockf al adquirirlo y no podemos,
# nos da un error.

h = open("kk.txt","a")
#fcntl.lockf(h.fileno(),fcntl.LOCK_EX|fcntl.LOCK_NB)
fcntl.lockf(h.fileno(),fcntl.LOCK_EX)
print "Hemos pillado el lock y n os vamos a dormir"

#--- Lo usamos
h.seek(0,2)
print "Tam: ", h.tell()

#--- Cerramos

print "Liberamos el lock y cerramos"
fcntl.lockf(h.fileno(),fcntl.LOCK_UN)
h.close()

lunes, febrero 25, 2008

urllib vs urllib2

Haciendo unas pruebecillas con la página de la wikipedia de mi signo chino, me pasaba una cosa curiosa que era que en la maquina en la que estaba ejecutando mi código me daba un error:


>>> import urllib2
>>> urllib2.urlopen("http://es.wikipedia.org/wiki/Rata")
Traceback (most recent call last):
File "", line 1, in ?
File "/usr/lib/python2.4/urllib2.py", line 130, in urlopen
return _opener.open(url, data)
File "/usr/lib/python2.4/urllib2.py", line 364, in open
response = meth(req, response)
File "/usr/lib/python2.4/urllib2.py", line 471, in http_response
response = self.parent.error(
File "/usr/lib/python2.4/urllib2.py", line 402, in error
return self._call_chain(*args)
File "/usr/lib/python2.4/urllib2.py", line 337, in _call_chain
result = func(*args)
File "/usr/lib/python2.4/urllib2.py", line 480, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden



Pero sin embargo, haciendo un wget, si que la obtenía...
Se me ocurre probar con urllib en lugar de con urllib2 y si que la obtengo. ¿Mande?

Solución ñapa temporal :pppp:


try:
h = urllib2.urlopen(theUrl)
except:
h = urllib.urlopen(theUrl)


¡Dios! ¡soy un lumbreras!
Bueno seamos serios.... tras probar mis cosillas gracias a la ñapa, procedamos a mirar que es lo que realmente está pasando...
Pues lo que está pasando es que urllib2 está enviando unos headers al servidor web que no le molan...
La solución es cambiar el user agent.
Para ello lo que tenemos que hacer es proceder del siguiente modo (por ejemplo):


userAgent = 'Mozilla' # Por ejemplo
headers = { 'User-Agent' : userAgent }
req = urllib2.Request(theUrl, None, headers)
response = urllib2.urlopen(req)
thePage = response.read()


Referencias:

lunes, febrero 04, 2008

HTML5 or XHTML 2.0

He leido un artículo interesante que compara HTML5 contra XHTML 2.0 [vía].

martes, enero 29, 2008

Brad Fitzpatrick

De una cosa que se oye hablar últimamente: opensocial.
Y tambien de openid.

Detrás de ambos proyecto hay un nombre común: Brad Fitzpatrick.

jueves, enero 24, 2008

¿Escalan bien los lenguajes dinámicos?

A través de este post de barrapunto, llego a éste articulo de The Server Side.
Es de interesante lectura, no solo por el artículo, sino ademas por todas las referencias que contiene.

Parece que todo viene a colacion del proyecto chandler.

TinyURL

Hoy me he encontrado una pequeña herramienta web, que puede ser muy util, TinyURL. No sólo proque nos puede ayudar a hacer mas manejables ciertas urls, sino porque nos puede permitir no favorecer el algoritmo de google, por el tema del enlazado. Se sepa... ;). O bien por lo que sea porque queramos enmascarar una url hasta el momento de pincharla.

miércoles, enero 16, 2008

Lista de año

En el 2007 mi lista favorita sin dudarlo ha sido python-es.

martes, enero 15, 2008

Blog favorito 2007

Sin dudarlo, Ismael El-Qudsi.

lunes, enero 14, 2008

Ha surgido un thread muy interesante en python-es a raiz de que python ha sido declarado por TIOBE lenguaje del año 2007.

viernes, enero 11, 2008

TIOBE Declares Python the Programming Language of 2007.

Impresionante el avance de Lua.

sábado, enero 05, 2008

¿que nos deparará el 2008 en cuanto a buscadores?

Un post interesante de dirson al respecto.

jueves, noviembre 15, 2007

Python en Linux-magazine

El número 32 de Linux Maganize va dedicado a python [vía la lista python-es].