Developing Frogtek

El blog del Departamento de Tecnología

Categoría: python (página 1 de 2)

R, rPython y ggplot2. Un poco de trabajo en equipo

Me llamo Jesús Armand y desde hace unos meses formo parte del equipo de Frogtek como científico de datos. Desde mi llegada, la compañía ha comenzado a utilizar nuevas herramientas en su día a día. Es por ello que a partir de ahora intentaré escribir sobre trucos, pequeños tutoriales o problemas con los que nos encontremos.

Cuando se trabaja con datos, a veces nos encontramos con la necesidad de ejecutar distintos códigos o comandos en diferentes herramientas. Por ejemplo, podemos estar trabajando con una base de datos en MySQL para extraer cierta información que queremos filtrar con algún método implementado en Python y ese resultado representarlo en un gráfico utilizando el paquete ggplot2. Resulta engorroso el proceso de crear, guardar y volver a abrir un fichero en las distintas etapas del proceso.

Es por ello que R a veces nos ayuda a simplificar todas estas tareas y a hacerlas más sencillas. Por ejemplo, con el paquete RMySQL podemos conectarnos de forma rápida con nuestra base de datos y realizar las consultas directamente desde la consola de R y guardar los resultados para, posteriormente, trabajar con el paquete rPython, creado por Carlos Gil Bellosta. En él podremos llamar fácilmente a las funciones desarrolladas en código Python y, finalmente, con las variables almacenadas en nuestro workspace en R, representar gráficamente la información que deseábamos en un principio con ggplot2.

Hoy nos centraremos en un pequeño ejemplo para interactuar con estos dos últimos paquetes: rPython y ggplot2.

El ejemplo va a consistir en, dado un vector con 83 valores, utilizar el método MADe para la detección y eliminación de valores extremos implementado en Python y representar el resultado en un histograma con el paquete ggplot2. El fichero datos-ejemplo- tiene los datos que necesitaremos. Os animo a que implementéis vosotros el código en Python.

Si no tenemos instalados en R los paquetes que necesitamos, ejecutaremos:

install.packages("rPython") 
install.packages("ggplot2")

Los paquetes en R se cargan de la siguiente forma:

library("rPython")
library("ggplot2")

El primer paso será indicar a R con qué fichero .py vamos a trabajar. Para ello ejecutaremos el comando:

python.load("statistical_formulas.py" )

donde el atributo es el nombre del fichero que contiene nuestra función (o funciones).

La función que hemos definido necesita de una sola variable con datos en la llamada. En este caso será el vector X:

python.call("remove_outliers_MADe_method", X)

donde el primer argumento es el nombre la función/método que tenemos en nuestro código y el segundo atributo es nuestro vector.

El resultado de la ejecución de esta llamada lo almacenaremos en la variable resultado.

Finalmente, sólo nos quedará invocar la función gplot() en ggplot2 para representar gráficamente un histograma:

qplot(resultado, geom="histogram")

Como habéis visto, el procedimiento es muy sencillo. Ahora, os animo a que implementéis vosotros mismos el algoritmo MADe para comparar el resultado.

Observer para compilar automáticamente cada vez que guardas

Los que hayan usado el ndk, me comprenderan. La cuestión es que cada vez que quieres hacer un cambio tienes que compilar la librería. A veces resulta muy pesado, ya que después de esto tienes que limpiar y construir tu proyecto Android que usa dicha librería. Un proceso la mar de ligero si tu proyecto es mínimamente grande.

Tras llevar un tiempo trabajando con esto pensé que sería interesante tener un observer que escuche y que compile el proyecto cada vez que guarde. Ya sólo me tendré que preocupar de hacer los pasos pertinentes en Eclipse para construir el apk con la librería recién compilada.

Para hacer esto elegí python, ya que es un lenguaje realmente potente y fácil de ejecutar desde la consola. Tras buscan un poco opté por usar WatchDog, que es una librería que observa cambios en un fichero. Solo hay que escuchar y cuando se realice la acción de grabar lanzar la compilación. Se ha programado para que escuche cambios en un directorio entero, puedes cambiar para limitar al fichero con el que estés trabajando.

Os dejo el código en github. Es muy sencillo de usar y muy potente.

La mejora más inmediata que se me ocurre es poder mostrar visualmente si la compilación ha ido bien o mal.

Comentarios? Sugerencias?

Google App Engine: Lanzar un MapReduce desde un Cron (Segunda Parte)

