viernes, diciembre 31, 2010

la naranja mecanica, el punk argentino y no me gusta stanley kubrick

hace un rato termine de leer la naranja mecánica, durante todo el libro pensaba que había muchas frases de la canción de los violadores "uno dos ultraviolentos".

nunca le presto atención a las letras así que no fue muy obvio para mi, pero el estribillo tenia muchas referencias al libro.

Al terminar el libro leí la letra y definitivamente esta lleno de términos del libro :D

acá va la letra:

Uno-Dos Ultraviolento
Uno-Dos Ultraviolento
Uno-Dos Ultraviolento
Uno-Dos Ultraviolento

Varias debotchas
caminan por ahi
Mueven sus scahrros
con frenesi
Los mal chicos de cuero
nos queremos divertir
Con mis drugos
al ataque vamos a ir

Y ahora que pasa, eh?
Y ahora que pasa, eh?
Y ahora que pasa, pasa:
Uno-Dos Ultraviolento.

Sin militscos en la esquina
Es mas fácil para mi
El dremcom en la goloba
Me hace decidir
La de grudos mas bolches
La quiero para mi
Crobo rojo entre sus capas
Les haremos salir

Y ahora que pasa, eh?
Nos quieren transformar
No lo lograran
No lo lograran
No, no lo lograran
No... no, no, no

Y ahora que pasa, eh?
Uno-Dos-Ultravio-len-to.

después de terminar el libro vi la película del mismo titulo de stanley kubrick.

y acá es donde le doy de comer a los amantes del cine arte para que me bardeen de lo lindo.

me parece muy mala la película.

No soy muy critico de las películas, son películas y listo, o me gustan o no. Normalmente cuando leo el libro antes suelo terminar pensando "el libro esta mejor" pero supongo que es una cosa normal ya que tratar de meter un libro en dos horas es difícil, pero en este caso me pareció definitivamente mala.

ya me había pasado con el mismo director después de leer 2001 odisea del espacio, no pude terminar la película porque me aburrí a los 30 minutos. En ese caso se justificaba porque el libro era puro relato que no se podía llevar a la pantalla fácilmente, pero en el caso de la naranja mecánica esta relatada por el personaje principal así que no tenia una excusa similar.

bue no voy a seguir porque no soy critico de cine (tampoco soy camionero) pero para cerrar, las omisiones, las modificaciones y el hecho que la película termine unos cuantos capítulos antes que el libro justifica al menos mi opinión.

para los amantes del cine arte con ganas de bardear a verdaderos trolls del cine los invito a pasar por el cine apesta :P

jueves, diciembre 30, 2010

an idea

build a couchdb backend for the logger module in emesene 2 so you can have log synchronization between machines.

one step further:

document the design and make it generic for any IM client so people can store all their chat logs in the same database.

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

viernes, octubre 29, 2010

Como generar archivos .exe e instaladores para una aplicación python (y pygtk)

Como generar archivos .exe e instaladores para una aplicación python


Este documento describe los pasos necesarios para crear un archivo ejecutable
de una aplicación python y como generar un instalador y una versión portable
para dicha instalación.

Este documento asume que la aplicación se basa en GTK pero debería funcionar
con menores cambios en otros toolkits.

porque un instalador

  • se requiere instalar muchos componentes a mano por el usuario final para una sola aplicación
  • muchos instaladores pequeños
  • difíciles de encontrar
  • difícil encontrar las versiones exactas que funcionan en conjunto
  • requiere instalarlos en un orden definido
  • rezar
  • algunas veces incluso haciendo todo bien puede no funcionar
  • fácil de automatizar y documentar para replicar con cada nueva versión
  • liberar al usuario final de los problemas para poder usar la aplicación

componentes requeridos

  • python
  • todas las librerías utilizadas por la aplicación
  • py2exe
  • nsis
  • tiempo y suerte

orden de instalación

algunos instaladores son independientes de otros, pero para evitar posibles problemas recomiendo la instalación en el siguiente orden.

  • python
  • gtk-runtime
  • gtk2-themes
  • nsis
  • pygobject
  • pycairo
  • pygtk
  • pywin32
  • py2exe

tareas extra

  • setear la variable de entorno PATH para agregar el path a la instalación de python
  • probar la instalación con una pequeña aplicación gtk
>>> import gtk
>>> w = gtk.Window()
>>> l = gtk.Label("asd")
>>> w.add(l)
>>> w.show_all()
>>> gtk.main()

prueba con una aplicación de ejemplo

Cree un repositorio con una aplicación de ejemplo para probar los pasos, la aplicación esta disponible en github acá:

http://github.com/marianoguerra/PyGtkOnWindows

pasos

  • descargarla
  • descomprimirla
  • ejecutar python setup.py py2exe
  • copiar los directorios lib y share de la instalación del runtime de gtk (no de la instalación de pygtk) al directorio dist
  • copiar todos los archivos del directorio dll al directorio dist
  • borrar los locales y temas no usados de los directorios copiados a dist (yo solo dejo el theme MS-Windows)
  • crear la siguiente estructura de directorios dentro de dist: etc/gtk-2.0
  • dentro de ese directorio crear un archivo llamado gtkrc con una linea como la siguiente dentro:
    • gtk-theme-name = "MS-Windows"
    • podes cambiar el tema usado manteniendo otro theme dentro de share/themes y cambiando el nombre del theme en gtkrc
  • right click en ejemplo.nsi y seleccionar "Compile NSIS Script"
  • right click en ejemplo-portable.nsi y seleccionar "Compile NSIS Script"
  • deberías tener el instalador y la versión portable disponibles
  • para probar que funciona correctamente, correr el instalador y la versión portable en una instalación de windows sin los paquetes que instalaste anteriormente

