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.

11 agosto 2009

Para la posteridad:

#!/usr/bin/python26                                                             
# kevent proc demo - luis peralta                                               
# http://www.ziritione.org                                                      
#                                                                               
# tested on python 2.6 % freebsd 7.2                                            

import sys
import select

if __name__ == '__main__':
    print sys.argv
    kq = select.kqueue()
    ke = select.kevent(int(sys.argv[1]),
                       select.KQ_FILTER_PROC,
                       select.KQ_EV_ADD|select.KQ_EV_ADD,
                       select.KQ_NOTE_FORK|select.KQ_NOTE_EXEC|select.KQ_NOTE_TRACK, select.KQ_NOTE_EXIT)
    events = kq.control([ke], 0, 0)
    while True:
        events = kq.control([], 1, 0)
        if len(events) > 0:
            for event in events:
                if event.fflags & select.KQ_NOTE_FORK:
                    print event.ident, "forked"
                if event.fflags & select.KQ_NOTE_EXEC:
                    print event.ident, "called exec"
                if event.fflags & select.KQ_NOTE_EXIT:
                    print event.ident, "exited"
                if event.fflags & select.KQ_NOTE_CHILD:
                    print event.ident, "is child, parent ", event.data

Se puede probar así: python2.6 kevent-test.py $$ &

12 abril 2008

Hace tiempo que tenía pensado publicar esto y al final, entre una cosa y otra, el tiempo ha ido pasando. La geocodificación inversa o reverse geocoding es el proceso de obtener una dirección o referencia local a partir de un par de coordenadas. Lo habitual suele ser lo contrario, el geocoding de toda la vida, donde a partir de una dirección obtenemos su par de coordenadas. Y digo lo habitual porque es una de las funcionalidades básicas que ofrencen las APIs de mapas (GClientGeocoder de Google o Geocoding API de Yahoo!). Lo que no suelen ofrecer es el proceso inverso (aunque hay varias ñapillas para hacerlo).

Ask tiene una API no pública para hacer precisamente esto. Ya veremos lo que dura una vez su uso se extienda (y espero que dure lo suficiente mientras se desarrolla Lost, que fue el primero en utilizarla de estranjis). La documentación aquí, gracias a Roland, con un ejemplo de código python.

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

16 diciembre 2007

No, no voy a hablar de la archiconocida serie de televisión, sino del proyecto que tengo en mente y en mis dedos desde hace bien poco: Lost, never get lost again. Una prueba de concepto de la unión de dos ideas: localización y sitios cercanos; algo que creo que va a marcar la tendencia en tecnología en los tiempos venideros y que no hay que dejar de lado.

¿Qué tengo cerca? ¿dónde estoy? ¿qué necesito, aquí y ahora? Esas son las preguntas que voy a intentar resolver de cuando en cuando.

Las herramientas, por ahora, van a ser python, servicios de geolocalización y location aware search engines (como la API de 11870, pero no es el único). Eso, unido a mi N70.

Los experimentos irán variando, rápido, volcando ideas, intentando sentir una necesidad cumplida. El código intentará seguir a las ideas, la ansiedad saciada puede que un poco más por detŕas.

Y todo esto dentro de mi particular sesenta/cuarenta (no confundir con ochenta/veinte), que implica dedicar cuatro noches de cada diez a mis proyectos en vez de vagar por Perdition city. El nombre del proyecto no sólo hace referencia a encontrar esa seguridad diluida por el desconocimiento de no saber dónde estamos, sino por la vida que se puede llevar en una ciudad como ésta.

Busco betatesters. A ser posible con N70s. A ser posible tecnófilos. A ser posible con ganas de cambiar lo que significa estar fuera de casa.

Actualización: primeros pantallazos.