Hace más de un año, Alberto nos explicaba cómo lanzar un MapReduce desde un Cron en Google App Engine. Desde entonces ha llovido mucho. Google App Engine ha evolucionado y madurado, trayéndonos mejor documentación y una comunidad más activa.

Gracias a ello he podido encontrar una solución más sencilla que la que os ofrecímos en nuestro último post al respecto. Digamos que queda mucho más sencillo 😛

from mapreduce import control
 
mapreduce_id = control.start_map(
"My Mapper",
"main.my_mapper",
"mapreduce.input_readers.DatastoreInputReader",
{"entity_kind": "models.MyEntity"},
shard_count=10)

Cuidado con el shard_count. Aseguraos que corresponde con el que tenéis configurado en vuestra aplicación.

 

BDD en Google App Engine con Lettuce y Splinter (I)

Hemos de reconocerlo: tenemos mucho que aprender en lo que se refiere a programación de pruebas automáticas en la web. Hace ya bastante tiempo que veníamos usando Selenium , primero grabando las pruebas con su IDE, más tarde programándolas con Web Driver. Pero los tests resultantes eran frágiles y aburridos de programar, por lo que sentíamos bastante envidia de los developers Ruby con su flamante Cucumber y sus elegantes tests BDD.

Decidimos remediarlo y Julio se puso con la instalación de  Cucumber + Capybara en el servidor, creando un test de demo y animándonos a montar el entorno en nuestras máquinas para comenzar a darle poquito a poco. Teníamos que aprender Ruby y conocer cómo funcionan sus versiones y conceptos nuevos como RubyGems, por lo que la cosa iba a ser divertida pero no rápida y por ello se nos ocurrió darle una oportunidad a una herramienta que nos sonaba de oídas: Lettuce, combinándola con otra herramienta bastante nueva: Splinter, de manera que, en lugar de pepinos y capibaras:
Siempre es verano con el pepino en la mano

tendremos lechugas y poder mutante. ¡Cowabunga!

Lettuce permite definir test de aceptación automáticos para proyectos Python, y Splinter proporciona un API sencilla y potente para implementar los pasos de los tests usando diferentes webDrivers.

De momento parece que aún falta que ambos proyectos mejoren un poco ya que son relativamente recientes. En el caso de Splinter, si no llega a darnos todo el potencial que necesitamos, siempre podemos sustituirlo por twill, selenium, webdriver o windmill.

¿Por qué usar estas herramientas quizás no tan maduras como sus homólogas del mundo Ruby? Una razón discutible – aprender un nuevo lenguaje siempre es divertido y enriquecedor – es que no nos obliga a aprender Ruby y nos permite definir los pasos en Python con el que estamos mucho más cómodos. Pero la ventaja principal es que tenemos una librería Python usada en nuestros tests de integración para crear diferentes escenarios de test en GAE y esta solución nos permite aprovechar todo su potencial instantáneamente. Bueno, eso si conseguimos instalar correctamente todo lo necesario para rular estas herramientas con GAE.

En Frogtek ninguno tenemos experiencia con Django más allá de su integración con Google App Engine, por lo que seguramente nos falte algo de familiaridad con ciertos conceptos que no aplican dentro de la plataforma de Google. Es quizás por esto por lo que nos encontramos con bastantes problemas de instalación y configuración que nos gustaría compartir con todos aquí. Eso será en el próximo post.

Katas diarias

Hace unas semanas se nos ocurrió retomar el tema de las Katas, y digo retomar porque hace un tiempo nos dio por hacer Katas una vez a la semana. Esta vez fue diferente, en vez de hacerlo con tanto tiempo de diferencia, nos planteamos hacerlas diariamente. En eso consiste la Kata, ¿no? en practicar, practicar y practicar.

Así pues, empezamos Julio, Pedro y yo con Katas diarias (más adelante se uniría Javier Martínez a la fiesta). Cada uno de nosotros se propuso un objetivo concreto con dichas Katas:

* Julio pretende mejorar su rapidez de desarrollo en Eclipse, aprendiendo teclas rápidas y trucos del IDE

* Pedro se propuso aprender emacs y mejorar su programación en este entorno (¡¡y vaya si lo está haciendo!! Ayer me enseñó unas cosas espectaculares, pero creo que eso se merece otro post)

* Yo, por otro lado, me propuse aprender Vim.

Y todos haríamos la Kata en un lenguaje diferente al que estamos habituados, en este caso, Python.

