logo

Acerca de

Bienvenido a mi blog, el sitio perfecto para mis inquietudes, experiencias e idas de olla sobre temas de hoy en día.

Historia al azar

Categorías

Últimas entradas

Últimos comentarios

Enlaces

Meta

photo Luis PeraltaEstado Jabber
Ziritione
Castellón Spain
39.997638, -0.064030

Sindica

Sindícame, por cortesía del subliminal Atom.

16 marzo 2008

El tener una API en 11870.com permite, entre otras cosas, el prototipado rápido de chorradas varias sin mucho esfuerzo. Así que hoy me ha dado por probar un poco otra API: Google Chart API (API de gráficas de Google) y que menos que explotar algún dato de los que hay en 11870.com. Ya se sabe, una imagen vale más que mil palabras, así que me he decidido a pintar las ciudades donde tengo sitios guardados.

Podría haber manejado a pelo la API de Google pero, puestos a probar, me he tirado a Python Google Chart que ofrece una interfaz para Python bastante cómoda. Lo primero que ha habido que hacer es descargar la lista de mis sitios:

import httplib2
import feedparser

def get_oos_entries(slug):
    user = "luis@XXXXXXX"
    key = "XXXXXXX"
    base_url = OOSURL + "/sites/" + slug
    
    entries = []
    
    h = httplib2.Http()
    h.add_credentials(user, key)
    next_url = [base_url]

    while len(next_url) == 1:
        base_url = next_url[0]
        r, c = h.request(base_url)
        feed = feedparser.parse(c)
        entries.extend(feed.entries)
        next_url = [i.href for i in feed.feed.links if i.rel == 'next']
        
    return entries

La lógica puede parecer un poco difusa, pero es simplemente porque el feed de resultados de nuestros sitios está paginado y los necesitamos todos. El cómo conseguir la key está documentado en 11870.com API authentication. Una vez con los sitios, tenemos que saber cuántos sitios hay por cada localidad o área geográfica:

from operator import itemgetter
from itertools import groupby

def do_chart_input(entries, field, other_threshold=None):
    f = itemgetter(field)
    lentries = [entry for entry in entries if entry.get(field, None)]
    sorted_entries = sorted(lentries, key=f)
    res = {}
    others = 0
    for k, g in groupby(sorted_entries, f):
        num = len(map(f, g))
        if other_threshold is not None and num / float(len(lentries)) < other_threshold:
            others += num 
        else:
            key = k + u' (' + str(num) + ')'
            res[key] = num
    
    if other_threshold is not None:
        res['Otros (' + str(others) + ')'] = others
        
    return res

A este método se le pasan las entries obtenidas con get_oos_entries, el campo sobre el que realizar la agrupación y si queremos que aquellas agrupaciones que no superen un cierto umbral se agrupen bajo un Otros. En el caso de mis ciudades, hay un montón de ellas donde sólo tengo un sitio, por lo que la gráfica salía muy muy fea si no aplicaba el filtro con umbral. El parámetro field sirve para determinar sobre qué elemento de cada entrada realizamos la agrupación y así conseguimos que el método sea lo suficientemente genérico como para calcular los datos sobre cualquier tipo de área (país, ciudad, barrio, etc...). El cuerpo principal de nuestro programita sería tal que así:

if __name__ == '__main__':
    entries = get_oos_entries('peralta')
    res = do_chart_input(entries, 'oos_locality', 0.03)
    chart = PieChart2D(600,375)
    chart.add_data(res.values())
    chart.set_pie_labels([i.encode('utf-8') for i in res.keys()])
    chart.set_title('mis ciudades en 11870.com')
    chart.download("/tmp/x.png")

Y el resultado:

Si quisiéramos pintar los barrios de manu, modificariamos el cuerpo principal tal que:

entries = get_oos_entries('manueltxo')
    res = do_chart_input(entries, 'oos_subdependentlocality', 0.03)

Y el resultado:

De aquí a hacer una interfaz web para mostrar estas imágenes a partir de cualquier usuario hay 15 minutos, pero se queda como ejercicio ;)

29 enero 2008

Los hashes o resúmenes FNV (de Fowler / Noll / Vo) son útiles por varias razones:

  • Es muy rápido generarlos
  • El tamaño del hash es fácilmente manipulable
  • Se portan muy bien, es decir, producen pocas colisiones

Pues hoy necesitaba usarlos con mi querido Python y curiosamente nadie lo había implementado. Así que no me ha quedado más remedio que ponerme (no sé quién me ha dicho esta tarde que eso sería sólo un algoritmo, que no tendría complicación... en cuanto lo recuerde se va a acordar). Por si a alguien le viene bien:

def FNV1a32(key):
    fnv_prime = long(0x1000193)
    hash = long(0x811C9DC5)
    for i in range(len(key)):
      hash ^= ord(key[i])
      hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24)
    return (hash & 0x00000000ffffffffL)

def FNV132(key):
    fnv_prime = long(0x1000193)
    hash = long(0x811C9DC5)
    for i in range(len(key)):
      hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24)
      hash ^= ord(key[i])
    return (hash & 0x00000000ffffffffL)

La diferencia entre FNV132 y FNV1a32 es el orden en el que se hace la multiplicación. Y aquí sólo he puesto los métodos que calculan el hash de 32 bits, en la referencia de arriba tenéis cómo hacer para generarlos variables (escoger un buen primo inicial, fnv_prime, y un valor inicial del hash, hash, adecuados y quedarnos sólo con la parte del resultado que nos interese).

9 octubre 2007

