sábado, noviembre 13, 2010

code coverage en python

convirtiéndome en un unittester necesito motivación para seguir testeando, esa motivación me sirve para mejorar, en el caso de python compito contra el puntaje que me da pylint, en el caso de testing estaba buscando algo para competir y encontré coverage, que es una herramienta que mide cuando código cubren tus tests.


si bien el code coverage no es indicativo que no hay bugs, es una buena forma de intentar superarse y agregar mas pruebas.


acá va una mini receta de como instalarlo y usarlo, en mi caso ubuntu 10.10 pero debería adaptarse fácilmente a otros SO.


instalando lo necesario


sudo apt-get install build-essential python-dev
sudo easy_install pip

instalando coverage


sudo pip install coverage

probandolo


yo tengo todos los tests en un directorio llamado test (que original) y en el archivo __main__.py importo todas las clases que heredan de unittest.TestCase y llamo a unittest.main()


para correr coverage ejecuto


coverage run test/__main__.py
coverage html --omit="/usr/*"

con el primero se mide la cobertura de código, con el segundo se genera un reporte html, ahora miramos el reporte


firefox htmlcov/index.html

para tener algo mas simple y fácil de correr para medir el avance podemos usar


coverage report --omit="/usr/*"

que nos muestra el reporte en consola, podemos hacerle un watch o un grep para seguir mas de cerca algún modulo


bueno, esta fue la forma de hacer el testing algo mas parecido a una competencia por quien consigue el puntaje mas alto, al menos a mi eso me sirve

martes, noviembre 09, 2010

si mis hermanos fueran canciones

si, leiste bien, este post iba a ser sobre la banda kyuss, pero en el medio estaba escuchando un tema de la banda y pense


si war fuera una cancion seria esta

(war es mi hermano mas chico) y automaticamete pense, que idea chiflada, que cancion seria pablo? (mi otro hermano, el mas grande), sin mucho pensar se me vino un tema a la mente


aqui estan, estos son... ante ustedes les presento a mis hermanos


pablo, tambien llamado Immigrant Song de Led Zeppelin




war, Whitewater de Kyuss




espero que mis canciones, ehem, hermanos les caigan bien

domingo, noviembre 07, 2010

apoyo moral a Martín Gaitán en su carrera

yo le hago el aguante a Martín Gaitán en su carrera despiadada.

espero que este link le permita subir un poco mas en el ranking de google :P

ya hablando en serio, no solo me parecio interesante su carrera sino que el articulo esta muy bien escrito.

PD: me voy a mirar contra quienes compito ;)

martes, noviembre 02, 2010

charla sobre efene en la utn cordoba

gracias a los muchachos del grupo uni-code voy a estar dando una charla sobre el lenguaje de programación efene en la utn este viernes.

del anuncio del grupo:


los esperamos este Viernes 5 de Noviembre, a las 17:30 Hs en el 1º Piso del Edificio Central de la U.T.N.

PS: se emocionaron un poco con el cartel, yo no tuve nada que ver con la concepción del mismo :P

CouchApp V: filtrar documentos por tag ordenados por fecha

ahora tenemos documentos y para pertenecer a este siglo decidiste agregar tags a algunos elementos para poder filtrarlos y categorizarlos (decí folksonomia y vas a sonar mucho mas hip!)

ahora, como filtro documentos por tag?

si puedo hacer eso, como filtro por tag y ordeno por fecha?

ya que estamos, no seria lindo poder filtrar por tag *y* por fecha?

vamos a resolver todos estos requerimientos con una simple vista

primero creamos la vista

couchapp generate view by-tag

esto crea una vista en el directorio views llamado by-tag, este es un directorio que contiene dos archivos, map.js y reduce.js

en este caso vamos a usar solo map.js asi que borra reduce.js

cd views/by-tag
rm reduce.js

ahora edita map.js para que se vea como esto

function(doc) {
    if (doc.tags) {
        doc.tags.forEach(function (element, index) {
                emit([element, doc.created], doc);
        });
    }
}

por cada documento en la base de datos, vemos si tiene el atributo tags, si lo tiene, por cada tag en tags emitimos un documento cuya llave es un array con el tag y la fecha y cuyo valor es el documento en si.

ahora empujamos los cambios a couchdb

couchapp push

para probar que funciona, crea algunos documentos con el un campo llamado tags que contenga un array de strings y otro campo llamado created que contenga el timestamp en el que el documento fue creado

si pongo esta URL http://localhost:5984/datos/_design/datos/_view/by-tag/ en mi navegador, obtengo algo así:

{"total_rows":8,"offset":0,"rows":[
{"id":"d6de7e9a63039dc1af500a40af0014d7","key":["bar",1288644825761],"value":{"_id":"d6de7e9a63039dc1af500a40af0014d7","_rev":"1-eab86fbc2b4c24f31e1d60dfdd762793","author":"wariano", "created":1288644825761, "tags":["test","foo","bar"], ...}},
...
]}