Cada semana elegíamos una Kata del repositorio de 12meses12katas y durante esa semana trabajábamos durante 25 minutos en esa Kata. Una vez pasado el tiempo, mostrábamos a los compañeros el código realizado y lo comentábamos entre todos. Al día siguiente empezaríamos de nuevo, desde cero.

Hace poco, cambiamos las reglas del juego. Ahora, lo que pretendíamos hacer es escoger una Kata y hacerla durante un mes. La primera semana la haríamos normalmente pero el resto de las semanas y hasta que acabase el mes nos pondríamos limitaciones, para explorar otras formas de resolver el problema y cambiar la forma de pensar. Se nos ocurrieron cosas como:

* Hacer la Kata solo con objetos, nada de primitivos. Encapsulamiento máximo

* Hacer la Kata en modo spaghetti-code. Nada de refactors

(Llevamos poco tiempo haciendo esto, así que solo se nos han ocurrido estas restricciones).

No puedo hablar por mis compañeros, pero creo que en general es una muy buena práctica. No solo mejoras en rapidez a la hora de desarrollar en un lenguaje en concreto si no que además, en nuestro caso, estamos aprendiendo otras herramientas de trabajo. 25 minutos al día, cada día. Es poco tiempo y aporta mucho.

 

Lanzar un Job de Jenkins desde Google App Engine

La semana pasada estuve dándole vueltas a este problema, después de varios intentos fallidos llegué, con la ayuda de Julio, a la solución que planteo en el título del post.

Para empezar tenemos que ir al job en Jenkins que queramos lanzar desde fuera y activar la opción de “Lanzar ejecuciones remotas”

Por motivos de seguridad, Jenkins nos obliga a usar un Token que será usado al llamar al Job desde fuera.

El código que usaremos en GAE (en Python) será el siguiente:

import urllib2, base64, httplib
from urllib2 import URLError, HTTPError
from django.http import HttpResponse

def call_mlp_generator(request):

    theurl = 'JENKINS_JOB_URL?token=TOKEN'
    username = 'USERNAME'
    password = 'PASSWORD'

    request = urllib2.Request(theurl, None)
    base64string = base64.encodestring('%s:%s' % (username, password)).replace('n', '')
    request.add_header("Authorization", "Basic %s" % base64string)
    try:
        urllib2.urlopen(request)
        response = str(httplib.OK)
    except HTTPError, e:
        response = str(e.code)
    except URLError, e:
        response = str(e.code)

    return HttpResponse(response)

Bastante simple, sólo había que saber tocar las teclas adecuadas.

Entorno de desarrollo de Google App Engine en Fedora 15

Me parece interesante contar la experiencia que tuve ayer al configurar el entorno de desarrollo de GAE en una máquina Linux (Fedora 15 en este caso), sobre todo por si puede ayudar a otros desarrolladores y evitar algunos dolores de cabeza.

Aquellos que trabajen con GAE han de saber que hasta nueva orden, el sistema necesita Python 2.5 para poder funcionar correctamente. Google así lo recomienda, aunque recuerdo haberlo hecho funcionar sobre Python 2.6 en mi anterior vida (cuando era Ubuntu).

Voy a intentar reconstruir el camino correcto a seguir para configurar el entorno de desarrollo de GAE sobre un Fedora 15 (ya que di muchas idas y venidas).

La última versión de Fedora tiene por defecto Python 2.7, y si intentaba arrancar el proyecto en local usando esta versión de Python, tenía serios problemas de incompatibilidades de módulos, por ello me bajé Python 2.5.

Por otro lado instalé un par de librerías que necesitaría más adelante (esto tardé varias horas en hacerlo funcionar, por el orden en que hacía las cosas):

sudo yum install openssl openssl-devel -y
sudo yum install sqlite-devel

Una vez instaladas estas librerías era el momento de compilar el código de Python 2.5 e instalarlo. Antes de nada, hay que modificar el fichero <python-folder>/Modules/Setup.dist y descomentar las siguientes líneas:

# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
SSL=/usr/local/ssl
_ssl _ssl.c 
	-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl 
	-L$(SSL)/lib -lssl -lcrypto

(Líneas 206-209)

De esta forma habilitamos el módulo de SSL cuando construyamos Python.

Es hora de construir Python:

su
./configure
make
make altinstall

Con el make altinstall lo que hacemos es instalar Python en una ruta diferente y no machacar la versión actual que tengamos instalada en el sistema.

Si todo ha ido bien, ahora podremos usar

python2.5 dev_appserver.py --port 8080 RutaDeTuAplicación