Ayer el borrador 17 de la especificación del Atom Publishing Protocol pasó a estándar como RFC 5023. Es sin duda un paso importante a la hora de estandarizar la publicación de contenidos. Lo que este estándar hace muy bien es reaprovechar otros estándares y no intentar reinventar la rueda: Atom syndication format (RFC 4287) para el contenedor de datos y HTTP (RFC 2616) para el transporte.

Se hacen eco de la noticia unos cuantos que han seguido el desarrollo como: Joe Gregorio, John Panzer, James Snell, ...

En 11870 hemos estado a la zaga con el estándar y hace ya tiempo que vimos que AtomPub iba a tener tirón. Por eso también estamos en enhorabuena en la ofi, porque nuestra API está fuertemente basada en el AtomPub (de hecho, el fuertemente es totalmente, pero hemos tenido que extender Atom para algunas cosas) y OpenSearch. Quizá el próximo estándar a implementar antes de que sea estándar sea OAuth... ;)

26 septiembre 2007

Mi lectura técnica de este verano recién terminado ha sido Beautiful Code. Se trata de un tipo de libro poco común desde mi punto de vista, porque el planteamiento del editor fue «voy a buscar a un tío que me cuente qué trozo de código ha escrito o leído por el que se sienta orgullo o tenga una especial admiración». Y así la friolera de 33 capítulos, treinta y trés.

Algunos de los autores me eran desconocidos totalmente, otros me sonaban y el resto eran de los de toda la vida. Algunos de los capítulos que me han llamado especialmente la atención:

  • A Regular Expression Matcher por Brian Kernighan, o cómo hacer un matcher de expresiones regulares con 400 líneas de C. Brillante, aunque no habla de su código sino del de Rob Pike. Además acaba el capítulo proponiendo ejercicios para el lector (el único que lo hace). Además, el tema está bastante de moda, porque parece que todas las implementaciones de los matchers actuales descienden de una implementación con backtracking que no es la más eficiente, porque la cañera, la de hace 30 años de Pike, se perdió en algún lugar.
  • Finding Things por Tim Bray. Sobre parsing de ficheros de log con Ruby, la verdad es que un capítulo bastante flojo, pero lo pongo por aquí porque el calavering se ha hecho colega de Tim Bray.
  • Correct, Beautiful, Fast (In That Order): Lessons From Designing XML Verifiers por Elliotte Rusty Harold. Interesante relato de cómo hacer dos veces lo mismo (un verificador de XML) te abre los ojos a la hora de tomar decisiones, explicando cómo fue cada una de ellas antes y después. No cuenta la pereza que le dio repetir el curro, que me parece de lo más importante.
  • Framework for Integrated Test: Beauty through Fragility por Michael Feathers. Describe su framework (y dale con la palabra) para la ejecución de tests de manera automática. Una patada en el estómago para los ortodoxos radicales de la programación orientada a objetos.
  • Beautiful Tests, por Alberto Savoia. O cómo se puede pensar a la hora de intentar que algo no funcione, para escribir el test acorde. Ejemplo, seguido de contraejemplo, seguido de contracontraejemplo. Ilustrante.
  • On-the-Fly Code Generation for Image Processing por Charles Petzold. Este capítulo es de los mejores, porque describe cómo en las primeras versiones de windows determinadas operaciones con imágenes en mapas de bits podían lentísimas. El enfoque para arreglarlo fue generar código al vuelo para cada una de ellas. Cuando lo lees te quedas un poco asombrado de la capacidad que puede llegar a tener la gente. Por desgracia, el capítulo habla de una implementación de ejemplo en c# para .Net en vez de la de hace 20 años (de ahí que el capítulo haga referencia a portable).
  • How Elegant Code Evolves With Hardware: The Case Of Gaussian Elimination por Jack Dongarra y Piotr Luszczek. Relata la historia del paquete LINPACK de cálculo numérico y de cómo se ha ido adaptando a los cambios de las arquitecturas HW subyacentes gracias a su diseño. Interesante.
  • Python's Dictionary Implementation: Being All Things to All People por Andrew Kuchling. Diseño cuidado y excepciones para casos concretos en los diccionarios de Python. Es curioso leer cosas así después de haber sido abducido por el sistema de "una forma de resolver el problema y que lo haga bien".
  • Distributed Programming with MapReduce por Jeff Dean y Sanjay Ghemawat. Describen el enfoque de programación paralela que se ha aplicado en los últimos años en Google. Interesante para comprender el concepto y anhelar que Hadoop esté listo para hacer alguna cosilla.
  • When a Button Is All That Connects You to the World por Arun Mehta. Te cuenta cómo funciona el sistema que utiliza Stephen Hawkins para comunicarse con el mundo, que consiste en un único botón. Curioso.
  • Code in Motion, por Laura Wingerd y Christopher Seiwald. Cómo escribir código que sea visualmente comprensible. Una especie de guía de estilo que va un poco más allá. Por ejemplo, te cuentan que les parece mucho mejor poner las condiciones de un if en líneas distintas, que se entiende mejor sin pensar. Yo les hice caso durante un día o dos durante mis sesiones de tecleo y la fricción cognitiva que me producía el asunto visualmente me impedía pensar.

Los capítulos no mencionados... no significa que no valgan la pena, simplemente que ya no quería escribir más, o que no los iba a resumir todos o que realmente no valían la pena. Hay que tener cuidado, porque efectivamente hay alguno tostón tostón.

En definitiva, un libro a tener de todas todas. Es un libro de ingeniería del software escrito por programadores y no por teóricos y creo que une lo mejor de los dos mundos. Los beneficios del libro se donan a Amnistía Internacional, así que una razón de más.

18 septiembre 2007

If Joe Gregorio can name his framework Robaccia, I certainly can name my database Basura.

-- Sam Ruby.

Página anterior Página siguiente