probar con una aplicación real

ahora para sentirlo mas real, creemos un instalador y una versión portable de
un programa real, en este caso, un proyecto personal llamado emesene 2
(http://www.emesene.org/).

pasos

  • descargarlo de http://github.com/emesene/emesene
  • descomprimirlo
  • copiar setup.py and ez_setup.py al directorio emesene
  • cd emesene
  • correr python setup.py py2exe
  • cd ..
  • copiar los directorios lib y share de la instalación del runtime de gtk (no de la instalación de pygtk) al directorio dist
  • copiar todos los archivos del directorio dll al directorio dist
  • borrar los locales y temas no usados de los directorios copiados a dist (yo solo dejo el theme MS-Windows)
  • crear la siguiente estructura de directorios dentro de dist: etc/gtk-2.0
  • dentro de ese directorio crear un archivo llamado gtkrc con una linea como la siguiente dentro:
    • gtk-theme-name = "MS-Windows"
    • podes cambiar el tema usado manteniendo otro theme dentro de share/themes y cambiando el nombre del theme en gtkrc
  • right click en emesene.nsi y seleccionar "Compile NSIS Script"
  • right click en emesene-portable.nsi y seleccionar "Compile NSIS Script"
  • deberías tener el instalador y la versión portable disponibles
  • para probar que funciona correctamente, correr el instalador y la versión portable en una instalación de windows sin los paquetes que instalaste anteriormente

notas

[EN] How to generate .exe files and installers for a python (and pygtk) applications

How to generate .exe files and installers for a python applications


This document describes the steps required to create an executable file from a
python program and how to build an installer and portable file from that
application.


The document assumes that the application is based on GTK but it should work
with minor changes for other toolkits.

why an installer

  • many components are required to install by hand by the end user for a simple application
  • a lot of small installers
  • hard to find
  • hard to match the exact versions that work together
  • install them in the required order
  • pray
  • sometimes even doing everything right it may not work
  • easy to automate and document to replicate with each new version
  • free the end user from problems to use the app

required components

  • python
  • all the libraries used by the application
  • py2exe
  • nsis
  • time and luck ;)

installation order


some installers are independent from the others, but to avoid posible problems I recommend the installation in this order.

  • python
  • gtk-runtime
  • gtk2-themes
  • nsis
  • pygobject
  • pycairo
  • pygtk
  • pywin32
  • py2exe

extra tasks

  • set the PATH environment variable to add the path to the python installation
  • test that the installation works with a simple gtk application
>>> import gtk

>>> w = gtk.Window()
>>> l = gtk.Label("asd")
>>> w.add(l)
>>> w.show_all()
>>> gtk.main()

test with a sample application


I created a repository with a sample application to test the steps, the application is available in github here:

http://github.com/marianoguerra/PyGtkOnWindows

steps

  • download it
  • unpack it
  • run python setup.py py2exe
  • copy the lib and share directory from the gtk runtime installation (not the pygtk installation) to the dist directory
  • copy all the files from the dll directory to the dist directory
  • remove unused locales and unused themes (I keep only ms theme)
  • create the following dirs inside dist: etc/gtk-2.0
  • inside that create a file called gtkrc with a line like this inside:
    • gtk-theme-name = "MS-Windows"
    • you can change the theme by keeping that theme inside share/themes and changing the name in gtkrc
  • right click on ejemplo.nsi and select "Compile NSIS Script"
  • right click on ejemplo-portable.nsi and select "Compile NSIS Script"
  • you should have the installer and portable versions available
  • to test that it works correctly, run the installer and portable versions in a windows installation without the packages you installed previously

test with a real application