Si compilamos Python 2.5 sin haber instalado las librerías arriba mencionadas o sin haber habilitado los módulos de SSL podríamos encontrarnos problemas como estos a la hora de arrancar el proyecto:

AttributeError: 'module' object has no attribute 'HTTPSHandler'

o

ImportError: No module named _sqlite3

(Dependiendo de lo complejo que sea vuestro proyecto, claro.)

Espero que esta pequeña guía sirva de ayuda para aquellos que tengan los mismos problemas que tuve en su momento.

Compartir es poder.

Cambiar de entorno de programación

Es común encontrarse con equipos “Java”, “.Net” o “Cobol”, los cuales trabajan solo y para un entorno. Está claro que si te sientes cómodo programando en Java, te dará algo de respeto meterte a programar en .Net, o lo mismo el jefe no quiere que pierdas tu tiempo programando en Java, si ya lo haces bien en .Net.

“Es una pérdida de tiempo y el cliente quiere el proyecto para ayer”.

Como programador, valoro mucho el poder trabajar en diferentes entornos de desarrollo, por varios motivos:

  • A veces trabajar sobre una tecnología demasiado tiempo (en mi caso, Android) me ofusca sobremanera. Hacer alguna Historia de Usuario en Python me relaja y ayuda a recuperarme un poco de la ofuscación.
  • Sacarme de la comodidad habitual de un entorno muy conocido puede ayudar a la motivación, a pensar nuevas estrategias y nuevas formas de desarrollar. Llevando esta analogía al mundo friki… ¿Es lo mismo jugar con los Marines Espaciales que con los Eldar en el Warhammer 40.000? Seguro que no, cada uno tiene sus estrategias, sus ventajas e inconvenientes.
  • Aprender nuevas tecnologías. ¿Hay algo más hermoso para un developer?

– “Hala, venga, trabajad en Python,”

– “¡Pero si no tengo ni idea!”

Esto pasa, si no tienes ni idea de un lenguaje, como decía antes,  te da algo de respeto cambiarte. Es posible que la primera vez no seas 100% productivo (siéntete afortunado si lo eres un 20%)  y no hagas las cosas bien del todo, pero lo mismo la segunda ya lo haces mejor y a la tercera vez que te cambias ya lo dominas mucho más. Es recomendable que las primeras veces haya algún “experto” en la materia que pueda guiarte por esos momentos de incertidumbre y confusión.

“¿Qué carajo es jQuery?”

¿Merece la pena bajar un poco la productividad por que haya más gente que sepa un poco de todo? Si tienes en tu equipo a un hacker en Cobol y solo él sabe del proyecto… ¿Qué probabilidad hay de que se vaya todo al carajo si a este hacker se lo lleva un autobús por delante? Bueno, quien dice un autobús….  dice que se va de vacaciones y se jode algo del proyecto… o algo más dramático (pero no tanto como lo del bus), que se vaya a otra empresa. Reducir ese factor de riesgo es positivo para la empresa (para una empresa que se preocupe de sus proyectos, la calidad de los mismos y la salud mental de los developers).

“No estoy programando en Python, sino que estoy programando en Python como si fuera Java”

Esto pasa… Cuando no conoces un lenguaje, sueles agarrarte a lo que conoces, si conoces Java tenderás a desarrollar código Python como si fuese Java… Luego, cuando vayas cogiendo más experiencia, conociendo la API y la sintaxis te darás cuenta de la diferencia, del cambio de chip y de crear código Python en sintonía con Python (luego corres el riesgo de volver a Java y escribir código Java como si fuera Python….).

A pesar de las pequeñas incomodidades (que en el fondo deberían ser alicientes para romperse la cabeza), recomiendo cambiar de entorno de vez en cuando y siempre y cuando la empresa te lo permita, claro.

De hecho, estoy bastante cansado de Android… me voy a poner a hacer algo en Python.

PD. Donde pone “Python” en este artículo, cambiar por el lenguaje que os gustaría aprender/practicar. He personalizado el post a mi caso, podría haber puesto “.NET”… pero entonces no habría sido yo el que hubiese escrito el artículo. 😛

VirtualEnv para Google App Engine en local

Por defecto en Google App Engine , hasta hace bien poco, solo se podía usar hasta la versión 1.1 de Django. Esto generaba problemas si tenías alguna otra aplicación web que requería una versión más reciente de Django, como por ejemplo nuestra herramienta de revisión de código. Obtenías una serie de conflictos que eran una molestia para el desarrollo y uso en local del servidor, impidiendo un desarrollo fluido y una configuración estable.