esto significa que la vista funciono, ahora para filtrar por tag la URL se va a poner un poco rara

vamos a usar filtros en la vista para filtrar solo los documentos con un tag especifico

http://localhost:5984/datos/_design/datos/_view/by-tag?descending=false&startkey=["test", 0]&endkey=["test", 9999999999999]

con este request decimos que queremos los resultados de la vista llamada by-tag, filtrando los documentos empezando con la llave ["test", 0] y terminando con la llave ["test", 9999999999999]. Esto significa que solo queremos los documentos con la llave "test" y que queremos todos los timestamps (por eso el numero enorme en endkey)

si queremos ordenar los tags en orden descendente deberíamos cambiar el orden de starkey y endkey: http://localhost:5984/datos/_design/datos/_view/by-tag?descending=true&startkey=["test", 9999999999999]&endkey=["test", 0]

podemos jugar con startkey y endkey para obtener rangos de tags o un tag en un periodo de tiempo especifico, por ejemplo: "cosas taggeadas con fun en los últimos dos días"

el código para hacer el request a couchdb desde javascript es el siguiente

datos.getByTag = function (tag, descending, okCb, errorCb, startStamp, endStamp) {
    var tmp;

    startStamp = startStamp || 0;
    endStamp = endStamp || 9999999999999;

    if (descending) {
        tmp = endStamp;
        endStamp = startStamp;
        startStamp = tmp;
    }

    $.couch.db(datos.db).view("datos/by-tag",
        {"descending": descending, "startkey": [tag, startStamp], "endkey": [tag, endStamp],
            "success": okCb, "error": errorCb});
};

con esto tenes una forma de listar documentos por uno o mas campos, podes modificar este ejemplo un poco para listar por usuario o por otras cosas

[EN] CouchApp V: filter documents by tag ordered by timestamp

you now have documents and to be in this century you decide to add tags to some elements so you can filter and categorize (say folksonomy and you will sound really hip!)


now, how do I filter the documents by tag?


if I can do that, how do I filter by tag and order by date?


now that we are at it, wouldn't be nice to have a filter by tag *and* date?


we will solve all this requirements with a simple view


first we create the view


couchapp generate view by-tag

this creates a view in the views called by-tags, this is a directory that contains two files, map.js and reduce.js


in this case we will only use the map.js file, so remove the reduce.js file


cd views/by-tag
rm reduce.js

now edit the map.js file to look like this


function(doc) {
    if (doc.tags) {
        doc.tags.forEach(function (element, index) {
                emit([element, doc.created], doc);
        });
    }
}

here for each document in the database we check if the document has the tags attribute and if it has the attribute, for each tag we emit a document that contains as key an array with the tag and timestamp when the document was created and as value the document itself


now we push our changes to couchdb


couchapp push

to test that this works, create some documents with a field called tags that contains a list of strings and a field called created that contain the timestamp when the item was created


if I put this URL http://localhost:5984/datos/_design/datos/_view/by-tag/ in my browser I get something like this


{"total_rows":8,"offset":0,"rows":[
{"id":"d6de7e9a63039dc1af500a40af0014d7","key":["bar",1288644825761],"value":{"_id":"d6de7e9a63039dc1af500a40af0014d7","_rev":"1-eab86fbc2b4c24f31e1d60dfdd762793","author":"wariano", "created":1288644825761, "tags":["test","foo","bar"], ...}},
...
]}

this means the view worked, now to filter by tag the URL will get weird


we will use filters in the view to filter only for a specific tag


http://localhost:5984/datos/_design/datos/_view/by-tag?descending=false&startkey=["test", 0]&endkey=["test", 9999999999999]


with this request we say that we want to get the result of the view called by-tag, filtering starting with the key ["test", 0] and ending with the key ["test", 9999999999999]. This means that we only want the documents with the key "test" and we want all the timestamps (that's why the huge number in the endkey


if we want to sort the tags in descending order we should switch the start and endkey like this: http://localhost:5984/datos/_design/datos/_view/by-tag?descending=true&startkey=["test", 9999999999999]&endkey=["test", 0]


we can play with startkey and endkey to get a range of tags or one tag in a specific period, for example, "things tagged fun in the last 2 days"


the code to do the request to couchdb from javascript is the following


datos.getByTag = function (tag, descending, okCb, errorCb, startStamp, endStamp) {
    var tmp;

    startStamp = startStamp || 0;
    endStamp = endStamp || 9999999999999;

    if (descending) {
        tmp = endStamp;
        endStamp = startStamp;
        startStamp = tmp;
    }

    $.couch.db(datos.db).view("datos/by-tag",
        {"descending": descending, "startkey": [tag, startStamp], "endkey": [tag, endStamp],
            "success": okCb, "error": errorCb});
};

with this you have a way to list documents by one or more fields, you can modify this a little to list by users, or by some other thing

Seguidores

Archivo del Blog