now to make it feel more real let's create an installer and portable versions
for a real world program, in this case, a project of mine called emesene 2
(http://www.emesene.org/).

steps


  • download it from http://github.com/emesene/emesene
  • unpack it
  • copy setup.py and ez_setup.py to the emesene directory
  • cd to emesene
  • run python setup.py py2exe
  • cd ..
  • copy the lib and share directory from the gtk runtime installation (not the pygtk installation) to the dist directory
  • copy all the files from the dll directory to the dist directory
  • remove unused locales and unused themes (I keep only ms theme)
  • create the following dirs inside dist: etc/gtk-2.0
  • inside that create a file called gtkrc with a line like this inside:
    • gtk-theme-name = "MS-Windows"
    • you can change the theme by keeping that theme inside share/themes and changing the name in gtkrc
  • right click on emesene.nsi and select "Compile NSIS Script"
  • right click on emesene-portable.nsi and select "Compile NSIS Script"
  • you should have the installer and portable versions available
  • to test that it works correctly, run the installer and portable versions in a windows installation without the packages you installed previously

notes

viernes, octubre 22, 2010

CouchApp IV: creando funciones show con templates HTML

necesitamos mostrar una entidad en su propia pagina, para eso vamos a necesitar un template html con los valores del documento almacenado en la base de datos, un template es una buena herramienta para eso, veamos como hacerlo en nuestra couchapp


primero creamos la funcion show, esta funcion es llamada para mostrar un documento en algun formato, en nuestro caso html


# generamos la funcion show
couchapp generate show dato
# la editamos con un editor de texto
vim shows/dato.js

en un principio vamos a ver este contenido



function(doc, req) {  
  
}

reemplazamos por algo parecido a esto



function(doc, req) {
    if (doc !== null && doc.name) {
        var ddoc = this,
            Mustache = require("vendor/couchapp/lib/mustache"),
            path = require("vendor/couchapp/lib/path").init(req),
            assetPath = path.asset();

        provides("html", function() {
            return Mustache.to_html(ddoc.templates.dato, {
                assetPath: assetPath,
                doc: doc
            });
        });
    }
    else {
        return "not found";
    }
}

en el codigo controlamos que tenemos un documento, sino mostramos "not found",
tambien creamos algunos objetos que nos ayudan y finalmente renderizamos el template pasandole algunos valores que seran usados dentro del template.


mi template esta en templates/dato.html (por eso ddoc.templates.dato) y contiene un template mustache, mira la documentacion de mustache para mas informacion sobre el formato


la url par acceder a esta funcion es [database]/_design/[app]/_show/[showname]/[docid] un ejemplo podria ser http://localhost:5984/datos/_design/datos/_show/dato/6bd97648d74961996c8f0d42b2005761

[EN] CouchApp IV: creating show functions with html templates

we need to display some entity in its own web page, for that we need to fill an html template with the values of the document stores in the database, a template is a nice fit for this, let's see how we do this in our couchapp


first, create the show function, this is a function that when called displays a document in some format, in our case in HTML


# generate the show function
couchapp generate show dato
# open it with a text editor
vim shows/dato.js

we will see this content



function(doc, req) {  
  
}

we replace the content with something like this



function(doc, req) {
    if (doc !== null && doc.name) {
        var ddoc = this,
            Mustache = require("vendor/couchapp/lib/mustache"),
            path = require("vendor/couchapp/lib/path").init(req),
            assetPath = path.asset();

        provides("html", function() {
            return Mustache.to_html(ddoc.templates.dato, {
                assetPath: assetPath,
                doc: doc
            });
        });
    }
    else {
        return "not found";
    }
}

here we check that we have a document, if not return "not found", also we create some objects that will help us and finally we render the template passing some values that will be used in the template.


my template is located at templates/dato.html (that's why ddoc.templates.dato) and contains a mustache template, see mustache documentation for information about the format


the url to access this function is [database]/_design/[app]/_show/[showname]/[docid] an example could be http://localhost:5984/datos/_design/datos/_show/dato/6bd97648d74961996c8f0d42b2005761

jquery.couch snippets

algunos snippets para hacer tareas comunes en jquery.couch


var datos = {};
datos.db = "datos";

datos.login = function (user, password, okCb, errorCb) {
    $.couch.login({"name": user, "password": password, "success": okCb, "error": errorCb});
};

datos.logout = function (okCb, errorCb) {
    $.couch.logout({"success": okCb, "error": errorCb});
};

datos.checkSession = function (okCb, errorCb) {
    $.couch.session({"success": okCb, "error": errorCb});
};

datos.create = function (data, okCb, errorCb) {
    $.couch.db(datos.db).saveDoc(data, {"success": okCb, "error": errorCb});
};

datos.get = function (id, okCb, errorCb, rev) {
    $.couch.db(datos.db).openDoc(id, {"success": okCb, "error": errorCb, "rev": rev});
};

datos.remove = function (id, rev, okCb, errorCb) {
    $.couch.db(datos.db).removeDoc({"_id": id, "_rev": rev}, {"success": okCb, "error": errorCb});
};

datos.getRecent = function (limit, okCb, errorCb) {
    $.couch.db(datos.db).view("datos/recent-items",
        {"limit": limit, "descending": true, "success": okCb, "error": errorCb});
};

CouchApp III: subiendo los cambios automaticamente

ahora que tenemos todo lo que necesitamos para crear nuestra couchapp, podemos ir al directorio _attachments y empezar a modificar el código para que haga lo que queramos


después de un rato vas a notar que necesitas hacer push de los cambios a couchdb cada vez que queres probarlos, si sos como yo esto se va a poner molesto bastante rápido, hagamos que las herramientas nos ayuden


#install inotify-tools
sudo apt-get install inotify-tools

con inotify tools vamos a correr un script que va a monitorear cualquier cambio de archivos y va a hacer un push cuando eso suceda, voy a excluir los cambios en *.swp ya que vim crea esos archivos y cambian bastante seguido


corre este comando en algún shell y dejalo corriendo


inotifywait -q -e modify -m -r . | while read line; do if echo $line | grep -v .*.swp; then couchapp push; fi; done

ahora edita algún archivo y guardalo, anda al shell donde tenes el script corriendo, vas a ver algo como esto:


./_attachments/ MODIFY index.html
2010-10-22 11:00:48 [INFO] Visit your CouchApp here:
http://wariano:secret@localhost:5984/datos/_design/datos/index.html

ahora podes editar tus archivos y los cambios van a ser automáticamente subidos a couchdb

[EN] CouchApp III: pushing the changes automatically

now we have all we need to start creating our couchapp, go to the _attachments directory and start modifying the code to do what you want


after a moment you will notice that you need to push the changes to couchdb each time you want to test it, if you are like me this will get annoying pretty fast, let's make the tools help us


#install inotify-tools
sudo apt-get install inotify-tools

with inotify tools we will run a script that will monitor any file change and make a couchapp push when that happens, I will exclude the changes in *.swp files since vim create those and they change pretty often


in some shell run this and leave it running


inotifywait -q -e modify -m -r . | while read line; do if echo $line | grep -v .*.swp; then couchapp push; fi; done

now edit some file and save it, go back to the shell where the script is running, you should see something like:


./_attachments/ MODIFY index.html
2010-10-22 11:00:48 [INFO] Visit your CouchApp here:
http://wariano:secret@localhost:5984/datos/_design/datos/index.html

now you can edit your files and the changes will be pushed automatically to couchdb

CouchApp II: arreglando la fiesta de admins

ahora que tenemos nuestra aplicacion corriendo podemos ver que hay un problema con la demo, no tenemos autenticacion, por default couchdb esta en modo "fiesta de admins", para leer mas sobre la fiesta de admins en couchdb podes leer Couchdb the definitive guide


para arreglarlo necesitamos usar futon (el panel administrativo de couchdb) y crear el primer admin


anda a futon con tu browser a http://localhost:5984/_utils/index.html


abajo a la derecha de la pagina deberias leer algo como "Welcome to Admin Party! Everyone is admin. Fix this", hace click en el link y crea el primer admin


voy a crear el admin como "wariano" y como password "secret", cuando veas esto deberías cambiarlo por tu usuario y password


si intentamos hacer push de nuestra couchapp de nuevo vamos a obtener un error que nos dice que no estamos autorizados, esto es porque necesitamos proveer usuario y contraseña para modificar la base de datos ahora, para hacer esto vamos a editar el archivo .couchapprc de nuevo para agregar el usuario y contraseña


edita la url de


http://localhost:5984/datos

a


http://wariano:secret@localhost:5984/datos

intenta hacer push de nuevo, debería funcionar. Intenta usar la demo de nuevo usando tu usuario y contraseña

[EN] CouchApp II: fixing the admin party

now that we have our app running we can see a problem in the demo, we don't have authentication, and by default couchdb is in "admin party" mode, read more about the admin party in Couchdb the definitive guide


to fix this we need to go to futon (the admin panel of couchdb) and set up the first admin


go to futon pointing your browser to http://localhost:5984/_utils/index.html


at the bottom right corner of the page you should read something like "Welcome to Admin Party! Everyone is admin. Fix this", click on the link and set the first admin


I will create the admin as "wariano" and password "secret", whenever you see that change for your user and password


if we try to push our couchapp again we will get an unauthorized error, that's because we need to provide credentials to modify the database now, to do this we will edit the .couchapprc again to add the user and password


edit the url from


http://localhost:5984/datos

to


http://wariano:secret@localhost:5984/datos

and try pushing again it should work now, try the demo again using your user and password

CouchApp I: instalando el entorno

vamos a empezar nuestra couchapp instalando el entorno, para eso necesitamos instalar couchapp y couchdb


# instalar couchdb y los modulos de python para poder instalar otros modulos
sudo apt-get install python-setuptools couchdb
# descargar pip
curl -O http://python-distribute.org/distribute_setup.py
sudo python distribute_setup.py
sudo easy_install pip
# instalar couchapp
sudo pip install couchapp

ahora que tenemos couchapp vamos a generar nuestro proyecto, vamos a llamarlo "datos"


couchapp generate datos
cd datos
# editamos el archivo couchapprc
vim .couchapprc

el archivo .couchapprc contiene los destinos donde vamos a instalar nuestra aplicación, definamos el target por defecto


{"env": {
  "default": {
   "db": "http://localhost:5984/datos"
  }
 }
}

guardar el contenido y correr


couchapp push

deberia mostrar algo como lo siguiente:


2010-10-22 10:21:10 [INFO] Visit your CouchApp here:
http://localhost:5984/datos/_design/datos/index.html

ahora anda a esa URL con tu browser, deberías ver la pagina de demostración.

[EN] CouchApp I: setting up the environment

we will start our couchapp setting up the environment, for that we will install couchdb and couchapp


# install couchdb and python modules to install other modules
sudo apt-get install python-setuptools couchdb
# download pip
curl -O http://python-distribute.org/distribute_setup.py
sudo python distribute_setup.py
sudo easy_install pip
# install couchapp
sudo pip install couchapp

now that we have couchapp we will generate our project, we will call it "datos"


couchapp generate datos
cd datos
# edit the couchapprc file
vim .couchapprc

the .couchapprc file contains the targets where we can deploy our application, let's define the default target


{"env": {
  "default": {
   "db": "http://localhost:5984/datos"
  }
 }
}

save the content and run


couchapp push

it should display something like the following:


2010-10-22 10:21:10 [INFO] Visit your CouchApp here:
http://localhost:5984/datos/_design/datos/index.html

now go to that site with your browser, you should see a demo page.

miércoles, octubre 20, 2010

hola mundo web con flask y mod_wsgi sobre apache2

necesitaba levantar una aplicación simple usando flask y mod_wsgi sobre apache para ver si encuentro la causa de un error en una aplicación un poco mas compleja y decidi ya que estoy documentarlo por si le es útil a alguien (en el futuro me va a ser útil a mi cuando me olvide ;)

empecemos con un poco de bash para establecer el ambiente

# creamos el directorio donde vamos a tener nuestro código
mkdir site
cd site

# bajamos los módulos que vamos a usar
wget http://pypi.python.org/packages/source/F/Flask/Flask-0.6.tar.gz
wget http://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.5.5.tar.gz
wget http://pypi.python.org/packages/source/W/Werkzeug/Werkzeug-0.6.2.tar.gz

# instalar los paquetes necesarios
sudo apt-get install libapache2-mod-wsgi curl

# desempaquetamos
tar -xzf Flask-0.6.tar.gz
tar -xzf Werkzeug-0.6.2.tar.gz
tar -xzf Jinja2-2.5.5.tar.gz

# creamos enlaces simbólicos a las bibliotecas
ln -s Flask-0.6/flask/
ln -s Werkzeug-0.6.2/werkzeug/
ln -s Jinja2-2.5.5/jinja2/

ahora con tu editor favorito (osea vim ;)

vim server.py

escribí lo siguiente

import flask

app = flask.Flask(__name__)

@app.route("/")
def index():
    return "hello world!"

if __name__ == '__main__':
    app.run(host="127.0.0.1", debug=True)


probemos lo que tenemos hasta ahora

# levantamos el server de desarrollo
python server.py &

# probamos traer la pagina principal
curl http://localhost:5000/

# matamos el server
kill %

esto debería andar, ahora vamos con la parte de apache, con tu editor favorito edita un archivo llamado server.wsgi con el siguiente contenido, tené en cuenta de cambiar el path al directorio tuyo, tiene que ser un path absoluto.

import os
import sys

sys.path.insert(0, "/home/wariano/code/site/")

from server import app as application

ahora necesitamos crear nuestro sitio dentro de apache

sudo vim /etc/apache2/sites-available/flask

este es el contenido del archivo, tene en cuenta de cambiar todos los "wariano" por el nombre de usuario que va a correr el proceso. también podes renombrar flask por el nombre de tu proyecto, tené en cuenta de también hacerlo en los otros lugares.

<virtualhost *>
    ServerName localhost

    WSGIDaemonProcess wariano user=wariano group=wariano threads=5 processes=5
    WSGIScriptAlias / /var/www/flask/server.wsgi

    LogLevel info
    ErrorLog /var/log/apache2/flask-error.log
    CustomLog /var/log/apache2/flask-access.log combined

    <directory /var/www/flask>
        WSGIProcessGroup wariano
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>


# creamos el directorio donde apache va a buscar nuestro script
sudo mkdir -p /var/www/flask
cd /var/www/flask/
# linkeamos al script en nuestro directorio (cambia el path al tuyo)
sudo ln /home/wariano/code/site/server.wsgi
# activamos nuestro sitio
sudo a2ensite flask
# desactivamos el sitio por default (no lo desactives si tenes algo andando,
# vas a tener que cambiar alguna configuración en el sitio de flask si haces esto)
sudo a2dissite default
# reiniciamos apache
sudo /etc/init.d/apache2 restart

# probamos que el sitio ande
curl http://localhost/

y voila! un sitio andando en python sobre apache, si nos queremos poner a jugar y correr un benchmark para medir vaya a saber que podemos usar el benchmark de apache

# instalamos las utilidades de apache
sudo apt-get install apache2-utils
# corremos el apache con 100 conexiones y 20 conexiones concurrentes
ab -n 100 -c 20 http://localhost/

domingo, octubre 17, 2010

material de charlas de PyConAr2010

mediante la presente hago disponibles los recursos utilizados en las charlas dadas por quien les escribe en el contexto de PyConAr 2010.


las anteriormente mencionadas se encuentran en un repositorio de git en github lo cual permitirá seguir el repositorio y ser notificado en caso de que alguna sea modificada o nuevas charlas sean agregadas.


el repositorio se encuentra aquí: http://github.com/marianoguerra/talks/tree/master/PyConAr2010/


para su mayor comodidad publico las charlas aquí.



por ultimo cumpliendo con mi promesa publico el código utilizado durante la charla click click, tu aplicación python en windows a un doble click de distancia, el mismo se encuentra como es de esperar en github aquí: http://github.com/marianoguerra/PyGtkOnWindows


promulgese, difundase y archivese

que semanita

miercoles Rage Against The Machine y Queens of the Stone Age en el Pepsi music, viernes y sabado PyConAr 2010 en Córdoba.

RATM fue impresionante, el mejor recital al que haya ido, el pogo fue lo mas groso que he visto, lo que se saltaba, los moshpits y encima de todo fuera de algunos golpes todos bastante respetuosos. Algo así como artistas del pogo :D

no se si es que escucho RATM hace mucho o que pero los temas elegidos fueron espectaculares y tocaron muy bien.



queens of the stone age también estuvo muy bueno aunque obviamente por el estilo fue un poco mas tranqui, los temas elegidos también estuvieron muy buenos y la banda sonó muy bien, mas que recomendable.



y por ultimo, el PyConAr 2010 en córdoba, acá no hubo mucho pogo pero no por eso no dejo de estar espectacular, la organización muy bien, las charlas mas que buenas, los lightning talks muy divertidos e informativos y lo mejor de todo es juntarse a charlar con gente grosa, divertida y recontra humilde.

esperando el a~no que viene por la próxima.

miércoles, octubre 13, 2010

compilando un paquete desde las fuentes en ubuntu/debian

para una cosa necesitaba agregar una columna con el timestamp a la salida de vmstat por lo que necesitaba el codigo y el entorno para modificarlo y recompilarlo.

despues de un poco de busqueda resulto ser bastante facil.

# donde esta vmstat?
$ which vmstat
# quien provee vmstat?
$ dpkg -S /usr/bin/vmstat
# traeme las fuentes de procps
$ apt-get source procps
# traeme las dependencias para construir procps
$ sudo apt-get build-dep procps
# vamos al directorio
$ cd procps-3.2.8/
# edicion furiosa de código
$ vim vmstat.c
# compilamos el codigo
make
# probamos nuestra creacion
$ vmstat -n 1

y voila!

martes, octubre 12, 2010

Si lo dice Trent Reznor... :P

if as many people really listened to Joy Division as list them on their Facebook page, Joy Division would be bigger than U2. That sense of, here’s the books I’m supposed to have read for the social archetype I want to fit into, so I’ll portray myself this way

Trent Reznor on Why Facebook "Sucks"

lunes, septiembre 20, 2010

gente que implementa en android cosas que uno hace

gracias a los aportes de don mateo bengualid la creciente comunidad (?) de repioleros podra disfrutar de su aplicacion favorita (?) en android.

a las pruebas me remito.





gracias a mateo por los aportes.

domingo, septiembre 19, 2010

*sensacion* de inseguridad

La capital argentina es la segunda ciudad más segura de las Américas, sólo superada por Toronto, Canadá. La tasa de homicidios del país es la cuarta más baja del continente y cayó casi un 40 por ciento desde 2002.

http://www.pagina12.com.ar/diario/elpais/1-153423-2010-09-19.html


Uno de los datos más curiosos del informe –un adelanto de las cifras oficiales que se conocerán en pocos días más– es la diferencia que existe entre lo que comúnmente se llama “sensación de inseguridad” y los datos que señalan las estadísticas reales. Una encuesta de victimización realizada en 2088 por Lapop (Latin American Public Opinion Project), precisó que la Argentina encabeza la compulsa, porque el 27,47 por ciento de los consultados afirman sentirse “inseguros” por haber sido víctimas de algún delito. El segundo lugar lo ocupa Chile (22,23) y el tercero Uruguay (22,04). Sin embargo, las cifras oficiales de esos tres países, del mismo año, señalan que los tres son los que tienen las tasas más bajas de homicidios: Chile (1,60), Argentina (5,30) y Uruguay (6,60).

De todos modos, en el caso de Chile, donde la tasa oficial es de 1,6 casos cada cien mil habitantes, se aclaró que hasta 2008 las cifras tuvieron como fuente el Ministerio del Interior, que releva datos del cuerpo de Carabineros. En el año 2009, el Ministerio Público de Chile (fiscalías), informó sobre un total de casos de homicidio que se traduciría en una tasa de 9,1 homicidios cada cien mil habitantes. “Esto indicaría que Argentina sólo tendría tasas más altas que Estados Unidos y Canadá”, explicó la fuente consultada por este diario.

obviamente son estadisticas y no hay que creerles del todo, pero si son ciertas...
Q. How do you stay on top of technology trends and innovation? 

A. Talk to people you respect and ask them what they're doing and what is interesting. Then read about those topics. When it makes a sense, you learn a lot more by actually doing a project in an area than by reading about it.

Q. Time management … technical leaders and executives are famous for being time-strapped. What strategies do you use to stay sane and use your time effectively?

A. Do the things that matter, stop doing the things that don't, and continuously examine your use of time so that you can tell the difference. Don't waste time on something just because that's the way it has been done.


-- Peter Norvig

viernes, septiembre 17, 2010

Se viene PyCon Argentina 2010

ya salio el schedule de charlas de pycon argentina 2010 y tengo el gusto de participar con 2 charlas.

acá esta el cronograma completo.

que haces que no reservaste los días para venirte a la docta al pycon?

domingo, septiembre 12, 2010

la sabiduria del pasado

después de escribir el post anterior me puse a buscar en mi blog cuantas veces hice comentarios fanáticos (tengo algunos en mente pero quería asegurarme de que no hubiera (o hubiese?) mas), encontre un post que resume el post anterior en una sola fase.

But there is a step beyond thinking of yourself as x but tolerating y: not even to consider yourself an x. The more labels you have for yourself, the dumber they make you.

ya lo dijo Pascal, el hombre nombrado en honor al lenguaje de programación (?)

I have made this letter longer than usual because I lack the time to make it shorter.

en mi caso me faltaba el tiempo y la sabiduría :D

humano meta

resulta que cometi el error de ponerme a leer comentarios de los siguientes eventos deportivos y otros:

  • argentina vs españa en futbol
  • argentina vs españa en basquet
  • argentina vs brasil en basquet
  • muchos partidos "chivos" del mundial de futbol
  • comentarios en youtube (OMG)
en diarios online de argentina y del otro pais.

TL;DR: anda hasta abajo para links con ejemplos.

me llevo a la conclusión de que me canse de las discusiones de "nosotros vs ustedes" y el interminable listado de razones por las cuales "nosotros somos mejores que ustedes" o bajar al simple "te denigro porque no sos como nosotros".

si no encontraste el patrón todavía el "nosotros vs ustedes" también me canso en otros ambientes como:

  • lenguajes de programación
  • sistemas operativos
  • licencias de software
  • frameworks
  • editores de texto
  • desktops
  • marcas de cualquier producto comercial
  • bandas musicales
  • carreras universitarias
  • metodologias de desarrollo
  • equipos de futbol
  • partidos políticos
  • religión
  • habitos alimenticios
  • preferencias sexuales
  • hobbies o como uso mi tiempo libre
y un largo etc que quizás siga completando.

para evitar este stress, debido a que por defecto con cada elección me pongo de un lado de la pelea, de ahora en mas me propongo definirme en terminos "meta".

Soy programador de unos cuantos lenguajes de programacion, elegi esos porque como vos elegiste los tuyos me interesaron de una forma u otra, como todos los lenguajes de programacion tienen sus ventajas y desventajas, si estas dispuesto a tener una conversacion centrada sobre el tema podemos analizar *en funcion de preferencias personales y totalmente subjetivas* porque elegí los que elegi, sino, por el bien de ambos, dejemos el tema de lado y charlemos de cualquier otra cosa.

reemplaza programador y lenguajes de programación por otros valores y vas a tener un template :P


En cuanto a las cosas que no puedo elegir, sino que soy, como nacionalidad o preferencias que resultan de algo que no puedo explicar racionalmente, dejemoslo en que es accidental y al igual que antes si querés que hablemos de las cosas que nos gustan y no nos gustan todo bien, si querés competir para ver cual es mejor, para eso están los comentarios de youtube.

Es muy difícil evitar ser trolleado y entrar en una discusión y mantenerse racional pero voy a intentarlo, para que esto quede mas allá de un post en un blog totalmente efímero cree una pagina que me permite recordarlo y distribuirlo fácilmente en una discusión para volver quizas a la recionalidad o establecer de forma simple y generica mi posicion.

la llamo la ley de wariano, esta basada en la ley de jante pero generalizada para que encaje en muchas cosas.

la instancia por defecto se refiere a países, porque es el tipo de discusión que mas me enerva pero puede ser parametrizado con lo que quieran.

les dejo unos ejemplos (por ahora en ingles porque es mas generica :P)

etc etc.

espero que sea útil :P

aclaracion, no creo que este en este nivel de "iluminacion", solo es un esfuerzo para evitar ponerme del lado "de los mejores" por preferencias o pertenencia a cierto grupo.

Intentare aplicarlo en lo que pueda y exponer mis preferencias de una forma centrada, lo que no implica que alguna vez no cumpla con mi propia ley :P.

por ultimo aclarar que esto no me convierte en un ser totalmente apático, festejare las victorias de los equipos o grupos a los que pertenezco, disfrutare los beneficios y ventajas que mis elecciones tengan, pero siempre evitando agredir a "los del otro bando".

miércoles, septiembre 01, 2010

martes, agosto 24, 2010

repiola 0.6: jump a direcciones, call, ret y compilacion

para darle un cierre a esta idea que tuve alguna vez, implemente lo que faltaba para considerar el proyecto "terminado", lo unico que puede llegar a faltar es UIs mas copadas (como guardar programas etc.)

en esta release agregue soporte para saltar a una direccion almacenada en un registro:

set r2 2
jmp r2

salta a la direccion 2

call y ret permiten simular rutinas, call empuja el instruction pointer al stack y salta al label especificado, ret saca la direccion del stack y salta a ella:

jmp begin

: donothing
ret

: begin
call donothing

con estas features ya no hay muchas cosas que no se puedan hacer.

y para cerrar ahora cuando ejecutas un programa lo compila a bytecode y despues la maquina virtual ejecuta el bytecode directamente, hasta ahora las instrucciones eran compiladas a bytecode pero el manejo de los saltos era manejado por la clase Interpreter.

esto da una mejora de velocidad considerable para mi pobre celular (el mas barato con j2me :D)

en la pagina http://code.google.com/p/repiola/ se encuentran los jars y documentacion de todas las instrucciones.

domingo, agosto 22, 2010

un poco de dylan



Come gather 'round people
Wherever you roam
And admit that the waters
Around you have grown
And accept it that soon
You'll be drenched to the bone.
If your time to you
Is worth savin'
Then you better start swimmin'
Or you'll sink like a stone
For the times they are a-changin'.

Come writers and critics
Who prophesize with your pen
And keep your eyes wide
The chance won't come again
And don't speak too soon
For the wheel's still in spin
And there's no tellin' who
That it's namin'.
For the loser now
Will be later to win
For the times they are a-changin'.

Come senators, congressmen
Please heed the call
Don't stand in the doorway
Don't block up the hall
For he that gets hurt
Will be he who has stalled
There's a battle outside ragin'.
It'll soon shake your windows
And rattle your walls
For the times they are a-changin'.

Come mothers and fathers
Throughout the land
And don't criticize
What you can't understand
Your sons and your daughters
Are beyond your command
Your old road is
Rapidly agin'.
Please get out of the new one
If you can't lend your hand
For the times they are a-changin'.

The line it is drawn
The curse it is cast
The slow one now
Will later be fast
As the present now
Will later be past
The order is
Rapidly fadin'.
And the first one now
Will later be last
For the times they are a-changin'.

de yapa

sábado, agosto 21, 2010

clear screen y stack en repiola (+ 400 posts)

a pedido de j0hn, el único usuario de repiola agregue soporte para limpiar la pantalla y stack en repiola.

para limpiar la pantalla se usa la instrucción clr con el color a usar para limpiar la pantalla, ya sea como un literal o con el nombre del registro donde esta el color:

# limpiar la pantalla con rojo
clr 0b111110000000000

# limpiar la pantalla con el color en r2 (verde)
set r2, 0b000001111100000
clr r2

el stack es como uno se esperaria

push 4
set r1, 8
push r1
pop r2
# r2 == 8

pop r2
# r2 == 4


a esta altura se están preguntando que demonios es repiola?

es un programita que interpreta un lenguaje muy parecido a assembly 80x86 que permite dibujar cosas en algo similar a un canvas, tiene implementación desktop (swing), mobile (j2me) y web (cortesia de j0hn y frutillita).

como nota adicional, este es el post numero 400 de este log personal, vino Ian Curtis y trajo pepsi.

domingo, agosto 15, 2010

MIentras tanto en escandinavia

Jante Law

From Wikipedia, the free encyclopedia
The Jante Law (Danish and Norwegian: Janteloven; Swedish: Jantelagen; Finnish: Janten laki; Faroese: Jantulógin) is a pattern of group behaviour towards individuals within Scandinavian communities, which negatively portrays and criticizes success and achievement as unworthy and inappropriate.
It has been observed as a form of behaviour for centuries, but the Norwegian/Danish author Aksel Sandemose identified it as a series of rules, the Jante Law, in his novel A fugitive crosses his tracks (En flyktning krysser sitt spor, 1933, English translation published in the USA in 1936). Sandemose's novel portrays the small Danish town Jante (modelled upon his native town Nykøbing Mors as it was at the beginning of the 20th century, but typical of all very small towns), where nobody is anonymous.[1]
Generally used colloquially as a sociological term to negatively describe an attitude towards individuality and success claimed to be common in Scandinavia, it refers to a supposed snide, jealous and narrow small-town mentality which refuses to acknowledge individual effort and places all emphasis on the collective, while punishing those who stand out as achievers.
The term may be used by those individuals who feel they are not allowed to take credit for their achievements, or to point out their belief that another person is being overly critical.

Definition

There are ten different rules in the law as defined by Sandemose, but they all express variations on a single theme and are usually referred to as a homogeneous unit: Don't think you're anyone special or that you're better than us.
The ten rules state:
  1. Don't think that you are special.
  2. Don't think that you are of the same standing as others.
  3. Don't think that you are smarter than others.
  4. Don't fancy yourself as being better than others.
  5. Don't think that you know more than others.
  6. Don't think that you are more important than others.
  7. Don't think that you are good at anything.
  8. Don't laugh at others.
  9. Don't think that any one of us cares about you.
  10. Don't think that you can teach others anything.
A further rule recognised in the novel is: 11. Don't think that there is anything we don't know about you.
In the book, those Janters who transgress this unwritten 'law' are regarded with suspicion and some hostility, as it goes against communal desire in the town to preserve social stability and uniformity.

martes, agosto 10, 2010

me uni a flattr

me uni a flattr me parece una opcion interesante para "premiar" a la gente que hace cosas interesantes en internet, ya le cargue unos euros y me puse a premiar a los proyectos de software libre que me parecian interesantes (y que estaban inscriptos)

por ahora mis flattrs fueron para:

* bottle (micro framework web en python)
* duck duck go (buscador)
* alien (rpm <-> deb)
* piratepad.net (lo uso de vez en cuando)
* Project Hamster the GNOME Time Tracker (porque es el unico proyecto gnome que encontre, a ver si algunos mas se unen :D)
* Lightspark
* dpkg (a este tendria que darle muchos flattrs :D)

ya que estabamos los agregue mis proyectos (emesene y efene) a ver que sale de esto.

si me genera confianza y no termina todo en un fiasco ire subiendo mis aportes para apoyar de una forma simple a las cosas que me interesan.

si a alguien le interesa me quedan dos invitaciones.

lunes, agosto 02, 2010

el dia que...

el dia que me acuerde cual es useradd y cual es adduser y me acuerde el orden de los parámetros en ln voy a subir un level en la vida.

-- yo

domingo, agosto 01, 2010

aguante restructured text (aka rst2man FTW)

estaba escribiendo la documentación del frontend del compilador de efene en restructured text (en que otra cosa podria uno escribir documentacion? ;) y pensé:

"que bueno que estaría generar el man page desde rst"

un google despues:

Generating Man Pages From reStructuredText

nota: no tienen que instalar nada, al menos en mi maquina rst2man ya esta disponible.

jueves, julio 29, 2010

que grande dolina

en una entrevista a Richard Stallman le preguntan que libros le gustan, una parte de lo que contesta es:

In other areas of fiction, I have enjoyed Jane Austen and Paul Auster,
Lewis Carroll and Edgar Allen Poe, among others. In Spanish, Jorge
Luis Borges, Arturo PÃrez Reverte (especially La Carta EsfÃrica and El
Club Dumas), and Alejandro Dolina.

http://blog.reddit.com/2010/07/rms-ama.html

nado sincronizado y riesgo pais

Mr. A: esta semana escuche / lei las palabras Inflacion y Riesgo Pais un par de veces
Yo: alla?
Mr. A: si
Yo: lololol
Mr. A: sisi
Mr. A: !!!1!!12oneEleven!!1!
Yo: (son tres personas levantando los brazos)
Mr. A: fourteeeen 
Yo: esto es nado sincronizado
Yo:  \o\
Yo: |o|
Yo: /o/
Yo: \o/
Yo: \o_
Yo: _o/
Yo: y asi...
Mr. A: sale gif
Mr. A: o script de bash
Yo: ahi va
Yo: http://marianoguerra.com.ar/random/nado.ogv

codigo:

import sys
import time
import random

ARM = ['\\', '_', '/', ' ']

def figure():
    fig = random.choice(ARM) + "o" + random.choice(ARM)
    sys.stdout.write(fig)
    sys.stdout.flush()

def erase():
    sys.stdout.write("\b\b\b")
    sys.stdout.flush()

def dance():
    while True:
        figure()
        time.sleep(0.5)
        erase()

if __name__ == '__main__':
    dance()

PD: "alla" es españa

recomendado gtk-recordmydesktop

sábado, julio 24, 2010

Desde el oeste - Almarfuerte

Python en Google

Where is Python used?

  • The Google build system is written in python.  All of Google's corporate code is checked into a repository and the dependency and building of this code is managed by python.  Greg mentioned that to create code.google.com took about 100 lines of python code.  But since it has so many dependencies, the build system generated a 3 megabyte makefile for it!
  • Packaging.  Google has an internal packaging format like RPM.  These packages are created using python.
  • Binary Data Pusher.  This is the area where Alex Martelli is working, on optimizing pushing bits between thousands of servers
  • Production servers.  All monitoring, restarting and data collection functionality is done with python
  • Reporting.  Logs are analyzed and reports are generated using Python.
  • A few services including code.google.com and google groups.  Most other front ends are in C++ (google.com) and Java (gmail).  All web services are built on top of a highly optimizing http server wrapped with SWIG.
fuente
Some findings on how language can affect thinking.

* Russian speakers, who have more words for light and dark blues, are better able to visually discriminate shades of blue.

* Some indigenous tribes say north, south, east and west, rather than left and right, and as a consequence have great spatial orientation.

* The Piraha, whose language eschews number words in favor of terms like few and many, are not able to keep track of exact quantities.

* In one study, Spanish and Japanese speakers couldn't remember the agents of accidental events as adeptly as English speakers could. Why? In Spanish and Japanese, the agent of causality is dropped: "The vase broke itself," rather than "John broke the vase."

fuente

sábado, julio 17, 2010

Seguidores

Archivo del Blog