La solución por la que optamos fue usar virtualenv. Con esta herramienta podríamos separar el entorno de ejecución de Google App Engine, del resto de aplicaciones instaladas, tanto en el servidor de integración continua como en los equipos de los desarrolladores.

Después de consultar varios sitios web al respecto, el proceso de configuración quedo algo así:


aptitude install python-virtualenv python-pip

Para instalar tanto el propio virtualenv como pip, una herramienta para instalar paquetes en dicho entorno.


virtualenv --no-site-packages --python=python2.5 ENV

Para configurar en ENV el entorno. –no-site-packages indica que no herede ningún package de la instalación de la cual se toma python y le indicamos que queremos la versión 2.5 pues GAE se ejecuta en con la 2.5 en los servidores de Google.

pip install -E ENV Django==1.1

Añadimos la versión de Django que utilizar con pip.

Para finalizar ya solo falta copiar la carpeta de Google App Engine dentro de ENV. Activar el entorno utilizando un par de scripts que hay en ENV/bin/ y lanzar el servidor de desarrollo.

Ahora mismo toda esta parafernalia tiene algo menos de sentido pues en la última versión del SDK del GAE han añadido la versión 1.2 de Django. Pero aún así puede ser útil para conseguir un entorno controlado y separado del resto de la máquina. Ya sea un servidor de integración continua o nuestra propia máquina de trabajo.

Primer Walqa Coding Dojo

Así es, el viernes pasado, día 21 de enero, se celebró el primer coding dojo realizado en el Parque Tecnológico Walqa, dirigido por Carlos Ble.

Un dojo (道場, literalmente “el lugar de la senda”) es un sitio donde poder practicar y entrenar una disciplina concreta. Simplemente son centros donde se pueden reunir personas con ganas de aprender. Como en todos sitios, es normal que haya gente con más conocimientos que otros, pero esto es precisamente lo que se busca: que el conocimiento puede transmitirse entre los asistentes.

En nuestro caso, las características de nuestro dojo eran las siguientes:

  • Se va a diseñar y programar un problema (o kata) llamado FluentAPI.
  • Debe realizarse por parejas (pair programming).
  • Debe utilizarse TDD.
  • Se realizará en periodos de tiempo determinados, tras lo cuales deberemos cambiar de pareja.
  • No se indicará cuánto tiempo dura cada periodo (así tampoco hay ansias por terminar)

Al evento asistieron más de 30 personas de distintos perfiles y distintas procedencias (Indra, Tafyesa, Universidad de San Jorge, Telefónica I+D,…)

El problema o kata elegido para la ocasión fue el siguiente:

Queremos conseguir una API para acceder a una lista de objetos que sea fácil de leer al ojo humano, al estilo de:

  1. select(“name”).from(users)
  2. select(“name”).from(users).where(“age”).greater_than(18)
  3. select(“name”).from(users).where(“surname”).contains(“rodriguez”)
  4. select(“name”).from(users).where(“age”).greater_than(18).and(“location”).is(“san francisco”)

Y a ello nos pusimos. En el primer periodo parecía que la cosa no terminaba de arrancar, ya que el problema era difícil de abordar en un principio. Por las mesas se veían lenguajes tan dispares como Java, Ruby, PHP, .Net o Python.

Al sonar la alarma y acabar el primer pomodoro, nos dirigimos a una sala habilitada por Walqa con aperitivos y bebidas, que de seguro nos sirvió para descansar y consultar algunas dudas (como el uso de import static en Java, que resultó fundamental para la resolución del problema)

Acabadas las sesiones de programación, nuestro sensei Carlos Ble se puso a los mandos del portátil y se dispuso a ejecutar una forma de resolver el problema en Python. Mientras, los asistentes observaban el proyector con lo que iba realizando, en medio de un silencio solemne.

Tras lo cual, Carlos dejó continuar la resolución a dos de los presentes: Dani y Rubén, que se enfrentaron a una modificación del problema ante todos los asistentes.

Y hasta aquí dio tiempo. Los participantes salimos muy contentos con la experiencia y alguien llegó a decir que había sido el coding dojo con más afluencia de los realizados en España. ¿Será verdad? 🙂

P.D: nuestra intención es que este sea el primero de una larga lista de eventos.

P.P.D: tenemos nuestro propio hashtag: #codingdojohuesca

Antiguas entradas