December 2009 - Posts
En mi anterior post describí algo de la implementación de canales y “goroutines” en AjSharp, mi intérprete de un lenguaje de scripting. Quisiera hoy mostrar algunos ejemplos del uso de esos canales y rutinas lanzadas en paralelo.
Primero, recordemos el código simple:
channel = new Channel();
go channel <- 10;
result = <- channel;
En la primera línea, se crea el canal. Luego, el comando go ejecuta en otro thread el envío del valor 10 al canal. En la última línea se toma el valor desde el canal, y se coloca en la variable result. channel <- 10 es “syntax sugar” para channel.Send(10). <-channel es una expresión (devuelve un valor, no es un comando, se puede colocar en cualquier lugar donde se espera una expresión), que codifica channel.Receive(). Las operaciones Send y Receive son bloqueantes: cuando enviamos un valor a un canal, si no hay otro thread leyendo, el thread que envía queda bloqueado, y viceversa. Esta conducta nos da una forma de coordinación entre el productor de valores para el canal y el consumidor de esos valores. Tengo que mejorar el código de implementación para soportar que varios productores (en distintos threads) puedan enviar valores a un mismo canal. Lo mismo para varios consumidores.
Podemos usar el canal varias veces:
channel = new Channel();
go for (k=1; k<=5; k++) channel.Send(k);
for (j=1; j<=5; j++)
result = result + channel.Receive();
que en notación de operadores, es lo mismo que:
channel = new Channel();
go for (k=1; k<=5; k++) channel <- k;
for (j=1; j<=5; j++)
result = result + <-channel;
En vez de generar solamente cinco valores, podemos escribir una goroutine que escriba todos los números en un canal:
channel = new Channel();
running = true;
k = 0;
go while(running) channel <- k++;
for (value = <-channel; value<=10; value = <-channel)
PrintLine(value);
La goruoutine no ejecuta por siempre: su ejecución es controlada, indirectamente, por el thread principal, usando las operaciones bloqueantes del canal. Si la goroutine intenta escribir en el canal, pero no hay quien esté leyendo, entonces la goroutine se bloquea.
Más interesante, podemos usar varios canales para comunicar distintos subprocesos:
channel = new Channel();
running = true;
k = 0;
go while(running) channel <- k++;
function filter(in, out)
{
while (true)
{
value = <-in;
PrintLine("Received in filter " + value);
if (value % 2)
out <- value;
}
}
odds = new Channel();
go filter(channel, odds);
for (number = <-odds; number <= 7; number = <-odds)
PrintLine("Received in main " + number);
running = false;
Este código crea un canal, y un thread paralelo que envía números naturales por ese canal. Otro thread toma valores del primer canal, filtra los impares (rechazando los pares) y los envía a un segundo canal. El thread principal toma valores de este segundo canal, e imprime los primeros resultados.
Vemos que podemos crear, conectar y usar muchos canales. El ejemplo que sigue (inspirado en el que brinda la gente de Google para el Go language ver http://golang.org/doc/go_tutorial.html#tmp_346) imprime los números primos menores de 1000:
numbers = new Channel();
running = true;
k = 1;
go while(running) { k++; numbers <- k; }
function filter(in, out, prime)
{
while (true)
{
value = <-in;
if (value % prime)
out <- value;
}
}
function makefilter(channel, number)
{
newchannel = new Channel();
go filter(channel, newchannel, number);
return newchannel;
}
channel = numbers;
number = <-channel;
while (number < 1000)
{
PrintLine("Prime " + number);
channel = makefilter(channel, number);
number = <-channel;
}
running = false;
Esto planeando agregar un comando done, para parar las goroutines que quedaron andando (una idea más liviana es que las goroutines se lanzen en threads de background). Por ahora, no necesité esa característica. Tengo que estudar el lenguaje Go más en detalle: al parecer, las goroutines se ejecutan en un solo thread, pero no estoy seguro. Para leer más:
http://scienceblogs.com/goodmath/2009/11/the_go_i_forgot_concurrency_an.php
Sutil tema: en el código de arriba, escribí una función makefilter. En mi primer intento, escribí ese código en línea, no como función, directamente dentro del ciclo while, pero tuve un problema: la rutina lanzada por go tiene acceso a las variables que estan en su “lexical scope”, y entonces, cuando la go ruitina accede, por ejemplo, a la variable channel, ese valor podría no ser el mismo que tenía cuando se pasó por el go (la rutina de dentro del go se ejecuta en paralelo), el código externo podría haberlo cambiado. La solución: escribir una función makefilter (que no es otra cosa que un lambda con nombre) para recibir y mantener el valor original de channel y otros valores, sin verse afectados por la rutina principal. En el ejemplo del lenguaje Go que cité arriba, el autor escribe la manipulación del canal en línea, sin apelar a una rutina (por lo menos en el primer ejemplo que muestra), así que debería estudiar más en detalle este tema.
Pueden bajar el código actual de AjSharp desde http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjLanguage. Los ejemplos presentados acá están en AjSharp.Tests/Examples y en AjSharp.Console/Examples (AjSharp.Console es una aplicación de consola que permite ejecutar programas AjSharp leyendo archivos o ingresando el código interactivamente).
Me gusta cómo queda el código del ejemplo de números primos en pastie http://pastie.org/758175 ;-)
Mis próximos pasos en canales y gorutinas: implementarlos y usarlos directamente en C# (ayer escribí un spike), y agregar a un proyecto como el AjAgents o similar. Pueden ver el spike en:
http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjConcurr
y el código de ejemplo de números primos en C# directo:
http://pastie.org/761916
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Hace dos años ya, estuve explorando Microsoft Robotics, y su librería CCR (Concurrency and Coordination). Esta tiene la implementación una port: podemos enviar un objeto por el port, y recibirlo y procesarlo en otra pieza de código, que puede ejecutarse en otro hilo de ejecución. También tiene la capacidad de ejecutar ambas partes en diferentes máquinas, una forma de conectar aplicaciones distribuidas. Yo escribí sobre el tema en:
Distributed Agents using DSS/VPL
Agentes Distribuidos usando DSS/VPL
Agentes Distribuidos y Fractales usando DSS/VPL
Genetic Algorithms with AjAgents and Concurrency and Coordination Runtime (CCR)
Algoritmos Genéticos con AjAgents y Concurrency and Coordination Runtime (CCR)
CCR posts (English)
Posts sobre CCR en español
Todo esto, me llevó a encontrarme con el concepto de canal: Channel programming (Wikipedia) y este año, leí sobre el nuevo lenguaje de Google, el lenguaje Go: http://golang.org. Pueden leer sobre Go y sus capacidades de manejo de concurrencia (go routines, channels) en: http://golang.org/doc/go_tutorial.html#tmp_346
También comencé a leer sobre proyecto Axum de Microsoft: http://en.wikipedia.org/wiki/Axum_%28programming_language%29
Con toda esta base, el último sábado agregué soporte de canales y goroutines en mi intérprete AjSharp (otros posts AjSharp interpreter). Pueden bajar y ver la versión actual desde http://code.google.com/p/ajcodekatas en trunk/AjLanguage
Primero, agregué un tipo nativo .NET Channel (a mejorar: agregar soporte para que el canal pueda soportar varios send y receive desde más de un thread):
public class Channel
{
private AutoResetEvent sethandle = new AutoResetEvent(false);
private AutoResetEvent gethandle = new AutoResetEvent(false);
private object value;
public void Send(object value)
{
this.gethandle.WaitOne();
this.value = value;
this.sethandle.Set();
}
public object Receive()
{
this.gethandle.Set();
this.sethandle.WaitOne();
object result = this.value;
return result;
}
}
Cuando se envía un objeto a un canal, el thread que lo envía se bloquea hasta que otro thread lea el canal (pienso agregar un QueueChannel, donde se puedan enviar varios objetos, a guardar en una cola, sin para los threads; supongo que la cola tendrá un tamaño limitado, para ir auto-coordinando los productores y consumidores de objetos del canal).
Siguiendo las ideas de goroutines en el lenguaje Go, agregué un nuevo comando en AjSharp: go <command> (ok, no mucha creatividad aquí… ;-)… igual hay que aclarar que los goruotines en Go tienen muchas más características que las que implemento acá). Esta nueva palabra lanza el comando en un thread separado, que comparte las variables del original, como en este ejemplo (recordemos que AjSharp tiene acceso a los objetos y clases nativas de .NET):
handle = new System.Threading.AutoResetEvent(false);
one = 0;
go { one = 1; handle.Set(); }
handle.WaitOne();
result = one;
Todo esto se agregó a la máquina de ejecución de AjSharp (por ejemplo, Channel es un tipo ya declarado dentro de la máquina, sin necesidad de usar el namespace completo), podemos usar entonces:
channel = new Channel();
go channel.Send(10);
result = channel.Receive();
Luego de tener esto andando, modifiqué algo más. Fue simple agregar “syntax sugar” al parser de AjSharp para que
<- channel
sea igual a
channel.Receive()
y que
channel <- value;
sea una forma de escribir:
channel.Send(value);
Entonces, el ejemplo anterior se puede escribir como:
channel = new Channel();
go channel <- 10;
result = <- channel;
En otro post, describiré algunos usos de estas características, con algún detalle de implementación. Ver el código actual en:
http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjLanguage
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Estoy escribiendo un intérprete no tipado con sintaxis tipo C#, que bauticé AjSharp. Hace un tiempo escribí sobre este proyecto de código abierto en:
AjSharp Programming Language a C#-like Dynamic Language
AjSharp: un lenguaje dinámico en C#
Pueden bajarse la versión actual desde http://code.google.com/p/ajcodekatas en trunk/AjLanguage (AjLanguage define el árbol de ejecución del intérprete, AjSharp tiene un parser, un lenguaje definido para construir ese árbol; la idea es colocar otros parsers sobre AjLanguage, por ejemplo, AjBasic).
Ayer sábado, agregué una nueva característica, la definición de un objecto. Ya de antes, AjSharp soporta la definición de una clase dinámica:
class Person
{
var Name;
var Age;
function AddYears(years)
{
this.Age = this.Age + years;
}
}
Pueden crear un objecto usando:
adam = new Person();
adam.AddYears(800);
adam.Name = "Adam";
El objeto creado es dinámico: se le pueden agregar variables de instancias y métodos, en cualquier momento:
adam.LastName = "unknown";
adam.EyeColor = "brown";
adam.SayHello = function() { PrintLine("Hello"); };
Pueden crear objetos, con esta notación, inicializando su estado:
adam = new Person() { FirstName = “Adam”, LastName = “Genesis”, Age = 800 };
Y hasta pueden definir un objeto sin tener una clase asociada:
dynobj = new { Name = “Adam”, Age = 800 };
Esto es equivalente a hacerlo más “programáticamente” así:
dynobj = new DynamicObject();
dynobj.FirstName = “Adam”;
dynobj.LastName = "Genesis”;
dynobj.Age = 800;
dynobj.FullName = function() { return FirstName + “ “ + LastName; }
Esto estaba implementado desde hace meses. Ayer agregué la notación:
object Adam
{
var Name = "Adam";
var Age = 700;
function AddYears(years)
{
this.Age = this.Age + years;
}
}
Adam.AddYears(100);
donde se puede definir un objecto único, dándole estructura, conducta y nombre.
La idea de AjLanguage es que pueda acceder a todas las clases y objetos del framework subyacente (en este caso, .NET, pero está pensado para ser reescribible sobre Java, si fuera necesario, claro, cambiando cualquier referencia a tipos nativos):
ds = new System.Data.DataSet();
dinfo = new System.IO.DirectoryInfo(“.”);
foreach (fi in dinfo.GetFiles())
{
PrintLine(fi.FullName);
}
Desde ayer, seguí implementando constructores. Tengo pensado definir visibilidades privadas y públicas (por ejemplo, las variables y métodos de instancia que comiencen con minúscula, hacerlas automáticamente privadas). También agregar propotipos, como en Javascript, lo que permitiría implementar cosas similares a los métodos de extensión de .NET.
Pero si van hoy al trunk, encontrarán que estuve implementando canales, como en en lenguaje Go de Google.
channel = new Channel();
go for (k=1; k<=5; k++) channel <- k;
for (j=1; j<=5; j++)
result = result + <-channel;
Pero eso dará para otro post más detallado. Con esa característica quiero explorar temas como programación reactiva, agentes, actores, shared transactional memory, ver:
http://clojure.org/Agents
http://en.wikipedia.org/wiki/Actor_model
http://en.wikipedia.org/wiki/Axum_%28programming_language%29
Por ejemplo, sería interesante que los canales comunicaran no sólo dos códigos en paralelos, sino máquinas diferentes. Y definir esas máquinas en tiempo de deployment, sin cambiar el código del programa. Podría reescribir los ejemplos de Distributed Agents using DSS/VPL o Genetic Algorithms with AjAgents and Concurrency and Coordination Runtime (CCR)
Como verán, me estoy divirtiendo!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Una de las prácticas que siempre intento “vender” a cualquiera involucrado en el desarrollo de software, es la práctica de Test-Driven Development. Una vez que se practica TDD, no quieren volver atrás. Es una forma de programar con tanta recompensa y gozo asociados, que me siento incómodo si no lo usa cuando escribo software real.
Gracias a un tweet de ayer de @jjfalcon, descubrí este ejemplo, en Youtube, del usuario objarni. El usa Ubuntu, programando en Python, usa pyTDDemon para ver inmediatamente el resultado de los tests.
Implementa algo sencillo: código que dado un string con una URL, identificar el protocolo, el dominio, y el recurso que está contenida en esa dirección. En TDD, se va escribiendo el test, el código que pasa el test, y se va progresando de a poco. No hace falta escribir el código correcto y completo desde el principio. Como en otras tantas actividades, el “baby-step”, el “pequeños pasos” de avance, nos ayuda para ir incrementalmente produciendo el resultado esperado.
Noten el ciclo rojo-verde-refactor, el código mínimo que se agrega en cada tests (a veces, retornando valores puestos a mano, sólo para pasar los tests), refactorizando el test si hay código duplicado, las micro-decisiones de diseño que se van tomando, etc… Excelente trabajo para mostrar en video!
Habría tanto para comentar de TDD. Por ahora, dos recursos. He “tagueado” más videos sobre TDD, en mi delicious:
http://delicious.com/ajlopez/tdd+video
Los enlaces que colecciono sobre TDD:
http://delicious.com/ajlopez/tdd
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Además de la reunión de hoy viernes ALT.NET Hispano VAN (Reunión Virtual): Automatizar mañana sábado 19 de diciembre (18 GMT, 3 de la tarda acá en Buenos Aires), tendremos otra reunión virtual, organizada por la comunidad ALT.NET Hispano, esta vez sobre el tema Domain-Driven Design.
Esta vez voy a hacer la presentación inicial. Mi idea es plantear los temas de DDD, desde un poco de historia, llegando a las ideas de Eric Evans, viendo cómo se puede implementar en .NET, con algún código de ejemplo. Tenemos que ver:
- Dominio
- Modelo
- Modelo de Dominio
- Capas sugeridas por Evans
- Implementando el Dominio
- Entities, Value Objects, Services, Repositories, Factories
- Persistencia, principal tema de infraestructura
- Ejemplo de código abierto
Creo que llegamos en tiempo para presentar conceptos de Command Query Separation aplicadas en .NET.
Gracias a Jorge Gamba que también escribió [VAN] Viendo la luz en “Domain-Driven Design” (DDD).
Más información sobre cómo asistir a la reunión virtual, software necesario, enlaces: http://altnet-hispano.pbworks.com/Descripcion-de-Reuniones
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Este viernes 18 de diciembre, habrá una nueva VAN (reunión virtual, des-conferencia) organizada por la incansable comunidad de ALT.NET Hispano. Esta vez el tema es la automatización, y la presentación principal estará a cargo del bueno de Martín Salías (@MartinSalias). Aunque es en viernes, en lugar de sábado, la hora es la habitual, 18 GMT (acá en Buenos Aires, 3 de la tarde). Hace un tiempo, Martín escribía en la lista del grupo, sobre el temario que va a encarar:
me gustaría encarar un tema … que es:
"antes de hacer algo por cuarta vez, automatízalo".
Creo que es muy común caer en repetición de tareas, y siempre tenemos oportunidad de automatizarlas, lo que brinda muchas ventajas:
- ahorra trabajo (productividad)
- optimiza tiempos (siempre la máquina va más rápido)
- aumenta la previsibilidad
- nos fuerza a ser más consistente en los procesos (tenemos que respetar cierto protocolo)
- facilita la mejora (es fácil agregar cosas en un proceso automático)
- permite obtener métricas fáciles de lo que se automatiza
Esto aplica a montones de cosas, desde:
- mejora de APIs y abstracciones (para mantenernos DRY)
- templates y generadores de código (para que el Maestro sea felíz) ;-)
- scripting para automatizar procesos de build, deployment, testing, etc
- encadenamiento (o workflow) de scripts
Temas/métodos puntuales:
- Scripting, scripting, scripting (Ruby, Python, Powershell, etc)
[se le preguntó si también habrá Integración Continua]
Digamos que a lo que quiero ir es a automatización mucho más allá del build server. Pero sobre éste nosotros tenemos además de compilación y
testing, todo nuestro proceso ISO (reporte a cliente, verificación de drops, etc).
Mi idea de todas maneras es contarlo a nivel más general y seguramente después se puede hacer otra mostrando como configurar CC.Net o Team
City, por ejemplo, cómo disparar diferentes tests (units, integration, code analysis, source analysis, dependencias, cálculo de coverage, etc) y cómo
tener alarmas, reportes, estadísticas, etc. Tal vez hasta alguien se anime a mostrar esto con TFS. :)
Más información sobre cómo asistir a la reunión virtual, software necesario, enlaces: http://altnet-hispano.pbworks.com/Descripcion-de-Reuniones
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
El bueno de Juan Gabardini anuncia en la lista Foro Agiles, un nuevo curso de Scrum de Tobias Mayer en Argentina. Copio el mensaje original:
Tobias Mayer facilitará un taller de un día en Buenos Aires, Argentina. Está orientado a Scrum Masters y agile coaches.
Para los que no lo conocen, Tobias dió el primer curso de CSM en Argentina, allá por el 2006. Luego de eso ha venido varias veces (no se cuantos, pero dió al menos 5 CSM en Bs As). ….
Se explorarán los principios y valores de Scrum. Este taller no se focaliza en las prácticas (se asume que los participantes tienen familiaridad con ellas) y explora Scrum en un nivel más profundo y humano. A través de una serie de juegos, ejercicios interactivos y conversaciones facilitadas, se adquirirá una comprensión más profunda del nuevo esquema de pensamiento requerido para hacer Scrum. Esto no es sobre metodologías o procesos, es sobre divertirse
Cuándo: 28 de enero 2010
Dónde: Perú 375, 1er piso (Southworks)
Costo: usd 220 + IVA
Registración: http://tinyurl.com/tobiasBsAsWorkshop
Este evento es organizado por Agiles Argentina y Agilar Argentina
Este evento será dado en inglés. Aunque por el tipo de evento no es imprescindible el hablar y entender perfectamente, ya que el resto de los que asistimos podremos dar una mano. Va el detalle en inglés.
Process/Mechanics
Scrum is quickly being seen as the de facto way of starting out down an Agile pathway. People see it as a quick and easy way in. The problem is that Scrum is very easily misunderstood. There are a multitude of Scrum Facades in place around the world, companies who claim to be doing Scrum because they have people with the titles of “Scrum Master” and “Product Owner”, have daily meetings, maybe even planning meetings, reviews and retrospectives, keep a backlog of work and show some sort of burn down graph each sprint.
Underneath the facade though, the same old command and control beast lurks, the same old fear and CYA behavior. Nothing has essentially changed. So what is missing? I believe the spirit of Scrum is missing, the essence of change.
Scrum is not just a framework and a set of roles, meetings and artifacts. Scrum is a way of being that is utterly different from any previous way of working that we have encountered in the software industry. To do Scrum — to really do Scrum — requires an absolute shift in the way we think and act.
Scrum relies on some core principles:
— Empiricism
— Self-Organization
— Collaboration
— Prioritization
— Rhythm
and some essential values:
— Courage
— Trustfulness
— Transparency
This session will allow Scrum practitioners to reach the next level of Scrum by exploring some of these underlying foundations in a highly experiential way. The session will consist of a series of interactive exercises and facilitated discussion designed to help participants not just understand, but embody these principles and values at a deep level.
I create and/or adapt new games frequently, the majority require no props, and usually require the participants to be on their feet. Most have simple formats and can be easily remembered. None of them have pre-determined outcomes: they are all about self-discovery. For more detailed information on the kinds of games and interactive exercises I’ll use for this session please follow one or more of these links to descriptions of sessions I have run previously.
This session is intended as a taster and it is hoped participants will be encouraged to explore more deeply the human interaction foundations of Scrum once they leave the conference.
Learning outcomes
Ya comenté sobre el bueno de Tobias en:
Tales from the Scrum: La esencia de Scrum
Tales from the Scrum: Un día en el equipo
Tales from the Scrum: El corazón de Scrum
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Este sábado 12 de diciembre, 19 GMT (4 de la tarde aquí en Buenos Aires) de nuevo tenemos VAN (Reunión virtual, des-conferencia) organizada por la comunidad de ALT.NET Hispano.
(Más información sobre cómo asistir a la reunión virtual, software necesario, enlaces:
http://altnet-hispano.pbworks.com/Descripcion-de-Reuniones
)
Esta vez el tema será Prism (Composite Application Guidance para Windows Presentation Foundation y Silverlight). La introducción estará a cargo del bueno de @juliandominguez, que nos comenta en la lista de ALT.NET Hispano:
La idea de este próximo sábado es presentar sobre Prism (o Composite Application Guidance for WPF and Silverlight para los que prefieren el nombre real pero aburrido).
¿Qué es Prism de patterns & practices y qué desafíos resuelve?
¿Qué beneficios les brinda a arquitectos, desarrolladores y a la interacción con diseñadores?
En esta sesión mostraré cómo Prism nos ayuda a trabajar en equipos distribuidos, no distribuidos, grandes o pequeños, con requerimientos cambiantes, aplicando conceptos como TDD y patrones de UI como Model View ViewModel (MVVM). También voy a mostrar cómo nos ayuda a reusar código que funcione en WPF y en Silverlight.
Vamos a estar viendo los beneficios que nos trae Prism a la hora de construir una aplicación compuesta, como así también en qué (lio?) nos metemos cuando queremos usar Prism en una aplicación que no lo amerita.
Espero que les resulte muy interesante a quienes no conocen Prism y tienen pensado empezar un proyecto en WPF o Silverlight.
Sé que normalmente las VAN suelen ser a las 18:00 GMT, pero debido a mi horario (actualmente estoy en Redmond), preferiría que sea las 19:00 GMT. Esto sería el sábado 12/12.
Así que la reunión será este sábado a las 19GMT (no a las 18GMT como otras veces).
Mi colección de enlaces sobre Prism:
http://delicious.com/ajlopez/prism
Otros interesantes:
http://delicious.com/ajlopez/mef
http://delicious.com/ajlopez/mvvm
http://delicious.com/ajlopez/silverlight
http://delicious.com/ajlopez/wpf
(especialmente si agregan examples o tutorial, como http://delicious.com/ajlopez/mef+example)
Si es la primera vez que topan con el término VAN, les recuerdo:
Si no conocen qué es una reunión VAN, pueden consultar VAN meetings. Para ver cómo se desarrolla una VAN de ALT.NET Hispano, y qué software necesitan para asistir, ver Descripcion-de-Reuniones-VAN. Pueden ver el historial de anteriores reuniones VAN (visiten las que dieron, por ejemplo, sobre NHibernate, WPF y demás) (yo participé en VAN sobre Scrum y en otra sobre generación de código). También pueden suscribirse para proponer nuevos temas, y colaborar con la comunidad. Si no pueden asistir a ésta VAN, seguramente quedará publicada más adelante, con video incluido.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Bueno, en realidad, no los Rolling Stones. Solamente Keith Richards, y no el de los Rolling, sino Keith Richards presidente de Keith Richards Consulting. Encuentro en un post de Gojko Adzic un post que comenta una charla de KRC:
Eight interesting techniques to test how a project is going
Es un muy interesante post, déjenme escribir esas técnicas, para saber si el proyecto y el equipo están en buena forma, sea que estén siguiendo Scrum o no. Esta es mi propia traducción de ese texto:
- 1. ¿Puede cualquier miembro del equipo escribir el objetivo del proyecto en una nota post-it con marcador grueso? Si no pueden, el final del juego no está claramente definido ni entendido por todos
- 2. Acérquese a un colega en su trabajo, y pídale ayuda para algo cualquiera. Vea cómo reacciona. Si encuentra una respuesta fría, la persona no está muy contento con su trabajo. Richards aconseja armar equipos con “aquellos que respondan ‘puedo’”. Esa gente mejorará la comunicación y el espíritu de equipo en su proyecto.
- 3. Cuando una fase del proyecto está oficialmente “hecha” (done), pregúntese a sí mismo: “¿Es seguro seguir adelante?”. Si esta pregunta le provoca una mala sensación en las tripas, es que no están listos todavía para avanzar a la siguiente etapa.
- 4. ¿Cuántos de sus proyectos terminan con una seria revisión del proyecto? Esto es, según Richards, crucial para la mejora de su organización. Permite prevenir errores repetidos y compartir conocimiento entre los equipos (yo agrego que, si trabaja en una organización con varios proyectos y equipos, tendría que haber comunicación entre equipos DURANTE los proyectos, comentando bloqueos, avances, hallazgos, problemas y soluciones; unas buenas reuniones periódicas con presentaciones timeboxed pueden ser un camino a seguir).
- 5. ¿Cómo reacciona la gente de su equipo cuando el cliente dice “cambié de idea”? Si reaccionan negativamente, el sistema que están construyendo no es tan flexible como debiera.
- 6. Pregúntele a alguien que le comente el estado actual de una tarea, y luego cállese 10 segundos; no hagan nada para provocar una respuesta. Si la persona se muestra insegura o nerviosa sobre algo, seguramente comenzará a comentarlo. Si se mantiene en silencio, las cosas van bien (este punto lo discutiría: debería haber comunicación y visibilidad sin necesidad de llegar a este tipo de “trick”).
- 7. ¿Conoce cuánto tiempo se empleó en la última iteración en pruebas? Si no puede estimarlo, no está tomando buenas métricas del proyecto. Tomar métricas de este tipo, dice Richards, es crucial para hacer estimaciones realistas (nota mía: ojalá tuviera un peso por cada vez que alguien en un equipo estimó una tarea SIN tener en cuenta pruebas, verificación, etc.; pongan atención a esto).
- 8. Tome un documento de su proyecto, usado durante una presentación. Si atrás hay diagramas dibujados a mano, señal que el documento no está claro, y necesitó de esa ayuda para ser explicado.
Me quedo principalmente con los puntos 1, 2, 3, 5 en primer lugar. Luego 7, 4.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Este sábado 5 de Diciembre, 18 GMT/UTC (3 de la tarde por aquí en Buenos Aires), habrá otra des-conferencia virtual de la comunidad ALT.NET Hispano. El tema será productividad, más específicamente Get Things Done (GTD) (ver también Consigue hacer el trabajo). La presentación inicial estará a cargo de Jeroen Sangers:
http://jeroensangers.com/
@jeroensangers
Este es el temario de Jeroen:
Mi presentación va más que nada sobre Getting Things Done y consiste
de tres partes:
1. Control: un flujo de trabajo para controlar tus acciones
2. Perspectiva: dar dirección a todo lo que haces
3. Consejos prácticas para implementar un sistema de productividad
GTD se populariza con un libro de David Allen. Pueden leer la descripción de GTD en el sitio de Allen:
What is GTD?
Ahí leo:
Sophisticated without being confining, the subtle effectiveness of GTD lies in its radically common sense notion that with a complete and current inventory of all your commitments, organized and reviewed in a systematic way, you can focus clearly, view your world from optimal angles and make trusted choices about what to do (and not do) at any moment. GTD embodies an easy, step-by-step and highly efficient method for achieving this relaxed, productive state. It includes:
- Capturing anything and everything that has your attention
- Defining actionable things discretely into outcomes and concrete next steps
- Organizing reminders and information in the most streamlined way, in appropriate categories, based on how and when you need to access them
- Keeping current and "on your game" with appropriately frequent reviews of the six horizons of your commitments (purpose, vision, goals, areas of focus, projects, and actions)
Pueden encontrar una buena descripción (con diagrama incluido, como el que aparece en el libro original) de GTD y una relación con los “cuadrantes de Covey” (me gusta recordar al creador de ese concepto, que es la matriz de Eisenhower).
Mis enlaces sobre GTD, y productividad:
http://delicious.com/ajlopez/gtd
http://delicious.com/ajlopez/productivity
Bueno, ya envíe varios posts sobre las VAN de ALT.NET Hispano, pero les recuerdo:
Si no conocen qué es una reunión VAN, pueden consultar VAN meetings. Para ver cómo se desarrolla una VAN de ALT.NET Hispano, y qué software necesitan para asistir, ver Descripcion-de-Reuniones-VAN. Pueden ver el historial de anteriores reuniones VAN (visiten las que dieron, por ejemplo, sobre NHibernate, WPF y demás) (yo participé en VAN sobre Scrum y en otra sobre generación de código). También pueden suscribirse para proponer nuevos temas, y colaborar con la comunidad. Si no pueden asistir a ésta VAN, seguramente quedará publicada más adelante, con video incluido.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Gracias a la gente del Microsoft User Group de Argentina, ayer miércoles 2 de diciembre estuve dando una jornada de Scrum teoría y práctica, de todo un día. Con unos treinta asistentes, estuvimos viendo temas como el manifiesto ágil, y las ideas que sustentan Scrum en particular. Así como también los roles, artefactos, reuniones, que se manejan en este marco de trabajo. Discutimos tópicos como contratos ágiles, relación con el cliente, la importancia del product owner, la auto-organización del equipo, el “ownership” que tienen que ganar, la idea de trabajar a un ritmo razonable, el “entrar en flujo”, Product backlog vs Sprint Backlog, y el clásico Chanchos y Gallinas.
Para mí, fue una grata experiencia: es uno de los cursos donde veo que más puedo aportar, y donde podemos practicar algo que considero muy importante conocer como es Scrum. Veo que la necesidad de tener equipos ágiles es creciente, no sólo en el desarrollo de software, sino en actividades en general. La labor en equipo permite llegar a objetivos que son más difícil de lograr individualmente o en simple grupo (vean que distingo entre equipo y grupo). Hay que estudiar más en detalle cuáles son los factores que hacen que Scrum funcione (me basé mucho en la idea de No somos vulcanos): hay un bias hacia mostrar los casos de éxito en la comunidad ágil, y no comentar los fracasos. Hay que pasar de la evidencia anecdótica a un fundamento más firme, no porque el marco de trabajo en sí lo necesite, sino para poder aplicarlo mejor, entender mejor en qué circunstancias funciona, y en cuáles se complica.
La parte teórica ocupó la mañana, pero ya después los asistentes se separaron en cuatro grupos, y comenzaron a trabajar en desarrollar un entregable, en dos sprints de 3 días de 10 minutos cada día. Fue una experiencia interesante: fuimos viendo cómo mejorar las reuniones, la precisión del backlog, los acuerdos con el product owner para los entregables de Sprint Review, el reparto de trabajo, la mejor partición de las tareas en el Product Backlog, y más.
Prometí publicar un post con los recursos que mencioné en el curso. Acá van los enlaces y bibliografía, que son similares a los que ya publiqué hace unos días para otros cursos dictados, pero para más comodidad, los concentro de nuevo en este post:
Reunión virtual de Scrum, con video (gran parte de la teoría vista en el curso está en este video) (ahí están los enlaces que presento acá).
Presentación usada en el curso ScrumSpanish.pptx
Pueden usar esta presentación compartida (en varios idiomas):
A Reusable Scrum Presentation. Introduce Scrum to your team, ScrumMaster and Product Owner.
Para leer en inglés y en español Scrum Primer http://agilethinking.net/ El sitio de Tobias Meyer, que me inició en el ScrumMastering en el 2006. http://www.implementingscrum.com/ Sitio donde encontraran la clásica historia: The classic story of the pig and chicken El Manifiesto Agil mencionado en la charla Artículo corto en inglés (pdf) What is Scrum? Reviews of Agile Product Backlog and User Story Management Tools: http://www.userstories.com/ Presentación en español sobre Contratos Ágiles Foro Agiles (Grupo Yahoo en español) Blog de Juan Gabardini Software Agil Enlaces y recursos adicionales en Scrum Práctico Scrum Cheat Sheet Scrum: Ficha Sinóptica Un libro que para preparar las primeras versiones del curso
Agile Project Management with Scrum
de Ken Schwaber ISBN:073561993x Microsoft Press © 2004
En ese libro, están enumerados estos recursos:
Agile Software Development with Scrum, Ken Schwaber and Mike Beedle (Prentice Hall, 2001)
Teoría y práctica de Scrum.
www.controlchaos.com/
El sitio de Ken Schwaber sobre Scrum.
http://www.jeffsutherland.com/
Jeff Sutherland tiene contenido relacionado con desarrollo de software, programación, tecnología, objetos, componentes y Scrum.
www.mountaingoatsoftware.com/scrum/
El sitio de Mike Cohn sobre Scrum.
www.scrumalliance.org
El hogar de los ScrumMaster certificados.
www.agilealliance.org
El sitio de la AgileAlliance, con recursos sobre Agile y Scrum.
http://groups.yahoo.com/group/scrumdevelopment/
El grupo de discusión de Scrum, con años de existencia.
www.xprogramming.com
El sitio de Ron Jeffries acerca de Extreme Programming (XP). XP provee varias de las prácticas que Scrum implementa para asegurar el incremento de funcionalidad potencialmente entregable.
Otras lecturas recomendadas
- Agile and Iterative Development: A Manager’s Guide by Craig Larman
- Agile Estimating and Planning by Mike Cohn
- Agile Retrospectives by Esther Derby and Diana Larsen
- Agile Software Development Ecosystems by Jim Highsmith
- Scrum and The Enterprise by Ken Schwaber
- User Stories Applied for Agile Software Development by Mike Cohn
- Artículos semanales en www.scrumalliance.org
Mis posts sobre Scrum (estoy ahí escribiendo una serie “Tales from the Scrum” donde trato más en detalle algunos puntos que tratamos en el curso).
Los enlaces que me interesaron los colecciono en:
http://delicious.com/ajlopez/scrum
http://delicious.com/ajlopez/agile
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
AjGenesis, mi proyecto open source de generación de código, usa tareas, templates (plantillas) y un modelo de libre definición, para generar artefactos de texto, en general código fuente, pero también archivos cualesquiera, como configuraciones, definición de proyectos, etc. Muchos de los ejemplos que están en el proyecto y otros que publiqué aparte, usan modelos serializados como archivos XML o de texto. Pero el modelo inicial puede ser cualquier entrada: no sólo esos archivos, sino cualquier fuente de información que nos dé alguna base de modelo. Hasta podemos armar archivos de modelo (recuerden, el modelo lo deciden uds, dónde va, qué tiene, es todo libre) desde otro modelo. Hace unos dos años, escribí sobre generar el modelo desde la base de datos. En mi opinión, la base de datos no es el modelo más expresivo, pero es uno muy ubicuo: puede servir como punto de partida, y desde la base de datos, generar un modelo que podemos refinar posteriormente.
(sobre el tema de modelos pueden leer Modelos y metamodelos en AjGenesis: los metamodelos no son necesarios ni obligatorios, pero es un tema que estoy agregando en el proyecto, como opcional).
(un tipo de modelo a explorar Otro modelo para AjGenesis)
Hoy quiero entonces volver sobre el tema de generar un modelo desde otro modelo, esta vez usando el esquema de la base de datos que tengamos entre manos. Es sólo un ejemplo “prueba de concepto”. Pero en el proyecto ágil en que estoy participando, el equipo tomó la base que ya tenían y generó un modelo usando técnicas como las de este ejemplo, usando AjGenesis, y ahora, ya abandonaron la base inicial, y usan directamente el modelo generado alguna vez y refinado desde entonces.
Pueden bajar el ejemplo actual de mi Skydrive DatabaseExample01.zip. (el código está en el repositorio de código en Codeplex, bajo el directorio examples\DatabaseExamples). El .zip de Skydrive tiene todo lo necesario, incluso la versión en desarrollo de AjGenesis ya compilada.
Despues de bajarlo y expandirlo, tenemos estas carpetas:

Hay un solo proyecto de ejemplo. EL contenido de Projects\Northwind\Metadata.xml:
<Metadata>
<Project>
<Name>Northwind</Name>
</Project>
<Database>
<Name>Northwind</Name>
<ConnectionString>server=.\SQLEXPRESS;database=Northwind;Integrated Security=true</ConnectionString>
</Database>
</Metadata>
Describe el string de conexión a usar para llegar a la base de ejemplo. Estoy usando la Northwind, en SQL Server (pueden usar el full o el express). Si no tienen esa base de datos, los scripts de creación están en el directorio Sql.
Para generar el proyecto, el modelos con sus entidades, ejecutar:
MakeModelFromDatabase.cmd
AjGenesis (compilado en el directorio Bin) comienza su trabajo:

El comando que ejecutamos contiene:
Bin\AjGenesis.Console Projects\Northwind\Metadata.xml Tasks\DatabaseProcess.ajg
Este comando carga el contenido de Metadata.xml como modelo en memoria, y ejecuta la tarea DatabaseProcess.ajg escrita en el lenguaje dinámico que uso AjBasic. Esta tarea usa las vista de Information Schema para obtener información acerca de la estructura de la base de datos (usando estas vistas, que están definidas en el estándar SQL, y presentes en varias bases de datos, nos abre la puerta para conseguir trabajar con otras marcas que no sean MS SQL Server; debería probar, por ejemplo, con Oracle).
La tarea crea el archivo Projects\Northwind\Project.xml:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<Project>
<Name>Northwind</Name>
<Model>
<Entities>
<Entity Source="Entities/Customer.xml"/>
<Entity Source="Entities/Shipper.xml"/>
<Entity Source="Entities/Supplier.xml"/>
<Entity Source="Entities/Order.xml"/>
<Entity Source="Entities/Product.xml"/>
<Entity Source="Entities/OrderDetail.xml"/>
<Entity Source="Entities/CustomerCustomerDemo.xml"/>
<Entity Source="Entities/CustomerDemographic.xml"/>
<Entity Source="Entities/Region.xml"/>
<Entity Source="Entities/Territory.xml"/>
<Entity Source="Entities/EmployeeTerritory.xml"/>
<Entity Source="Entities/Employee.xml"/>
<Entity Source="Entities/Category.xml"/>
</Entities>
</Model>
</Project>
El proyecto y las entidades son parecidas a las que usé en Generando aplicaciones con AjGenesis (pero no es igual, estoy experimentando con mejoras). Parte del contenido del archivo generado Projects\Northwind\Entities\Customer.xml nos da una idea de lo que se captura de una “Entity”:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<Entity>
<Name>Customer</Name>
<Description>Customer</Description>
<SetName>Customers</Name>
<Descriptor>Customer</Descriptor>
<SetDescriptor>Customers</SetDescriptor>
<SqlCatalog>Northwind</SqlCatalog>
<SqlSchema>dbo</SqlSchema>
<SqlName>Customers</SqlName>
<Properties>
<Property>
<Name>CustomerID</Name>
<Description>CustomerID</Description>
<SqlName>CustomerID</SqlName>
<SqlLength>5</SqlLength>
<IsKey>True</IsKey>
<SqlType>nchar</SqlType>
<SystemType>String</SystemType>
<IsNullable>False</IsNullable>
</Property>
....
</Properties>
</Entity>
La lógica principal de todo este proceso de generación, reside en la tarea Tasks\DatabaseProcess.ajg, de nuevo escrita en AjBasic (I love this language! :-) un fragmento:
cmd = new System.Data.SqlClient.SqlCommand()
cmd.Connection = conn
cmd.CommandText = "select * from Information_Schema.Tables where Table_Type = 'BASE TABLE'"
conn.Open()
PrintLine "Reader"
dr = cmd.ExecuteReader()
Tables = CreateList()
while dr.Read()
PrintLine "Table " & dr.Item("Table_Name") & ": " & dr.Item("Table_Type")
Table = CreateObject()
Table.SqlCatalog = dr.Item("Table_Catalog")
Table.SqlSchema = dr.Item("Table_Schema")
Table.SqlName = dr.Item("Table_Name")
Table.Name = Table.SqlName.Replace(" ","")
if IsPlural(Table.Name) then
Table.SetName = Table.Name
Table.Name = ToSingular(Table.Name)
else
Table.SetName = ToPlural(Table.Name)
end if
Table.Descriptor = Table.Name
Table.SetDescriptor = Table.SetName
Table.Description = Table.Name
Tables.Add(Table)
end while
dr.Close()
Posibles mejoras
Como escribí más arriba, este ejemplo es una “prueba de concepto”; una versión anterior la usamos en un proyecto real. Pero hay varios puntos a mejorar:
- Usar el modelo generado para generar una aplicación que funcione, con scaffolding o no.
- Soportar más metadata que obtengamos via Information Schema
- Probar con otras marcas de bases de datos, y con bases de datos reales
- Tratamiento de relaciones: detectar borrados en cascadas, soportar claves primarias compuestas, otras acciones.
Otros posts relacionados (aparte de los ya mencionados):
Si es la primera vez que se topan con generación de código con AjGenesis, tengo varios posts escritos. Recomiendo un video, producido gracias a la comunidad ALT.NET Hispano: Resultado de la VAN ALT.NET Hispano sobre Generación de Código
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez