El sábado y domingo pasado se realizó el Cuarto Festival de Cultura Libre y Copyleft: Fábrica de Fallas, organizado por La Tribu. Fue una fiesta. El sábado estuvo más tranquilo, con charlas, talleres, y algunos stands adentro del edificio, como en los otros años. Buena afluencia de gente, todo bien. El domingo, en cambio, fue en la calle. Lambaré cortada entre esquina y esquina, los stands directamente en la calle, banderas colgando entre los árboles, luces y guirnaldas. Un escenario inigualable para recibir a la inmensa cantidad de gente que pasó por ahí. Realmente fue un festival de cultura libre. Desde un lenguaje de programación hasta intercambio libre de ropa. Desde cómo fabricar antenas hasta un taller de arte urbano, graffitti, stencil. Y muchas cosas más. Y mucha improvisación, porque había onda. Entrada la tarde, se armó un escenario, y tocaron varios músicos y bandas. Lo que les decía... una fiesta: Todas las fotos, acá .
Este sábado 26 y domingo 27 tenemos el Cuarto Festival de Cultura Libre y Copyleft: Fábrica de Fallas. Se hace de 12 a 23 horas, en La Tribu, Lambaré 873, Ciudad de Buenos Aires. Es un evento multicultural, multitemático, multiartístico, multietario, multi. Con espacios para charlar, para crear arte en el lugar, para conocer gente, para hacer talleres, y para mucho más, se destacan la radio abierta que siempre tenemos durante el evento, y en especial muchas charlas copadas ( acá tienen el temario ), donde en otros años se han escuchado frases de alto calibre como "Romper la barrera tan finamente inculcada de que todo lo ilegal es ilegítimo" (Enrique Chaparro). (hagan click en la imagen para ver un video copado) Python Argentina, como siempre, tendrá un stand en el evento. No se lo pueden perder, ¡nos vemos allá!
Agregué en la página de mis videos los correspondientes a California, México y Suecia (todos de Mayo/Junio del 2005). Ya casi no me quedan videos que editar, y estoy terminando con esta tarea que es un poco agotadora (en promedio, para editar un video, lo termino viendo unas 5 veces, lo cual aburre muchísimo!). Pero bueno, era algo que quería hacer, y ya casi está listo.
Esta foto la saqué en uno de las dos caminatas que hice por Irlanda, en una plaza (obviamente, la otra caminata fue por los bares...). Me encanta el contraste de colores... el blanco de la piedra, el verde de todo alrededor, y el azul del farol.
Y llegaron los dos años de Felu. Como teníamos gente demasiado dispar (y demasiada) para invitar un sólo día, decidmos separar los festejos. El mismo día del cumpleaños fuimos al jardín, para que festejara con sus compañeritos (justo Felu estaba terminando de recuperarse de una gripe, así que sólo fuimos para eso y nos volvimos al rato), y esa tarde Moni armó una merienda con compañeras de ella de los jardines. El fin de semana siguiente era largo, entonces aprovechamos para hacer los dos festejos principales. El sábado recibimos en casa a familiares y amigos que no tenían hijos pequeños, e hice unas carnes a la parrilla para armar sanguchitos. El lunes, feriado, hicimos el festejo para todos aquellos que sí tenían hijos pequeños, en una especie de casa pseudo quinta, algo abierto y al aire libre, con parque para que los chicos jueguen, todo muy lindo. Como era feriado no había "animación" provista por el lugar, pero nos salvaron Valentina y su amiga Sofía, que divirtieron a los chicos, los guiaron en actividades, etc... todo muy bien. La verdad es que terminamos súper cansados, luego de esa semanita, pero lo importante es que Felu disfrutó mucho en cada una de esas reuniones. Todas las fotos acá , acá , acá y acá .
Consejo: Nunca traten de upgradear el sistema operativo de un VPS que tienen contratado. No funciona, por cosas que van más allá del OS en cuestión (uno de los detalles que ví en el mío, es que el /boot está vacío... nunca puede andar, :p). ¿Cómo lo sé? Porque lo intenté, e hice crema mi server. Tenía backup, pero sólo de los datos. Esto significa que aunque tenía copias de lo más importante y realmente valioso, volver a hacer funcionar todo me llevó varias ( varias ) horas de trabajo de instalar y configurar cosas. Lo último que acabo de arreglar: la posibilidad de dejar comentarios aquí en el blog. Con esto creo que ya está todo al 100% como antes. Si encuentran algún otro detalle, me chiflan. ¡Gracias!
Un momento con el hijo, que me encantó (click en la foto para ver el video).
(Note: There's an English version of this article here ) Los últimos meses en el equipo Ubuntu One Foundations, en Canonical, estuvimos experimentando con la metodología cirujano-copiloto. ¿Qué es eso de cirujano-copiloto? El concepto viene de un libro de los setentas, The Mythical Man Month , donde Frederick Brooks describe un provocativo esquema (propuesto primero por Harlan Mills) para un equipo de desarrollo de diez personas. En el libro, Brooks intenta manejar el hecho de que proyectos grandes de software no pueden ser escritos por una persona, o por un equipo chico, por lo que propone partir el proyecto en partes más pequeñas, prestando especial atención a la optimización de las comunicaciones dentro y entre los equipos. En el libro, la organización propuesta es poner a un desarrollador Cirujano rodeado de un gran equipo de ayudantes. Hoy en día el entorno de desarrollo es otro; tenemos herramientas como lenguajes de alto nivel, y repositorios de software, y versionado de código, etc. Seguramente no necesitamos a alguien para que nos clasifique las tarjetas perforadas, :) Sin embargo, este es un concepto que podemos usar hoy, pero achicando el equipo a sólo dos personas: el cirujano, y el copiloto. Traducido del libro... (el copiloto) es el alter ego del cirujano, capaz de hacer cualquier parte del trabajo, pero menos experimentado. Su función principal es compartir la etapa de diseño, pensando y discutiendo, y evaluando. El cirujano intenta ideas con él, pero no está atado a sus recomendaciones. El copiloto frecuentemente representa a su equipo en discusiones con otros equipos sobre funcionalidades e interfaces. Conoce todo el código íntimamente. Investiga estrategias alternativas de diseño. Nuestra experiencia Este experimento fue valioso para nosotros, ya que generó un equipo de dos que al ejecutar el experimento probó ser más eficiente que las dos personas por separado. Alguno de los casos donde esto fue evidente durante el experimento fue que al discutir problemas o nuevas características, el cirujano (teniendo un conocimiento más profundo del sistema) podía prever fácilmente situaciones, cómo podría diseñarse la característica, resolverse el problema, etc. Entonces el cirujano discutía eso con el copiloto, necesitando explicar el razonamiento lo suficiente como para que se entienda (pero a alguien con experiencia en el sistema), lo que provocaba algunos buenos efectos secundarios: Tener que poner el razonamiento en palabras lo hace más claro tanto para el cirujano como para el copiloto; sin embargo esto no es un gasto notable, ya que ambos conocen el sistema, lo que hace más sencillo la transferencia de conocimientos. Se descubren temprano posibles fallas en el razonamiento, y también se pueden incorporar en este momento ideas frescas del copiloto. Luego que el copiloto entendió la idea, él o ella pueden ayudar al cirujano a implementarla (o directamente hacerlo todo, liberando al cirujano para otras tareas). Quiero dejar en claro que esto no implica que el copiloto dependa siempre del cirujano para el trabajo diario. Normalmente el copiloto trabaja creativamente y trae nuevas ideas y conocimiento al equipo; sin embargo discutir esta nueva información con el cirujano, de manera de integrarla mejor al sistema actual, hace más eficientes estas contribuciones. Esto está muy relacionado con otro beneficio interesante del dúo dinámico cirujano/copiloto: entrenamiento. Cuando el copiloto es nuevo al equipo y al sistema, tener a alguien que sabe exactamente los avances que está haciendo al ganar velocidad, revisando y guiando el trabajo, hace más fácil y disfrutable esta etapa inicial (lo que se traduce a una mayor eficiencia y mejores resultados). Más aún, este equipo altamente acoplado es especialmente bueno para atacar problemas complejos. Esto se debe principalmente a tener cuatro ojos en lugar de dos, pero con la ventaja que ambas personas tienen baja impedancia entre ellas. Sin embargo, ser explícitos sobre quien es responsable de tomar las decisiones es algo muy bueno en la interacción entre el equipo y otros jugadores externos (jefes, líderes técnicos, usuarios): queda claro que el cirujano es responsable por las decisiones tomadas, de una manera u otra. Una ventaja adicional de formar el par cirujano/copiloto es que si el equipo prueba ser exitoso (lo cual depende de muchos otros factores más allá de esta configuración en particular, somos mayormente humanos) se puede mantener a futuro, sabiendo que esas dos personas trabajando juntas son buenas para determinadas tareas, y usarse de esa manera (lo cual concuerda con el concepto de desarrollo ágil de asignar trabajo a equipos, no personas a tareas). Un caso real Quiero explicar uno de los casos donde trabajamos como cirujano/copiloto durante estos meses, sólo como una muestra que quizás ayude a entender mejor los conceptos anteriores. Este fue uno de los problemas más grandes encontrados en el Ubuntu One Syncdaemon luego de la liberación de Karmic, generando de los usuarios un quintillón de reportes de bugs: el States de Syncdaemon. Era un pedazo de código que arrancó chico y creció orgánicamente mientras aprendíamos qué debía hacer para manejar todas las complejidades de Syncdaemon. Al final, era un módulo grande, construido de una manera que no permitía realmente ser probado, y difícil de leer y entender, que generó un montón de problemas muy visibles (normalmente, hacía que Syncdaemon se trabara y no trabajara más hasta que se lo reiniciase). El objetivo para el equipo era simplemente "arreglarlo". Sin embargo, un análisis simple probó que se necesitaba reescribir desde cero, y el reemplazo debía estar literalmente libre de problemas (no podíamos darnos el lujo de perder dos meses encontrando detalles en el nuevo código estando tan cerca de Lucid). Ejecutamos el proceso de "arreglar States" en varios pasos bien definidos: Análisis: Acá estudiamos el código anterior, encontrando los casos explícitos e implícitos que manejaba. Definimos qué necesitábamos cambiar, y qué necesitábamos escribir de nuevo (notablemente, encontramos acá algo inesperado: debíamos rehacer el cómo Syncdaemon manejaba las conexiones de red a través de Twisted). En esta etapa, el tener un equipo altamente acoplado funcionó muy, muy bien. La misma tarea no podría haber sido ejecutada tan eficientemente si la hacía una sola persona, o si un equipo se involucraba en profundas discusiones. Debo mencionar que este trabajo se hizo cara a cara durante un sprint (difícilmente se podría haber hecho remotamente y tener el mismo resultado). (click para ver la imagen en una resolución entendible) Diseño: También durante el sprint diseñamos un nuevo modelo para la bestia, tratamos de simplificar y generalizarlo, y discutimos todo esto con los autor(es) anterior(es) del módulo. El tener un cirujano con más experiencia en esta fase, mezclado con las nuevas ideas del copiloto, provocaron un buen diseño, simple y poderoso. Una sola persona o dos trabajando por separado no podrían haber diseñado el nuevo States de forma tan limpia como sucedió en este caso. Implementación: esto se hizo completamente en paralelo y remotamente, en las semanas siguientes al sprint. Sin embargo también incluyeron largas conversaciones por teléfono donde se discutieron detalles específicos o nuevas ideas. En esta etapa también notamos que el equipo tenía el tamaño ideal: un sólo par de ojos seguramente no habrían visto los detalles más complicados, y más gente no podría haber trabajado en paralelo en la misma implementación como lo hicieron dos personas. (click para descargar los tres .SVG actualizados del diseño) Puesta en funcionamiento: realmente no fue un paso, ya que no hubo ningún problema... fue sólo un tema de hacer el commit a trunk, y hacer un seguimiento los próximos días. El resultado de esta experiencia fue muy satisfactorio: reemplazamos algo que era muy doloroso para usuarios y desarrolladores en favor de algo que fue invisible luego de la instalación: funcionó tan bien que nadie lo notó más. Conclusiones Estoy muy contento con el resultado de este experimento, y con los objetivos que logramos mientras lo hacíamos. El trabajo producido durante esos meses fue muy bueno, considerando especialmente que venía Lucid. Sin embargo, es mucho más valioso encontrar dos personas que trabajen tan bien juntos, incluso si no hay una diferencia de experiencia entre ellos para que califique dentro de la estructura cirujano/copiloto. No siempre se tiene que un equipo de dos desarrolladores produce más que los dos desarrolladores por separado... entonces cuando se encuentra, es buena idea mantenerlo. Recomiendo hacer experimentos similares en Canonical, especialmente como una oportunidad de aprendizaje para personas que recién entraron en la compañía, o al hacer rotaciones entre equipos. En estos casos, el tener un entrenador que tiene más experiencia al menos en lo que está haciendo el departamento, ayuda mucho al desarrollador nuevo, y al final mejora el rendimiento de todo el equipo.
Venimos atrasados con el procesamiento de fotos, pero acá ya tenemos los videos del cuarto y quinto mes de Felipe (click en la foto para verlos en YouTube). Si quieren, pueden bajarlos de acá y acá con más resolución.
(Note: There's an English version of this report here ) Mandé este mail originalmente a la lista interna de Canonical donde discutimos temas técnicos: "Testing" (o testeo , o realizar pruebas ) es un terreno resbaladizo en el desarrollo de software. Es como dejar de fumar: todo el mundo sabe que es algo bueno, pero pocos tienden naturalmente a hacerlo. Además tiene facetas muy diferentes: pruebas de unidad, pruebas de integración, interfaces gráficas. Incluso en las interfaces gráficas, no es lo mismo hacer pruebas en PyGTK, o en interfaces web. Por ejemplo, yo estoy convencido de que debemos hacer pruebas cuando desarrollamos software, que es una buena manera de evitar (o minimizar) deuda técnica, y que no sólo te mejora la calidad del producto, sino que tiene características más difíciles de medir (como innovación: nadie va a tocar un proyecto grande que no tiene pruebas sólo para probar algo nuevo). Pero, todavía tengo algunas dudas, y mucho que aprender en este campo. ¿Es valioso en todos los casos? ¿Cual es el balance correcto entre pruebas de unidad y pruebas de integración? ¿Y qué hacemos con las interfaces gráficas? Y un tópico probablemente controversial: yo sé que tenemos que hacer pruebas, pero gente en mi equipo no, ¡ayúdenme a convencerlos! En cualquier caso, es algo para hablar. Podemos arrancar una charla acá, y luego agendar un par de reuniones para cubrir algunos temas particulares, una vez que sepamos cuales, o quizás encontrarnos en el UDS para discutirlo personalmente. Estoy seguro que dentro de Canonical "Testing" se usa en todos lados, y podemos aprender unos de otros. Ideas? Preocupaciones? Experiencias? Esto generó un gran árbol de discusiones, con un montón de puntos en los que todos estaban de acuerdo, y un montón que fueron un poco controvertidos. Entonces, luego de que el polvo se asentó, escribí un resumen de toda la conversación: Esto es una especie de resumen con conclusiones y comentarios del hilo sobre Testing de los últimos días. Es mejor mostrar ventajas sobre algo a la gente que forzarlos a usarlo. Hay un par de situaciones "fáciles de ver" donde las pruebas de unidad son claramente algo bueno. Jamu K. agregó algunos puntos a lo que yo mencioné en el correo original: Te dicen cuando cometiste un error y rompiste algo. Cuanto antes detectes el error será más barato arreglarlo. Si un problema entra a un sistema en producción y afecta a los clientes, costará mucho en términos de satisfacción del usuario y tiempo para arreglarlo. Son material educativo que ayuda un principiante (o alguien experimentado) a entender la lógica en una manera que no es posible simplemente al leer el código mismo. Esto es especialmente verdad cuando las pruebas ejercitan condiciones de error que no se desprenden de forma obvia del código. Te ayudan a mantener una velocidad consistente. Es mucho menos probable que encuentres un problema que te haga perder dos días revisando y corrigiendo cuanto tenés buenas pruebas. Te permiten optimizar la implementación con la confianza de que no rompiste ninguna API . "Primero hacelo bien, luego hacelo rápido" es bastante duro, y lo es aún más sin buenas pruebas. Por definición, hacen que tu implementación se pueda probar. Te ayudan a entender cuando amontonaste demasiados detalles y te llevan a un mejor diseño. Algunas ventajas son más conceptuales: muy claras a la gente que ya probó pruebas de unidad, pero no tan fáciles de ver para gente que realmente nunca lo hizo. Un ejemplo de esto es que diseñar para ser probado frecuentemente lleva a una mejor API (sin embargo, algunas veces lleva a una API más fea, porque estás forzado a agregar parámetros que sólo son útiles en un entorno de pruebas; como en todo, el equilibrio es el mejor de los consejos). Una buena frase del hilo que me gustó como razón para hacer pruebas: El código que estás escribiendo será usado por años. Será actualizado al cambiar los requerimientos. Y de vez en cuando, alguien que no es familiar al código como lo estás vos ahora estará en apuros para corregir un problema en él. ¿Qué previsión razonable podés hacer para ayudar a esa persona? Pensalo un minuto. Acordate, esa persona podrías ser vos. ¿Y qué desventajas hay? La gente a veces se queja de que si hacen pruebas, tardan más en escribir código. Sin embargo, lo que sucede es que las pruebas no cambian realmente el total de tiempo que toma desarrollar software, sólo cambia el cuando se paga ese costo. Sí, para software con pruebas, el beta inicial es mucho más completo y mejor probado, pero aparece más tarde en el ciclo, lo que puede ser un problema si no podés entregar ese código al usuario. En todo el hilo, sólo se mencionó una desventaja real de TDD : puede pasar a veces que en lugar de realmente pensar profundamente un detalle del código, sólo lo vas toqueteando hasta que pasás las pruebas: esto puede llevar a código que esté menos pensado que lo que debería, ya que programás contra una luz verde, no contra un modelo mental limpio. Hay que aclarar que no hay nada malo en no hacer TDD, pero que entrega resultados muy distintos con respecto a hacer las pruebas como corresponde, y se podría decir que al no hacer TDD los resultados son peores. ¿Está bien tener malos resultados? En algunos entornos, apuesto a que sí; sin embargo en Canonical queremos entregar lo mejor. Jamu lo dijo bien claro: si estás escribiendo código de producción sin hacer pruebas, entonces no estás haciendo tu trabajo correctamente. Mark S. lo reforzó con: Deberíamos requerir pruebas para el código que somos responsables, y las excepciones que haya (seguro las habrán) necesitan justificarse y documentarse, no al revés. Hacer pruebas es algo cultural, necesitamos encontrar cómo hacerlo crecer culturalmente: contratar gente que ya entienda y actúe con ese conocimiento, y entrenar a aquellos que todavía no tienen confianza en esto. Hubo un montón de charla alrededor de hacer pruebas, pero nadie hizo distinción sobre que tipos de pruebas eran. Parece que las pruebas de unidad y de integración, o probar bibliotecas o interfaces gráficas, es todo lo mismo al discutir el tema. Sin embargo, alguien preguntó específicamente sobre pruebas en interfaces gráficas. Realmente no sé sobre eso (¡quiero aprender!), pero creo que es un área menos conocida que las "pruebas sobre bibliotecas". También se mencionó un tipo de pruebas que es raramente comentado fuera de los círculos de administradores de sistemas: cuando se maneja un servicio que se tienen que monitorear, es vital disponer de una manera de poder probar al servicio de manera frecuente y repetida tal que se pueda asegurar que sigue funcionando. Entonces, también se necesitan pruebas de reglas y procesos de negocios para los sistemas funcionado. Hubo un poco de discusión acerca de las pruebas de documentación. "Doctests" son un buen material de aprendizaje para las bibliotecas, y pueden escribirse para mostrar funcionalidad y guiar por arriba a los usuarios. Pueden ser muy buenas para dar impresiones generales sobre el módulo. Pruebas de documentación bien escritas son excelentes para documentar APIs, porque podés hacer que el conjunto de pruebas ejecute también aquellas, de manera de asegurarte que la documentación siempre permanece actualizada. Estás haciendo pruebas sobre la documentación, no usando la documentación para probar nada. Quedó claro que las pruebas de documentación no reemplazan las pruebas de unidad, las complementan. La discusión más grande del hilo fue sobre si TDD era útil en código experimental, o en etapas muy tempranas del desarrollo. Se aseguró que TDD funciona mucho mejor con códigos maduros que con código experimental. Esto se aplica también a características experimentales dentro de proyectos maduros. Básicamente se reduce a esto: si tenés una buena visión de lo que necesitás, escribir las pruebas primero te ayudan a señalizar el camino que vas a tomar. Si no tenés ni siquiera una buena idea de para qué dirección vas, TDD es un esfuerzo desperdiciado. Esto generó algo de controversia, hasta que se explicó que "experimental" no es la mejor palabra para explicar que: estás en una fase de aprendizaje porque realmente estás tratando de entender mejor el problema. Una vez que entendiste el problema lo suficientemente bien como para tener una visión de la solución, volvés a TDD. Son realmente dos actividades distintas. Esto normalmente sucede cuando la gente que escribe el código en modo "experimentación" sólo quiere ver si una idea loca va a funcionar o no, lo que muchas veces resulta en descubrir que todavía no se entiende el problema completamente. Por otro lado, está la situación donde se necesita código en producción, y realmente no hay tiempo de hacer pruebas. Sí, ya sabemos, tendrá defectos, y a largo plazo es más caro, pero "lo necesitamos ya". Esto pasa en la vida real más veces que con las que estaría cómodo... Gustavo N. dijo algo que comparto completamente: Si estás en una startup en una situación de vida o muerte (para la compañía), seguro... podés optar por ir realmente rápido, obtener un montón de mercado, y luego estabilizarte si resultó bien (mirá Twitter :-). Si sos parte de un contexto más grande (como nosotros), y tu producto no va a desaparecer pronto (ni la compañía que tiene una marca asociada con el producto), entonces estas rupturas pueden dañar realmente al producto y a la marca. Entonces, como conclusión, por favor compartí sobre hacer pruebas en esta lista. Preocupaciones, ideas, tecnologías, si deberías o no hacer algo, etc.; este no es un tema donde todo es blanco o negro, o donde está todo dicho. Si con el tiempo encontramos que es necesario una reunión para discutir algo (o incluso un grupo que se reúna regularmente), podemos ir a por ello. Mientras tanto, charlemos por acá.
Es que estuvimos programando... ... y luego me plantearon un desafío: Más tarde nos relajamos leyendo... ... hasta que caímos exhaustos!
El jueves había una sensación general de cansancio y de que ya faltaba poco para que termine la semana. Yo estaba igual. El día no ayudaba, frío, casi lluvioso. Luego de las sesiones me quedé un rato en la habitación, sin decidirme qué hacer... finalmente agarré la campera y bajé rápido para tomarme el bus hacia la ciudad, a ver si agarraba el último. Por suerte sí, y encima me encontré con Nicolás Valcárcel, así que paseamos juntos. El bondi nos dejó en el medio de nada, pero al lado de una estación de subte. Ocho estaciones y estábamos en el centro de la ciudad. Paseamos un rato para ver al famoso niño que hace pis| ( Manneken Pis ), y de paso compramos cosas para llevar a nuestras familias, ya que entre esa estatua y la plaza central están todos los puestos para turistas. Comimos rápido por ahí (si no perdíamos el micro de regreso), y no tan tarde estábamos en el hotel nuevamente. Ya en la habitación, me abrí una cerveza y me puse a trabajar en distintas cosas. Estaba cansado, y mi idea era irme a dormir temprano, pero al final me enganché con no se qué y me terminé acostando a las dos de la mañana. El viernes no tenía nada en la primer franja, así que me levanté una hora más tarde (a las nueve y diez, así entre vestirme y desayunar llegaba bien a la sesión de las 10). La tarde la tenía casi libre, así que estuve laburando en mi habitación hasta que se hicieron las cinco, que arrancaba la ceremonia de cierre. En la misma hicieron un anuncio que ya se había sugerido en otro momento, y que es una idea genial. ¿Saben cómo es 42 en binario? 101010. Bueno, Ubuntu Maverick Meerkat será liberado el 10/10/10, :D. Para los que 42 no les dice nada, les dejo este enlace . Cuando terminó la ceremonia pasé por mi habitación a agarrar la raqueta, y me fuí a jugar al tenis con Guilherme Salgado. Fue un partido interesante, no sólo porque nuestro nivel era parejo (gané 6-3 6-1), sino porque jugamos sobre pasto sintético (nunca había jugado sobre pasto, y la verdad es que se nota la diferencia... la pelotita pica un poco menos, y sale disparada luego de hacerlo). Luego del partido, me pegué un baño y me fui a la fiesta, donde entre cena, vino y cerveza, se desenvolvió el clásico All Stars, donde la gente se va turnando en los instrumentos para hacer música (generalmente rocanrol). Me terminé yendo temprano a dormir, porque entre el cansancio y la cerveza, no daba para trasnochar. El sábado me levanté temprano, y aprovechando el micro que iba y venía a la estación de tren de La Hulpe , me fui para allá para pasear un rato. Caminé por la ciudad casi una hora, yendo y viniendo de la estación de tren a un pequeño centro comercial que habíamos visto con John cuando fuimos en bici al Carrefour. Ahí compré un par de libritos en francés para Felipe y Moni. Volví al hotel con otro micro, y empecé la ceremonia de partida: revisé toda la habitación y dejé arriba de la cama todo lo que era mío, me bañé, armé la valija y la mochila, y bajé. Hice el checkout, esperé un par de horas en el lobby del hotel a mi micro para el aeropuerto, y luego partí de regreso a casa. Sinceramente, el evento estuvo muy bueno. Más allá de encontrarme con mucha gente que conozco, es maravilloso ver como la comunidad de Ubuntu trabaja y trabaja para que todos tengamos un sistema operativo mejor, para cambiar el mundo un bit a la vez, algo que ya se está logrando, y lo mejor es que es de forma coordinada con otras comunidades. Relacionado con eso les dejo un enlace a este video que fue presentado por Jono Bacon en la apertura del UDS, y que yo subtitulé para que sea más facilmente entendible. No dejen de verlo. Para cerrar, pueden ver todas las fotos del UDS acá .
El lunes nos levantamos tempranito con John, bajamos a desayunar tipo ocho y veinte, y estábamos a las nueve listos para la apertura del evento a cargo de Jono Bacon, y luego una keynote de Mark Shuttleworth. Durante el día estuve en varias sesiones, algunas me gustaron más, otras menos, en algunas aprendí, en otras participé, etc. Nada realmente maravilloso. La parte de sesiones de UDS terminó a las seis de la tarde, y seis y media ya estábamos con John alquilando unas bicis: fuimos hasta el pueblo cercano, al supermercado. El paseo estuvo fantástico, pero la verdad es que las subidas y bajadas del terreno nos mataron... pasábamos de una punta a la otra de los cambios de la bici, en la bajada alcanzábamos casi la velocidad de la luz (?), pero en la subida sufríamos . Llegamos, acomodamos las cosas en la heladera, y bajamos a tomar una cerveza y charlar con la gente. Más tarde ya volvimos a la habitación, cenamos, laburamos un rato, llamé a casa y a mi hermana que cumplió años, y luego a dormir. Ya que menciono lo de llamar a casa... hablé más de 10 minutos por Skype, de Bélgica a Argentina, y gasté 30 centavos de dólar. En comparación, Movistar me cobra 29 centavos de dólar + IVA por mandar un sólo SMS! Si alguna vez tienen que viajar, la opción de usar Skype para comunicarse hace todo mucho más barato. El martes costó más levantarse, pero arranqué temprano igual. La mañana la pasé en distintas sesiones, normal. La tarde fue distinta: nos juntamos todos los de Ubuntu One en una habitación grande, y todos los que tenían algún problema venían y se lo solucionábamos. Yo manejé tres casos... el primero, tenía la metadata corrupta (el usuario mismo protestaba que esa computadorita que tenía se le colgaba siempre y se le jodían los archivos, más allá de los nuestros); el segundo, cuando me fue a mostrar el problema, funcionaba todo perfectamente, :); y el tercero, al que realmente no le funcionaba todo perfectamente, era porque el servicio todavía es lento en algunos casos (y él había tirado miles de archivos y nunca terminaba), así que tocamos algunas cosas para sacarlos, y dejarlo "sano", para que vaya agregando otra info que le interesaba más. Luego de las sesiones de UDS misma, la idea era irme a jugar al tenis con Rodrigo, pero lloviznaba, así que me puse el short y me fui a la pileta del hotel, hice algunos largos, me metí cinco minutos en el sauna, y volví a la habitación como nuevo. Me pegué un baño y bajamos a tomar una cerveza con John y Achuni. Luego los chicos y un par más arrancaron un juego de Illuminati , yo me quedé un rato viendolos y aprendiendo las reglas y dinámica del juego, y luego volví a la habitación y me fui a dormir. El miércoles también fue un día de sesiones y sesiones, pero aproveché para salir a caminar. Como el último turno de la mañana terminó temprano, aproveché para comer rapidito y salí a recorrer un poco el bosque de alrededor del hotel. Comentario del hotel: está muy bien, moderno, elegante, muy luminoso, rodeado de unos bosques maravillosos. Lo mejor: el servicio de wifi; andaba en todos lados, con una velocidad maravillosa, podías pasearte por todo el hotel y que no se desconectara, no tuvo problemas. Lo peor: el diseño del baño; estaba como separado en tres partes... un inodoro (sin bidet!), el cual tenía puerta, la pileta que daba directamente al pasillo, y la bañadera/ducha que tenía una especie de mampara que cubría la mitad de la misma... pero dejaba entrar todo el frío que venía desde la parte de la pileta, que no tenía puerta que la separe del resto de la habitación. A la noche también salí a caminar, pero esta vez por la ciudad. Aproveché los micros hotel-ciudad, y pegué una vuelta de hora y media antes de que se terminara la luz. La ciudad me pareció aburrida... quizás porque es bastante gris y estaba muy nublado, pero lo más probable es que fuese porque estaba todo cerrado. Bueno, no todo. Había varios restaurants y muchos pubs que todavía estaban abiertos, pero todo el resto de negocios (cafés, librerías, negocios de ropa, negocios de regalos, casas de discos, etc, etc, etc.) esta cerrado. Parece que si trabajás, no podés comprar nada en esta ciudad, porque el horario de todos los negocios es (más o menos) de 10 a 18-30, algunos cerrando un rato al mediodía también. Incluso pasé por un teatro que decía que el día que tenían función "nocturna" el horario era extendido: hasta las 20:30! Anyway.... volví medio decepcionado al hotel, fuimos al gym con John (hice cinta y algo de bici), luego cenamos, laburamos un rato y terminó el día.
En la semana del 10 al 15 de Mayo se realiza el Ubuntu Developers Summit para Maverick Meerka , en Bruselas, Bélgica . Salí de Argentina el Sábado a la una de la tarde, en un vuelo a Madrid sin mayor novedad, excepto que estaba el la troupe de Charly García (reconocí al Zorrito Vön Quintiero ), y que el avión era una mierda: un vuelo de 11 horas sin pantallita individual y sin enchufe para la laptop; juro que trataré de evitar Iberia de ahora en más. La escala fue en Madrid a la madrugada, y al mediodía ya estaba en Bélgica. Del aeropuerto me tomé un tren por una estación, y de allí otro por un buen rato hasta la ciudad donde estaba el hotel (de la estación al hotel mismo había un micro que iba y venía). Llegué a la habitación (que comparto con John , pero él ya estaba desde la semana pasada), desensillé, nos comimos una ensalada, y descansé un rato hasta la reunión al atardecer. Allí nos contaron algunas cosas en las que Canonical se enfocará para el próximo ciclo, cosas que todavía no se conocen pero van a hacerse públicas durante la semana. Luego, una cena con mucha charla, ya que fui encontrando gente que no veía hace rato, nos tomamos una cerveza con John, más charla, y al sobre!
El otro día le conté a Leito que quería emparejar el volumen de mis mp3, así cuando los escucho mezclados en el auto no tengo que andar subiendo o bajando el mismo para tener una experiencia auditiva placentera. Me recomendó usar normalize . En particular, decidí usar la versión normalize-mp3. Lo analicé un rato, y ví que tiene dos modos, mix y batch: mix: calcula el promedio de volúmenes de todos los temas, y normaliza cada archivo por separado para alcanzar este volumen. Este modo es ideal para cuando armamos un "compilado" a partir de distintas fuentes que están a distintos volúmenes batch: calcula el promedio de volúmenes de todos los temas, computa un sólo ajuste para llevar este promedio a lo deseado, y le aplica este mismo ajuste a todos los temas. Este modo es ideal para usar en las canciones de un mismo álbum, ya que el artista decidió que quizás un tema suene más fuerte que otro, y mantendríamos eso. Entonces, vamos a contar mejor qué es lo que quiero obtener, así se entiende cómo lo obtuve. Yo tengo, por ejemplo, toda mi colección de música que son tres directorios: SuiGeneris Kusturica IronMaiden (compilado) Los primeros dos directorios contienen los mp3 de dos CDs que compré y bajé a la compu, manteniendo los volúmenes originales. El tercero es un compilado que armé a partir de otros CDs. Estas canciones son (expresando el volumen en valor ficticio entre 0 y 100 para que sea más fácil hacer la cuenta): SuiGeneris/Tranquila.mp3 40 SuiGeneris/Rocanrol.mp3 60 Kusturica/Balada.mp3 70 Kusturica/Power.mp3 80 IronMaiden/BaladaPower.mp3 70 IronMaiden/TePartoElCoco.mp3 40 Como yo voy a escuchar estos álbumes mezclados, quiero que en general el volumen de los temas de IronMaiden, SuiGeneris y Kusturica sean similares, pero manteniendo las diferencias internas que se haya decidido en cada caso. Entonces, elegí una amplitud para todos (-6dB, por ejemplo, Leito me dijo que era un standard, aunque se puede usar -3db y que quede todo en general más alto), y llevar el promedio de cada álbum a esa amplitud: normalize-mp3 --mp3 --verbose --amplitude 6dB --batch SuiGeneris/* normalize-mp3 --mp3 --verbose --amplitude 6dB --batch Kusturica/* normalize-mp3 --mp3 --verbose --amplitude 6dB IronMaiden/* Corriendo al normalize-mp3 en cada directorio, considerando para el ejemplo que le estoy indicando "50" como volumen objetivo, el tipo hace lo siguiente: >>> (40+60) / 2 50 (como lo llevaría a 50 justo lo de SuiGeneris me lo deja sin tocar) >>> (70+90)/2 75 (para llevarlo a 50, tiene que bajar -25 lo de Kusturica) El caso de IronMaiden es más sencillo: como es un compilado y no es el caso de que el artista puso diferentes volúmenes para lograr efectos, se lleva todo al volumen indicado (fíjense que no tiene el --batch en el comando). ¿Por qué no uso --mix acá? Porque yo le estoy indicando qué volumen quiero, no que saque el promedio él. Finalmente, me dejaría: SuiGeneris/Tranquila.mp3 40 SuiGeneris/Rocanrol.mp3 60 Kusturica/Balada.mp3 45 Kusturica/Power.mp3 55 IronMaiden/BaladaPower.mp3 50 IronMaiden/TePartoElCoco.mp3 50 O sea, manteniendo las relaciones dentro de cada álbum, pero emparejando los promedios de los álbumes, y llevando lo compilado exactamente a eso. Analizando los resultados, luego, vi que en algunos temas (no revisé todos), pasó a recortarme sonido. O sea, lo amplificó de manera que algunos picos se van de rango, y eso distorsiona. ¿Se nota el efecto? Sí, abrí archivos con audacity y lo comprobé visualmente, porque la canción me sonaba mal al escucharla. Estuve viendo, y antes esta gente tenía un bug, que se suponía que estaba resuelto (parece que no del todo); teoricamente no debería recortar nunca. Por otro lado, encontré un parámetro "limiter": poniéndolo en 1 no limita nada (recorta cuando debe), y en 0 limita en todas las muestras. Más allá de que esto implicaría que con el valor default (cualquiera intermedio) recortaría en algunos casos (que es lo que me pasa a mí), si lo pongo en 0 nunca hace nada (me dice que la muestra original ya estaba normalizada). Concluí que no me sirve este programa. Borré todo, levanté el backup que había hecho, y pasé a probar con mp3gain . mp3gain, a diferencia de normalize, no rearma el mp3 con el nuevo volumen, sino que luego de analizar la canción y decidir el ajuste necesario, modifica un campo en la metadata del archivo. Este campo es utilizado por los reproductores de mp3 para ajustar el volumen, entonces el efecto es similar. Tiene la ventaja (contra normalize) que no hay ninguna pérdida de calidad porque no transforma el mp3 en wav y luego a mp3 de nuevo, pero tiene la desventaja que el control es más burdo, porque este campo sólo tiene 256 valores distintos. Por otro lado, mp3gain tiene una gran desventaja: no permite que uno le indique a qué volumen uno quiere llevar la música: el programa analiza lo que tiene que analizar, y lo equilibra a todo lo mismo, pero a un valor que él determinó como óptimo. Por lo que probé, baja el volumen aunque no sea necesario (queda rango dinámico para explotar), así que decidí no correrlo sobre toda mi música: solamente lo pasé en los compilados que había armado con canciones de distintas fuentes, para que me queden todos los temas de volumen parecido. La forma de usarlo es sencilla: mp3gain -r IronMaiden/* Con -r le estamos diciendo que aplique la ganancia "Track" automáticamente (todos los archivos al mismo volumen). Pero esto seguro que no puede estar del todo bien, porque no hace un análisis de todo y luego da los resultados normalizando a lo que más conviene en función del total; lo más probable es que sea por eso que lo baja demasiado de volumen, para trabajar sobre seguro en cada uno. Claramente, acá hay que experimentar con distintos valores, para ver cual nos conviene más. Y pensando en esto encontré easymp3gain , que es una interfaz gráfica sobre mp3gain , y nos permite analizar las canciones e intentar distintas ganancias viendo si clipea o no. Entonces, al final, retoqué mis compilados con esto para emparejarlos en volumen, y no hice nada sobre los discos originales que tenía. No es la mejor solución, pero sí lo mejor que pude hacer según el estado actual de los programas.
Fueron cuatro días, pero los tenía tan ocupados como pocas veces. Finalmente, decidí sacrificar el empezado PyWeek (en el que laburé en el arranque y algo en la semana), y me tomé el jueves para visitar a Agata, y el resto de los días para ir con familia a Junín. Agata estuvo un par de semanas en Argentina, y la fuimos a visitar un día de semana a la noche ni bien llegó. Pero debíamos pasar un rato más largo y relajado, así que apuntamos a ir uno de los días de semana santa. Como finalmente salió el viaje en familia a algún lado, la visita fue el jueves. Así que el primer día del finde largo lo pasamos en Padua, viendo jugar a Felipe y Lautaro (que se llevan un día de diferencia), y charlando mucho mucho. Como fuimos a la mañana, pudimos aprovechar bastante tiempo al aire libre, almorzamos, hicimos vagancia, etc. Un regio día con amigos, como quien dice. Ya casi al final del día decidimos hacer una foto del estilo de la anterior , y aunque los pequeños nos complicaron la operatoria y ya nos quedábamos sin luz, salió algo interesante... Directamente desde la casa de los padres de Agata salimos para Junín. Salimos ya anocheciendo, y llegamos bien entrada la noche a la Laguna de Gómez, a las afueras de la mencionada ciudad, donde nos esperaban Diana y Gustavo en una casita que habíamos alquilado para todo el fin de semana. Ellos habían ido más temprano ese día, y ya habían paseado algo, conocido, y lo más importante, preparado algo de comida que atacamos ni bien llegamos :). Así que morfamos algo, acomodamos las cosas, armamos nuestra cama y la cuna de Felu, y nos fuimos a dormir. Al otro día nos levantamos tempranito con Moni y salimos a pasear con Felipe por la costa de la laguna. Caminamos algo (aunque estaba más fresco de lo que pensábamos), y volviendo compramos algo para invitar al desayuno. Ya llegando al mediodía llegaron Karina, Pablo, Nahuel y la Tía Estela, que viajaban ese viernes. Llegaron justo cuando nosotros estábamos en el supermercado comprando cosas para almorzar, así que nos tuvieron que esperar un rato en los juegos cercanos hasta que llegamos. Viernes, sábado y domingo, la pasamos muy bien. El lugar es hermoso, tiene una laguna muy apta para la pesca (actividad en la que ninguno de nosotros incursionó), juegos para los más chicos (y para los no tanto), pequeños puestos de artesanías, etc. Uno de los días compramos carne e hicimos un asado bárbaro, al anochecer del día, en una parrilla que estaba en la casa. "Hicimos" no es el término más adecuado, realmente lo hizo Gustavo y nosotros lo ayudamos, así que las felicitaciones son para él. Anocheceres como ese invitan a la fotografía (teniendo especialmente en cuenta que alguien más cuida el asado), así que les dejo una postal: Una de las tardes hasta tuvimos tiempo de dejar a Felipe con Gustavo (Diana se estaba bañando, luego de que rescatara a Auca que se había tirado a la laguna), y fuimos con Moni a pegar una vuelta por el lugar en unos de esos carritos/bicicleta. Igual, no resistimos la tentación, y ya al terminarse el tiempo pasamos por la casita, agarramos al pequeño, nos sacamos unas fotos, y luego lo llevamos en el carrito la última cuadra que nos quedaba para devolver dicho vehículo. El domingo, partimos a eso de las 19hs para casa, y aunque nos agarró una congestión bastante fea al llegar a Chacabuco, el viaje de vuelta fue sin novedad (por otro lado, aprovechamos para desviarnos y pasar por el centro de Chacabuco, y pegar una mirada para ver cómo era). Esperemos que el año que viene se repita, ¡y con más familia!
Arrancó PyWeek, y estamos haciendo un juego en una semana. Y vos podés participar en el juego colaborativo más grande jamás creado! ¿Podés tipear? ¡Podés participar! Para cada nivel de conocimiento, hay una manera de crear niveles... podés participar incluso si nunca programaste, o si hiciste millones de juegos... podés participar si querés invertir 5 minutos o varios días... ¡esto es para todos! Entrá acá , registrate (tu nombre va a los créditos del juego, y el mail es por si te olvidás la clave), y empezá agregando niveles! El más sencillo es una trivia : tenés que pensar una pregunta y un par de respuestas, ¿te animás? Dale!
Uno de los bugs críticos que tenía en Enjuéwemela era el de internacionalizarlo/localizarlo. Este proceso (que tiene en inglés nombres tan complicados que se los refiere normalmente como i18n y l10n, deduzcan ustedes por qué) basicamente permite al programa mostrar todos los textos en el lenguaje del usuario. Obviamente, para que todos los textos de un programa estén en varios idiomas, la gente tiene que traducirlos, y aparte el programa tiene que mostrar los textos correspondientes en el lugar adecuado, en función del idioma del usuario. La forma de hacer esto está establecida desde hace varios años, y está armada especialmente para facilitar que colaboradores creen nuevas traducciones y se agreguen al sistema. Esta tecnología se conoce como Gettext , y se puede utilizar desde todos (o casi todos) los lenguajes existentes. Pero una cosa es utilizarlo, y otra es armar el programa para que pueda utilizarlo, y que se puedan agregar nuevas traducciones, etc. Recuerdo que cuando lo hice para Typus Pocus no salió fácil, y tuve que leer bastante. Casi me pongo a pensar nuevamente como era, pero se me prendió la lamparita y me acordé que en su momento había escrito en ese proyecto un procedimiento_locale.txt , así que lo tomé y usé. Para que estos pasos los puedan usar todos, los dejo acá. Pero ojo, no muestran como usar gettext desde tal o cual lenguaje (eso lo verán ustedes), sino cómo preparar los archivos y directorios para que luego puedan usar gettext desde sus programas. Por otro lado, los ejemplos son las lineas que tiré para Enjuéwemela, así que están orientados a Python, sepan adaptar. Entonces... Creamos el directorio para guardar nuestra estructura de traducciones: mkdir locale Editamos todos nuestros archivos y metemos todos los textos que queramos internacionalizar en la llamada a función _() . O sea, que si teníamos el texto "click here" y queremos que ese texto se internacionalice, tenemos que dejar _("click here") . Esto es vital para el próximo paso, y para el funcionamiento luego, ya que _() será la función de gettext que reemplazará lo que está escrito en el código con lo que se mostrará al usuario en función de su lenguaje. Generamos el archivo .pot con todos los textos que utilizamos en nuestro programa. Para ello utilizamos xgettext y le pasamos todos los .py que usamos (esta utilidad revisará las fuentes y tomará los textos que tienen el _() que agregamos antes): xgettext *.py --output=locale/core.pot Este .pot es el archivo template que distribuiremos a todos aquellos que deseen traducir nuestro programa. Antes de distribuirlo, deberíamos abrirlo con un editor y completar ciertos campos que están listos para ser rellenados (título, autor, etc.). La preparación propiamente dicha del sistema ya está completa, los pasos a continuación muestran qué hacer con el .pot si queremos generar la traducción para un nuevo lenguaje. Generamos el .po , renombrando la base del archivo para incorporarle las dos letras del idioma que estamos utilizando. Si es la primera vez, sólo copiamos el .pot al mismo... cd locale cp core.pot core_es.po ..., pero si ya teníamos el .po de antes y ahora tenemos un nuevo .pot (porque aparecieron nuevos textos en el programa, o cambiaron los que estaban de antes), tenemos que mergear los archivos de la siguiente manera: cd locale msgmerge core_es.po core.pot > /tmp/po_temporal mv /tmp/po_temporal core_es.po El próximo paso es abrir el core_es.po con un editor de texto y traducir todas las cadenas. Luego, tenemos que compilar el .po al .mo , que es el archivo que levantará realmente el sistema gettext : msgfmt core_es.po Y finalmente, movemos el archivo compilado a un directorio que tiene que seguir la estructura preestablecida aquí mostrada (prestar atención al renombre del archivo en sí, y a que en el directorio está el idioma utilizado en la traducción): mkdir -p es/LC_MESSAGES mv messages.mo es/LC_MESSAGES/core.mo Como último detalle, quiero aclarar que hay muchos editores especializados que muestran los .po y .pot uno al lado del otro, especialmente útiles cuando los programas a traducir son muy grandes o contienen muchos textos, pero que realmente uno se puede arreglar con un editor de textos común y corriente.
Fuí gentilmente invitado a dar una charla en dicho evento , en la Universidad Católica de Lima, Perú. Llegué el lunes bien tarde, y me volví el sábado al mediodía para Argentina. En el medio esta buena gente me trató más que bien: me sacaron siempre a almorzar/cenar, me llevaron/trajeron a la Universidad, etc. (no solo los organizadores, sino también Nico Valcarcel, compañero de Canonical, que se re portó). Lamentablemente no pude pasear demasiado por Lima... aunque era la primera vez que iba me quedé sin ver nada más que lo que espié desde taxis y coches, porque tenía que trabajar durante mañana y tarde (el evento era a la noche). Es que era esto o no ir para nada, porque estamos trabajando contra reloj por la liberación de Lucid Lynx y no era momento de tomar días de vacaciones). Pero la visita me sirvió para conocer a Fernando San Martín, de Chile, que dio una charla muy interesante sobre la importancia de los proyectos de código abierto en la formación profesional, y con el que charlamos muchísimos temas de software y demás (y también de los lamentables sucesos sísmicos acaecidos recientemente en su hogar). También pude conocer y charlar con otras personas de la comunidad peruana, como Rosa María, Marcos, Diego, Antonio, y tantos otros. Mi presentación fue sobre Python en el mundo real , y la verdad es que salió muy bien (siendo la primera vez que la daba)... la gente no se durmió, se mostró muy interesada, y al terminar hubieron decenas de preguntas, no sólo en el espacio que correspondía, sino afuera del auditorio, y en todo el camino hacia la salida (ya cuando la gente de la Universidad nos echaba porque debían cerrar). Algunos comentarios sobre Lima: Manejan mal, *muy* mal. Demasiado rápido, saltando de carril en carril, frenando demasiado cerca de los otros autos, cruzándose a otros que quieren pasar primero, siempre haciendo luces y tocando bocina. Creo que escuché más bocinazos en estos cuatro días que en el resto de mi vida... Hay muchos casinos. Habré visto unos 30 distintos, desde pequeños locales a megacasinos todos iluminados. Según me comentaban, es porque no hay una legislación fuerte al respecto, así que hacen medio lo que quieren. La cocina es buenísima, todo muy rico y no hubo nada que no me haya gustado. Encima, siempre me invitaron a probar muchos platos con mucha variedad... comí más que demasiado (y bebí otro tanto), la verdad, porque estuvo todo muy rico. Ahora ya respiro tranquilo, pero en algún momento pensé que me estaban engordando y que me iban a carnear en el cierre del evento... Me queda pendiente visitar la ciudad desde un punto de vista más turístico, seguramente volveré en el futuro. Muchas gracias a Rosa María Orellana y todo su equipo de trabajo por este evento.






