sábado, 28 de febrero de 2009

Del desarrollo del lenguaje en la búsqueda de la perfección.

Si para algo me ha sevido este blog es a contrarrestar los efectos de la programación sobre la calidad de mi lenguaje cotidiano. Me he sentido muy identificado con este párrafo:

You have to pour your heart and your soul into accepting nothing but perfection from that damn regular expression, that damn CSS selector, that damn SQL case statement, that bloody mother f***ing a*****e of a *** **** son of a ******* ugly ***** ***** **** of a **** installation package, so the lucky ******* **** of an end user gets all the joy of a working system.

(Extracto de Low Frustration Tolerance: Curse and Blessing - secretGeek)

En efecto, si transcribiera todo lo que digo cuando programo sería algo muy parecido a ésto:

****** de ****** una san ******* y la ****** madre ****** que lo ******* por qué ****** si esta ***** *****… ¡Funciona! Tomá, ***** de la ****** madre que te ******.

viernes, 27 de febrero de 2009

Jueguitos de viernes: Super Stacker 2.

Siguiendo la línea Jelly Towers, Perfect Balance y Totem Destroyer 2, el siguiente sería Super Stacker 2, en el que también tenemos que apilar diferentes figuras geométricas sin que caigan hacia el fondo de la pantalla.

Tiene un buen toque de humor y música jazzera. Los primeros niveles son tal vez demasiado fáciles, pero finalmente aparecen los problemas.

ss2

La “respuesta” a “¿Cuál es el error?”, la ambigüedad, su resolución y, finalmente, la realidad.

question Estamos hablando del problema planteado en el post ¿Cuál es el error? Si no lo has leído (con sus comentarios) no vas a entender nada (es simple y cortito, no hay excusa).

Me encanta ese problema ya que es disparador de un montón de cuestiones relacionadas a la codificación entre las que encontraremos muchas zonas grises. Algunos (como yo) verán las suficientes para afirmar sin lugar a dudas que programar está a medio camino entre el arte y la técnica, y que para el ojo entrenado no es difícil encontrar cierta belleza (o por lo menos elegancia, una de sus formas) en algunos ejemplos.

Bueh, tal vez me emocioné un poco. De todas maneras lo anterior sirve para aclarar que lo que sigue es mi personalísima opinión y que si bien puede ser contraria a la de algunos de ustedes no pretende ni puede invalidarla en manera alguna ya que, como establecimos, son zonas grises.

La solución “estricta”.

Siendo riguroso con el enunciado del problema, creo que la respuesta más acertada es “No se puede saber”.

Parece que hay un error (y aunque eso parece claro, si leyeron los comentarios en la entrada del planteo verán que hasta eso puede objetarse) ya que la declaración dice que suma pero la implementación resta. No hay forma de decidir qué está mal sin un contexto.

Lo más que podemos decir es que el código es poco legible, que es confuso, ambigüo (para un ser humano) o traicionero. Lo que no podemos decir (sin contexto) con seguridad es que hay un error de esos que le interesan a la gente común, y mucho menos decir cuál es. El único error que podemos verificar es de estilo o prolijidad, y no podemos resolverlo.

De acuerdo al contexto el error podría ser nimio, de esos que uno corrije sin decir nada a nadie (sería obviamente de tipeo, el programador quiso poner “+” y le salió un “-”. Algunos de los muchos números del reporte –por ejemplo- salieron mal, pero eran tantos que era difícil darse cuenta. En las pruebas, para un analista que interprete esos números, será mucho más evidente que para un programador cansado o aburrido de hacer reportes)… o grosero, muy grosero. Que se entienda bien clarito: al programador que utilice eso para restar, repetida y consistentemente en cualquier porción de código, yo le deseo la muerte.

Mejor volvamos a nuestro problema, sin contexto. Uno de los principios de diseño de Guido Van Rossum (autor de Python, entre otras cosas) nos dice:

Cuando te enfrentes a la ambigüedad, rechaza la tentación de adivinar.

Es muy, muy difícil de seguir. Casi tanto como decir “No sé” o “No se puede saber”. La primera respuesta es dolorosa para un orgullo cultivado (y los programadores sí que cultivamos el nuestro) y la segunda requiere mucha confianza y conocimiento del tema que se trata.

Por otro lado las preguntas engañan. No es lo mismo preguntar “¿Cuál es el problema?” que “¿Hay un problema?”.

Vivimos en un mundo imperfecto y una computadora no entiende de imperfecciones. A los programadores nos toca ser el último eslabón entre lo ambigüo por naturaleza (el lenguaje, los negocios, el ser humano, la vida en general) y lo absoluto (una sucesión finita de operaciones), así que lidiamos con este problema -de enfrentarnos a la ambigüedad- todos los días.

Un ego desmedido como el nuestro no digiere fácilmente que (si bien podemos hacer cualquier cosa) no somos dueños de la verdad absoluta (no todo lo que hagamos estará bien -¡aunque funcione!-) y que -peor todavía- existe la verdad absoluta y tiene dueño: el cliente. Utilizando estrictamente las palabras, los programadores somos dueños de la implementación, pero no de la solución. Decidimos cómo pero no qué.

El cliente (o quien lo represente ante nosotros, los programadores) puede equivocarse en muchas cosas, pero cuando hay que resolver una ambigüedad tiene no sólo la última, sino la única palabra. En el trabajo de todos los días no podemos decidir si “una operación revertida aparece en el informe o no”. ¿Por qué no? Porque estaríamos inventando y tal vez invirtiendo tiempo en hacer bien algo que nunca debería haberse hecho.

Recuerden siempre: las preguntas engañan. Siguiendo el ejemplo de la operación revertida, es probable que hayamos arribado a esa opción binaria más por nuestra naturaleza de programadores que por la realidad de la situación. ¿El cliente pensó en esta situación? No. Entonces, ¿cómo podemos saber que la solución es una u otra, y no una tercera, o ninguna, o las dos?

¿Cómo saber si hay que sumar o restar? No lo sabemos. No sabemos qué es lo que hay que hacer si no nos lo comunican, tenemos que preguntar. La frase de Guido nos está diciendo “más fácil inventar parece, pero evita la tentación, porque buscar una respuesta debes” (¿o ése era Yoda?). Ésa es, en principio, nuestra responsabilidad: resolver la ambigüedad preguntando, no inventando.

Es también, entonces, un tema de responsabilidades (“Un gran poder conlleva una gran responsabilidad”): ¿tenemos ese poder para decidir? ¿queremos esa responsabilidad? Recordemos, otra vez, que estaríamos tomando una decisión sin conocer todos los detalles: no conocemos el negocio, al cliente final, ni la situación comercial… tal vez ni siquiera el sistema completo.

Pero, ya lo dijimos, vivimos en un mundo imperfecto. Muchas veces (en todo proyecto real esta situación es más que frecuente) el cliente no está disponible (si estuviese disponible él tiene la respuesta, aunque ésta sea “hacé lo que te parezca” o tire una moneda o cambie con el tiempo) o no entiende la pregunta. ¿Entonces?

La frase nos dice “evita la tentación”, no nos dice “no adivines”. Hay veces que tenemos que adivinar. Presionados por un sinfín de circunstancias, para bien o para mal, hay veces que hay que adivinar y seguir adelante, rellenar los huecos en las especificaciones apelando al sentido común o, en última instancia (es lo que yo lo recomiendo) hacer lo que sea más fácil para nosotros, así por lo menos el tiempo perdido será menor.

Pero tenemos que ser conscientes de que lo estamos haciendo. Y de que está bien si lo hacemos sólo si hemos agotado otras instancias (o no tenemos tiempo de hacerlo) y no nos queda otra, y no para patear un problema debajo de la alfombra.

La razón última por la que un proyecto no puede llevarse a cabo sin la cooperación y compromiso real de los programadores que en él participan (por lo menos de buena parte de ellos) es que (como una computadora no entiende de ambigüedades) estas pequeñas decisiones…

  • que nos vemos obligados a tomar sin información completa
  • o con la poca que logremos recabar investigando hasta donde dé nuestra conciencia,
  • basándonos en nuestra experiencia, sentido común, pálpito y buena suerte,
  • sabiendo que en el mejor de los casos evitaremos un problema y nadie se dará cuenta ni agradecerá nada,
  • y que en el peor de los casos… (mejor no hablar de ello)

…tienen gran impacto (para bien o para mal) en el resultado. Tanto que son determinantes, tal vez no del éxito (que dependerá también de muchos otros factores), pero seguro que del fracaso de un proyecto (que con una buena cantidad de decisiones equivocadas o con apenas un par en los lugares precisos puede darse por muerto).

La mejor manera de sabotear un proyecto es hacer exactamente lo que te piden, sin chistar.

jueves, 26 de febrero de 2009

El control total y sus consecuencias.

Juan Carrión (Jano 2.0) tiene una increíble capacidad para generar imágenes y frases impactantes, de esas que no puedo dejar de referenciar.

Éste es un pequeño extracto de Panópticos: Diez años y un día:

Las consecuencias del control total son terribles, ya que “los maltratados” tienden a vengarse de las empresas que los maltratan, convirtiéndose en auténticos terroristas. Sin duda, cada empresa tiene tantos empleados terroristas como se merece.

Frankenstein, el líder de proyecto (XII).

ATENCIÓN: ¡No sigas si no has leído la onceava parte! Y si no has leído nada empieza por el principio.


[Resumen: Frankenstein encomienda al líder técnico que complete la codificación del módulo, resolviendo las incongruencias y pequeños errores de las especificaciones. El líder accede por primera vez al código de la criatura, descubriendo con horror que es inmenso y completamente ilegible, y por tanto inmodificable. “¿Pero quién carajo es el monstruo que le enseñó a programar a este tipo?”, exclama. Él no lo sabe, pero ese monstruo no es otro que Frankenstein.]

El líder sostenía su cabeza con las manos, los codos apoyados en el borde del escritorio, la silla alejada de éste, la vista perdida entre los detalles de la alfombra.

Algo en el sonido del grito que acababa de liberar –un timbre de genuino horror, una nota que denotaba algo más que un grave problema, algo más que un incidente laboral… una nota que transmitía desesperación, furia, impotencia… locura- había actuado sobre el resto de los ocupantes de la oficina. Todos –todos menos la criatura, que continuaba tipiando impasible- habían interrumpido sus tareas y miraban fijamente en dirección al líder, inmóviles, esperando alguna reacción.

No la hubo. Un programador se acercó tímidamente y observó la pantalla. Detrás de él se aglutinaron los demás. Inclinándose por sobre el cuerpo del líder, el programador corrió un poco el teclado y giró el monitor.

Se enderezó, luego de unos instantes. Cruzó el brazo izquierdo sobre el pecho. En la mano izquierda apoyó el codo derecho, y la mejilla en su mano derecha. Así permaneció, con la boca abierta, mientras los demás repetían aquello que parecía un extraño ritual.

El silencio era absoluto. Algunos se miraban entre sí, otros al piso. Otros volvieron a sus lugares, reconcentrados, incrédulos, intentando asimilar lo que habían visto.

No era la visión de aquel código lo que los horrorizaba, sino el asomarse a la naturaleza de su autor e imaginar su origen.

Un programador ve en el código de otro su lógica, su forma de pensar, el camino que recorre su cerebro en busca de una solución, sus problemas, sus dudas, sus errores. ¿Qué revelaba de la criatura aquel ejemplo abominable?

Una ausencia, un vacío. No una lógica ajena, extravagante, complicada o simplemente equivocada (como estaban acostumbrados a ver de vez en cuando), sino una carencia, un vacío absoluto. Carencia de lógica, de comprensión, de razonamiento.

- Es… siniestro –dijo uno de ellos, rompiendo el silencio.

- ¿Qué es siniestro?

- Cuando lo cotidiano se vuelve extraño.

- Es… como… es como… un compilador de documentación funcional.

Alguno esbozó una sonrisa triste. Era solamente eso, al fin y al cabo. Un autómata de carne y hueso, una máquina de traducción simple, lisa y llana del lenguaje al código, un paso más, mecánico, transparente e inútil entre el analista y el software.

Pero parecía humano. Era esa similitud lo que lo volvía siniestro y -en principio- atemorizante.

El líder sollozaba. Y tal vez algún programador contuvo una lágrima. No por el fracaso del módulo o del proyecto, sino a causa de la profunda tristeza que inspiraba su autor, tan humano en apariencia.

Luego del rechazo, del temor y del horror ante la visión del vacío, éste sólo inspiraba una tristeza absoluta.

Un programador –el mismo que había roto el silencio- se acercó a la criatura y apoyó una mano en su hombro, pero ésta continuaba trabajando, ajena a todo y todos a su alrededor.

- ¿Qué está haciendo? –preguntó alguien desde el otro extremo de la oficina.

- Nada, sólo sigue escribiendo.

…continuará. Actualización: capítulo XIII.

miércoles, 25 de febrero de 2009

Frases: personas y planificación.

Una muy buena frase de Clay Shirky, citada en Buenas y malas prácticas en la transición hacia la “Empresa 2.0″, de El Caparazón:

Los sistemas con buenos participantes producen mejores resultados que los que fueron bien planificados.

¿Cuál es el error?

Una bobada para pensar un rato, de esas que me gusta tirar en las primeras clases: ¿qué está mal en este código, y por qué?

public decimal Suma(decimal a, decimal b)
{
 return a-b;
}

Obviamente el "por qué" es lo más importante de la respuesta. No consulten ninguna fuente (pierde la gracia), sólo sigan su instinto y, si quieren, dejen un comentario (sin mirar antes los de los demás).

Actualización: el tema se resuelve (en parte) en La “respuesta” a “¿Cuál es el error?”, la ambigüedad, su resolución y, finalmente, la realidad.

martes, 24 de febrero de 2009

Siguiendo el rastro del WTF.

perro Una tarea que se perfila como rutinaria puede transformarse inesperadamente en análisis forense funcional.

La asignación -más que rutinaria, aburrida-, era migrar un reporte del sistema viejo al nuevo. Usualmente se resuelve con un par de adaptaciones y listo, pero…

Mi primer descubrimiento en la tarea comenzó consistió en el procedimiento almacenado más enrevesado que vi en mi vida: una sola instrucción SELECT de más de 300 líneas, con tres niveles de subconsultas y un par de UNION’s en cada uno de ellos. Un bonito WTF.

Por supuesto que una maraña de código de ese calibre no es puntual ni tiene un sólo padre. Es el producto más paradigmático (entre muchos otros) de una larga cadena de producción de basura útil. Una cadena de errores que puede recorrerse hacia atrás desde la codificación hasta la gestión del proyecto.

La codificación, ilegible, traicionera y escurridiza, es el producto de “construir un rascacielos con ladrillos”. Es decir, se pretende resolver  todo el problema con una sola herramienta (¿qué necesidad había de hacer todo en una sola consulta?) en vez de separarlo en partes y aplicar a cada una la más adecuada.

No tiene sentido buscar un culpable, obviamente no lo hay. Si bien el código nació medio enrevesado fueron las sucesivas modificaciones las que lo volvieron caótico. Un buen ejemplo de la parábola de la rana hervida: pequeñas modificaciones, todas ellas muy inocentes tomadas en forma individual, generan un bonito quilombo desastre.

Lo que nos lleva a la metodología. Una refactorización a tiempo hubiese cortado este problema de raíz. Es claro, por la estructura de la consulta (bloques SELECT conectados por UNION’s que agregan casos no contemplados, subconsultas que vinieron a reemplazar referencias a tablas, cálculos repetidos que producen pequeños ajustes sobre el  resultado sin alterar la estructura, reutilización de campos para agregar datos “sin tocar nada”, etc.), que su creador sabía mucho más al final del proceso que al principio. La refactorización no sólo es imprescindible para mantener el código legible a través de las sucesivas modificaciones, es la actividad con la que se solidifica el aprendizaje, el momento en que lo aprendido se transforma en código. Aquel primer autor partió tiempo atrás y todo el conocimiento acumulado, por lo menos en lo relativo a esta experiencia en particular, se ha perdido irremediablemente (snif).

Esto es triste, sobre todo combinado con el hecho de que luego de un tiempo este código se ha convertido en la única documentación existente sobre la funcionalidad.

Lo que nos lleva al segundo error metodológico: ¿cómo transmitió el sector de análisis las especificaciones del reporte? No lo sabemos. El sólo hecho de que no lo sepamos hace de esa transmisión un acto fallido. ¿Fue verbalmente? ¿Se elaboró un documento? En todo caso, la falta de un soporte o repositorio confiable hizo humo (o leyenda) ese trabajo de análisis.

El que crea que el conocimiento puede preservarse “solo” en la cabeza de los integrantes del equipo puede acompañarme en la experiencia de consultar a las personas directa o indirectamente involucradas con una funcionalidad en particular. Lo que se obtiene son varios pedazos -ligeramente diferentes y que no encajan del todo- de la misma fotografía. Los detalles… “mirá el reporte en el sistema viejo”, con lo que volvemos a nuestro querido e ilegible procedimiento almacenado.

Entonces el problema es no de una o unas personas sino de todo el equipo. Nadie trabajó aislado. El analista hizo su trabajo, el programador hizo su trabajo. ¿Entonces? Lo que ha fallado es la interacción entreambos. La falta de visión a futuro (o la indiferencia con respecto a él), o un exceso de individualismo (“sólo hago mi trabajo”).

Los problemas de equipo son, por definición, de liderazgo. Cuando las partes no coordinan bien entre sí es necesaria la intervención de un elemento superior que modifique esa interacción: por caso, el líder. Por complicidad, desconocimiento o falta de soluciones (es irrelevante) eso no ha ocurrido.

Esta basura útil, este “cowboy code” incrustado en medio de un “pure chaos environment” funciona. Y bastante bien, por cierto. Entonces, en la mirada miope o distraída de líder, el equipo debe haber superado con creces el desafío, que quedó cerrado y archivado definitivamente.

El siguiente eslabón de la cadena es organizacional. La vara (ya sea para medir o aleccionar) más común en las organizaciones es el costo/beneficio. El costo de no haber documentado el análisis y refactorizado el código ha pasado desapercibido, lo que ha devenido en una medición inflada del resultado final, generando un pernicioso condicionamiento positivo respecto del apuro y la desprolijidad. Tal vez una medición más precisa del costo a futuro de esas desprolijidades hubiese motivado una corrección más temprana.

Esta última observación excede el ámbito de la gestión de un proyecto. Está más relacionada con la estructura de costo de la organización, del sistema que utilice para medirlo y de cómo se utilizan esas mediciones. El costo de este retrabajo, originado en aquél otro proyecto que salió “tan bien” y fue “tan rentable” pesará sobre este nuevo proyecto.

En fin, hemos comenzado hablando de procedimientos almacenados y prolijidad del código para terminar en cálculo y gestión de costos a nivel organizacional. Hemos recorrido, a través de un divertido ejemplo la cadena que une el error con la pérdida (en el mejor de los casos) o el fallo con la catástrofe (en el peor).

lunes, 23 de febrero de 2009

Frases: análisis de impacto o…

thumb Una pequeña modificación a las apuradas aquí y… una gran explosión allí. ¿Qué paso?

- Y… falló el análisis de impacto.

- ¿Análisis de impacto? Acá no hacemos análisis de impacto. Hacemos análisis forense.

Clasificación de usuarios.

Saltando de link en link caí en La era de los perdonadores, un artículo de Julio de 2008 de Nicolás Cohen. Entre otros temas (les recomiendo el artículo y el blog) referencia una clasificación de usuarios propuesta por Alan Cooper en el libro The immates are running the asylum:

[…] Los “Apologists” o “perdonadores” es el caso de usuarios de software evidentemente defectuoso, pero que ante el desconocimiento o la incapacidad de cambiarlo, lo aceptan y terminan queriendo de cualquier modo. […]

(El autor los relaciona con los rehenes que sufren el síndrome de Estocolmo, ocurrencia muy apropiada de la cual todavía me estoy riendo.)

[…] En el otro polo están los “survivors” o “sobrevivientes”. Ellos se dan cuenta que algo esta mal, pero no saben bien qué. No saben mucho sobre computadoras o interacciones, pero ven que hay un problema. Saben lo que quiere decir “díficil” y lo que quiere decir “fácil” y saben muy bien, que las computadoras son “difíciles”. […]

[…] El “Homo Logicus” […] desea por sobre todas las cosas tener control sobre las cosas que le interesan. Esta dispuesto a relegar simplicidad en función de Él. El “Homo Sapiens”, en cambio, quiere las cosas fáciles, incluso si eso implica unos minutos más de espera. […]

Frankenstein, el líder de proyecto (XI).

ATENCIÓN: ¡No sigas si no has leído la décima parte! Y si no has leído nada empieza por el principio.


[Resumen: El módulo de pago a proveedores se atrasa rebotando entre pruebas y correcciones. Los clientes presionan y Frankenstein se ve obligado a tomar cartas en el asunto. Instruye a su criatura que el módulo debe superar las pruebas “a toda costa”. Luego indica al líder de proyecto que complete la codificación superando los errores en la especificación de acuerdo a su criterio, tarea que no puede encargar a su programador por carecer éste, precisamente, de criterio.]

El líder de proyecto llegó temprano. Ordenó sus cosas, resolvió un par de cuestiones pendientes con los demás programadores, se preparó un café y charló un poco con todo el mundo.

Sentía la presión de su nueva asignación –terminar el módulo de pago a proveedores- pero algo lo alejaba de ese código. Extendía el rechazo que le provocaba el programador a su obra. Finalmente tomó impulso, se sentó y abrió el proyecto.

Tardó un poco más de lo esperable en presentarse en pantalla. Finalmente aparecieron ante sus ojos los archivos del proyecto: eran doce. Uno por cada pantalla. Y nada más.

Qué extraño –pensó-. Ahí están los formularios… ¿y el resto del código, los espacios de nombres, las clases, los módulos con funciones compartidas, las referencias?”.

Abrió el primer formulario. Se dirigió al código que lo controlaba. El entorno de programación dudó por un par de segundos (“¿Por qué está tan lento esto?”) y finalmente reveló su contenido.

El líder quedó inmovilizado, incapaz de reaccionar, de despegar los ojos de la pantalla. El botón de desplazamiento de la barra lateral de la ventana había alcanzado el mínimo. El formulario tenía… 86,042 líneas de código.

Abrió los demás… 93.402… 107.312… 85.324… en total… 1.032.510 líneas de código.

Quien lo hubiese visto en ese momento habría notado en su palidez, en sus manos inmóviles sobre el teclado, en el meñique derecho moviéndose apenas -“Page Down”… “Page Down”…-, el terror de un hombre que observa impotente el infierno que se abre bajo sus pies. “Qué… ¿qué es esto…?”.

Miró fijamente al programador, seguía tecleando impasible en la esquina opuesta de la oficina. Volvió a fijar la vista en la pantalla. Trató de reponerse… se dirigió al código que controlaba el botón “Aceptar” de uno de los formularios. Todo funcionaba en cámara lenta. Obviamente el entorno de desarrollo no estaba pensado para esto, toda la computadora parecía fuertemente sedada. Empezó a recorrer el procedimiento.

Todo estaba allí. Todo. El procedimiento tenía… 92,907 líneas. Comenzaba en la validación de cada uno de los datos de cada uno de los controles, seguían todas las operaciones y cálculos necesarios, las validaciones contra la base de datos, los mensajes, el reporte…

Todo estaba allí. No habían llamadas a otras funciones ni a librerías externas compartidas con los demás formularios. No había capa de datos, de negocio, de presentación. Todo estaba allí… todo y nada al mismo tiempo. Los nombres de los controles… “c1”, “c2”, “c3”… los nombres de las variables “i1”, “i2”, “i3”, “b1”, “b2”, “b3”… “i352”.

Los demás formularios estaban igual. Aquello era… ininteligible, intocable, inmodificable, basura.

Sintió que algo se quebraba dentro suyo. Una presión angustiosa comenzó a subir desde su estómago y se acumuló en su garganta. Finalmente, rojo de ira, levantó la vista al cielorraso y gritó con todas sus fuerzas:

- ¿Pero quién carajo es el monstruo que le enseñó a programar a este tipo?

Como todo en la criatura, sus habilidades de codificación provenían de Frankenstein. Nadie se lo había dicho nunca –tampoco hubo nunca necesidad de hacerlo-, pero todos sabían que programando era tan desastroso como eficaz. Hacía tiempo ya que cualquier aporte suyo había sido descartado y recodificado. Su código era ilegible.

Por algo había llegado rápidamente a líder de proyecto.

…continuará. Actualización: capítulo XII

domingo, 22 de febrero de 2009

Ejemplo a seguir a la hora de los problemas.

Otra de Demotivator Blog. Para pegar en la oficina.

trouble

Intercambio de webcomics.

Hace apenas un par de meses descubrí los webcomics. Sabía que existían pero nunca les había prestado demasiada atención.

Es un mundo enorme en el que hay para todos los gustos. Les paso mi lista de favoritos (todavía soy un newbie, así que no esperen grandes revelaciones), me gustaría recibir sus recomendaciones en los comentarios.

Los links apuntan al sitio y las imágenes a las tiras recientes que más me han gustado.

Sinergia sin control Geek Hero Comic
53 superhacker
Dilbert We the robots
41217stripprint 2009-02-16-Valentine
Cyanide & Happiness xkcd
comiccookinghobby1 music_drm
A Friki's Life Geek in Love
2009-01-30-afl 3110919120_d7ecdfb427_o
404 Linux Hispano
2009-01-08-comic136 respuesta
Plétora de piñatas El señor enviñetado
467 ese000245s
TiraEcol El show de Juanelo
tiraecol-292 Juanelo882
Indexed 
(no creo que sea un webcomic, pero… adentro)
 
 card2048-378x230

¿Cuánto sabes de Google?

OpcionWeb ha publicado un Quiz sobre Google. No es nada fácil (prueben primero sin buscar las respuestas en… en Google, claro).

qsabesdegoogle

Yo saqué 12/22. Bastante flojo.

sábado, 21 de febrero de 2009

Currículos creativos (más una ayudita para el plural de currículum y evitar quedar en ridículo en general).

Ya he pasado mucho más tiempo con el título que con la entrada. Finalmente recurrí a mi nuevo mejor amigo para evitar el ridículo (gracias a Verónica por presentármelo):  el Diccionario panhispánico de dudas que puede consultarse desde la página principal de la RAE.

Resumen: currículum vítae es una locución latina que significa literalmente “carrera de la vida”. El plural -en latín- es currícula, y no debe usarse. Lo correcto es utilizar la voz adaptada currículo y su plural, currículos (ver Diccionario panhispánico de dudas - RAE).

¿A qué venía todo esto?

Ah, sí. Recomendarles una divertida entrada en 101.es, "Currículum creativos" (mal, y encima en el título), en la que se recopilan algunos currículos creativos.

Un par de muestra (hay más en el artículo), uno con el look & feel de Google, y éste en forma de mapa del metro:

CVJeroCasi me olvido: visto en el twitter de @yoriento.

Frases: hechos y palabras.

Una muy buena cita, vista en el blog de Jorge Juan Fernández:

“After all is said and done, more is said than done.”

- Esopo.

viernes, 20 de febrero de 2009

Juegos de viernes: Totem Destroyer 2.

Tarde pero seguro (¡gracias Cerebrado!). Nuestro objetivo en Totem Destroyer 2 es alcanzar un preciado ídolo dinamitando las bases sobre las que se apoya hasta acercarlo al suelo. Simple, ¿no? Simple, pero no fácil.

Totem2

Definir el negocio.

Encontrado un muy buen concepto en la última de las recomendaciones de artículos de Wikipedia de Pymecrunch. Es una regla muy simple y en la que no había pensado nunca: Miopía de Marketing. Transcribo ese fragmento:

[…] Es mejor definir tu negocio en términos de mercado, y no de producto.

El artículo de la wikipedia lo explica con dos ejemplos muy divertidos:

-La gente no compra taladros, compra agujeros. Si te posicionas como “vendedor de taladros”, tendrás muchos problemas cuando se popularicen los punteros láser.

-La gente no quiere viajar en tren […], lo que quiere es ir del punto A al punto B. Si dices que te dedicas al negocio de los trenes, ¿qué harás cuando subir a un avión esté al alcance de cualquiera?

jueves, 19 de febrero de 2009

Frankenstein, el líder de proyecto (X).

ATENCIÓN: ¡No sigas si no has leído la novena parte! Y si no has leído nada empieza por el principio.


[Resumen: Las correcciones al módulo de pago a proveedores se atrasan debido al excesivo celo de “Jaime” (tal el apodo dado a la criatura de Frankenstein por el analista a cargo) por la burocracia y al detallismo con el que se apega a las especificaciones. El analista a cargo de las pruebas, preocupado por lo absurdo de la situación, intenta una charla con Frankenstein en la que éste le transfiere la responsabilidad de los retrasos y se muestra inflexible. Trabaja al límite de sus fuerzas para seguir el ritmo del programador, que trabaja día y noche y parece incansable.]

Finalmente llegó el momento en el que todos los módulos estuvieron listos salvo el de pago a proveedores, que seguía rebotando continuamente entre correcciones y pruebas.

Los clientes presionaban. Frankenstein llamó al analista.

-Hago lo que puedo, tal vez deberías hablar con el coso ése –ya no ocultaba su desprecio por el programador, al que consideraba “un autista subnormal con una gran capacidad para romper teclados”.

Frankenstein decidió hablar directamente con el programador. Insertó una reunión en su lista de tareas.

-Tenemos que instalar la semana que viene, y el módulo de pago a proveedores está retrasado. Sé que no es tu culpa pero tenemos que hacer algo.

-… –Frankenstein se dio cuenta de que estaba hablando solo. A la criatura no le afectaría ese tipo de presión… ni ningún otro tipo de presión.

-¿Qué podemos hacer para terminar a tiempo?

-No sé –la respuesta fue, como siempre, tajante.

-Voy a asignarte una tarea. Quiero que el módulo funcione para la semana que viene, ¿ok?

-El módulo ya funciona –dijo secamente la criatura.

-Mmm… dejáme ponerlo en otras palabras: no quiero ver más errores… cada pantalla debe arrojar el resultado previsto para el conjunto de pruebas indicado… éstas son tus únicas prioridades ahora. ¿Podés hacer eso?

-Sí.

-¿Para cuándo podés tenerlo listo?

-Mañana a la mañana.

-Perfecto.

Frankenstein observó con sincero cariño el paso decidido del programador, la firmeza de su mirada, su concentración absoluta. “Es demasiado bueno para este equipo –pensó-. No saben comunicarse con él, ése es el problema. Con especificar las prioridades claramente es suficiente.”

Frankenstein llamó al líder técnico, responsable directo del equipo de programadores.

-Quiero que ayudes a… al chico nuevo con el módulo. Las especificaciones no son buenas y eso está generando retrasos. Quiero que tomes los incidentes pendientes y los revises personalmente. Corregí lo que indiquen y también lo que surja implícitamente de ello: errores en las especificaciones, incongruencias, inconsistencias funcionales, lo que sea. Tenés carta blanca para resolver cualquier tema de acuerdo a tu criterio.

Te lo dije –pensó el líder, mordiéndose la lengua para no decirlo en voz alta-. Asignarle toda la responsabilidad de un módulo completo a un recién llegado… espero que sea tan bueno como sus recomendaciones.”

El nuevo le daba escalofríos. Luego de un par de vanos intentos de socializar había optado por alejarse de él, dedicándole de vez en cuando una mirada cargada de desconfianza… ¿por qué escribía tanto? Pero nunca se decidió a revisar su trabajo.

Esto se me fue de las manos, es mi culpa. No debería estar preguntándome estas cosas a esta altura… tendría que haber revisado el código… espero que esté bien… debe estar bien… por algo Frankenstein le tiene tanta confianza.”

Había pasado una hora del horario oficial de salida. En la oficina sólo quedaban el analista a cargo de las pruebas del módulo y el programador en cuestión. Se acercó al primero, tal vez sólo por alejarse del segundo.

-Hola. ¿Trabajando hasta tarde? Quería preguntarte por el módulo de pago a…

-No quiero hablar de eso.

-Frankenstein me pidió que me haga cargo de los incidentes. ¿Por qué no nos juntamos mañana y me hacés un resumen informal, para ver por dónde empezamos?

El analista –que había respondido de espaldas, sin siquiera desviar los ojos de la pantalla o dejar de tipiar- permaneció inmóvil un par de segundos… y se dio vuelta lentamente.

El líder retrocedió un par de pasos, sobresaltado. El analista estaba demacrado, excesivamente flaco, pálido, gris. Los ojos, inyectados de sangre, estaban rodeados por enormes ojeras de color violeta profundo. Estaba desarreglado, despeinado, sucio. Le temblaban las manos y los labios.

-¿Vas a hacerte cargo?

Se abrazó, llorando, a la cintura del líder, que permanecía de pie, sin saber cómo reaccionar.

-Creo que mejor te tomás unos días… de todas maneras hay suficiente como para que empiece por mi cuenta… sí, creo que te hace falta. Nos vemos el lunes ¿ok? No te preocupes, yo me hago cargo.

-Gracias… gracias… –continuó repitiendo el analista mientras tomaba sus cosas y salía. El líder tomó las suyas, dispuesto a irse también.

-¿Te falta mucho? –le dijo de pasada al programador, que continuaba en su puesto.

-Sí.

-Ya no queda nadie. Apagá cuando te vayas.

…continuará. Actualización: capítulo XI

miércoles, 18 de febrero de 2009

Planificación estratégica según Dilbert

No puedo dejar de robarle pedirle prestado a Jano 2.0 este pequeño extracto de Dilbert (no he podido hallar el original) sobre planificación estratégica:

  1. Los ejecutivos determinan el rumbo a seguir por la empresa, mediante declaraciones útiles como: “convertirnos en el líder del mercado de suavizante de ropa y comunicaciones por satélite”. Este rumbo es esencial, porque los empleados pueden verse inducidos a creer erróneamente que el objetivo de la empresa es el de cerrar el negocio. O, lo que es peor, el conductor de un camión de reparto podría sentirse confundido ante la ausencia de rumbo, y empezar a diseñar circuitos de microchips en lugar de llevar cargas de suavizante de ropa de un lado a otro.
  2. Se pide a los empleados que clasifiquen objetivamente el valor de sus actividades en apoyo de los objetivos de la empresa.
  3. Los empleados clasifican cada actividad como de alta prioridad, esencial para la existencia misma de la empresa. Apoyan sus afirmaciones con siglas indescifrables.
  4. Las aportaciones de los empleados se clasifican en grandes carpetas.
  5. El departamento de presupuesto utiliza las aportaciones de los empleados como base para prolongadas discusiones sobre la estupidez relativa y el poco valor de cada departamento. Finalmente, se plantean recomendaciones presupuestarias sobre la base de varios factores debidamente sopesados:
    • 10% de las siglas de proyectos con lo que esté más familiarizado el departamento de presupuestos.
    • 10% de anécdotas de cuarta mano que hayan escuchado contar y que indiquen el apoyo ejecutivo para un proyecto concreto.
    • 80% de aquello en lo que al propio departamento de presupuesto le gustaría trabajar si encontrara una forma de dejar de hacer presupuestos.
  6. Se llama a un redactor técnico para que asuma la culpabilidad por el hecho de que los diversos componentes del plan no tienen sentido, y de que los proyectos importantes no disponen de fondos. Amargado y cínico, pero seguro, porque nadie verá nunca el plan, el redactor técnico prepara un documento y luego dimite, asqueado, después de borrar el archivo original.
  7. El plan se guarda en una caja de seguridad porque es demasiado confidencial para compartirlo con los empleados.

Guía para el buen programador en un mal día.

cansancio Es bastante común encontrar colecciones de pequeños consejos de estilo de codificación, “tips” del tipo:

  • Comenta el por qué y no el cómo.
  • No copies y pegues sin entender qué es lo que estás copiando y pegando.
  • Los nombres de las variables deben indicar qué dato contienen (totalVentas) y no su tipo o uso dentro del código (auxDecimal).
  • No incluyas el nombre de la clase en el nombre de un método(Cliente.Actualizar en vez de Cliente.ActualizarCliente).
  • Resuelve el problema antes de comenzar a codificar.

… y un largo etcétera que pueden buscar por ahí. Es bueno conocerlos, releerlos de vez en cuando, tenerlos en la cabeza.

Así, como estamos motivados para codificar cada vez mejor, en forma más legible, elegante, eficiente y fácil de mantener, son de gran ayuda.

Pero hay veces que uno tiene un día de m***. Enojado con la tarea, el trabajo, el mundo o la vida en general. O sin ganas de trabajar. O tal vez medio dormido después de una noche de juerga.

Hay veces que uno no tiene ganas de hacer las cosas bien. El que diga que no le pasó nunca, miente.

Yo aconsejaría no codificar en ese estado “de desgracia”, pero hay veces que la tarea es ineludible o que la tarea misma es la que nos pone de mal humor.

Así que empecé a pensar en tips para programar “en esos días de angustia y dolor”. Se me hace bastante más difícil, sólo logré esbozar algunas propuestas:

  • ¿Seguro que no puede resolverse sin codificar?
  • ¿O mejor dejarlo para otro día?
  • En fin… Si estamos modificando algo, considerar borrarlo e implementarlo de vuelta. Lo que hagamos en este estado tampoco será de gran calidad, de todas maneras.
  • Es preferible no comentar el código a comentar cualquier cosa.
  • Al copiar y pegar código sin mirar borrar los comentarios copiados.
  • Para días no tan malos, seguir las dos indicaciones anteriores y poner un comentario al principio (también al final, ¿será mucho pedir?) de lo copiado, indicando qué pretendemos que haga (y una plegaria pidiendo que por favor lo haga).
  • Asegurarse de que el muerto quede encerrado en un sólo procedimiento o clase.
  • Prestar atención aunque sea a los nombres y parámetros de los elementos públicos, no hay por qué molestar a los demás con nuestra desgracia… ok, los nombres de los privados pueden quedar para otro día.
  • Lanzar una excepción del tipo NotImplementedException o similar para casos del tipo “nah, eso no se va a dar nunca”. Es mejor que algún caso raro falte y se note a que el sistema “siga de largo” haciendo cualquier cosa.
  • ¿Todo en un sólo procedimiento de 500 líneas o más? Bueno, por lo menos dejar un par de renglones entre las diferentes partes. O si el día no es tan malo ponerle una línea de guiones de separación.
  • Es mejor poner el código de un recurso inexistente que hardcodear una cadena en la interfaz con el usuario (odio cuando los sistemas quedan traducidos a medias).
  • La performance puede quedar para el final… o mejor para mañana. Funciona, ¿no?

La consigna es “algo es algo”. ¿Ideas?

martes, 17 de febrero de 2009

La interfaz del usuario en un sistema de gestión.

Hablando puntualmente de sistemas de gestión tenemos en realidad varias interfaces de usuario:
  1. Orientada a la captura de datos.
  2. Orientada a la obtención de información.
  3. Orientada al análisis o búsqueda de información.

Recorramos cada una de ellas.

Orientada a la captura de datos: El usuario es un operario o empleado abocado a una tarea cuyo foco está fuera del sistema de gestión: atender a un cliente, a un proveedor, pagar una factura, recibir materiales. Otra posibilidad es que la carga de datos sea el objetivo en sí mismo (un data entry).

En el primer caso contamos con la mínima atención por parte del usuario, que tal vez ni siquiera mire la pantalla. En el segundo estará concentrado en el ingreso y verificación y su atención al resto de la pantalla será nula.

Lo esperable es una infinidad de pantallas prácticamente iguales, los clásicos ABM o CRUD. Aquí la regla número uno es simplemente no innovar. El usuario probablemente trabaje o haya trabajado con otros sistemas de gestión y espera algo muy específico: dato – [enter o tab] – dato – [enter o tab] – dato – [enter o tab] – fin. Cualquier cosa que se aparte de este camino le resultará molesta y probablemente inútil.

Este escenario sugiere el minimalismo, la simplicidad absoluta en el diseño de la interfaz. Esto coincide con las necesidades del desarrollo: es casi imprescindible generar estas pantallas a través de algún método en el que se ingresan los campos necesarios y la pantalla se genere automáticamente, asegurando la consistencia en el método de ingreso.

Orientada a la obtención de información: Nuevamente el objetivo central no es la información en sí. Será el control de la facturación, del inventario, de un envío o despacho de mercadería, etc. Son informes estándar, rutinarios y usualmente orientados al control de la operación.

Debería primar el minimalismo. Pocas opciones, pocos datos, y dispuestos de manera tal que facilite el control para el que fueron diseñados.

Aquí es donde fallan algunos sistemas. Estos reportes son usualmente puestos en la misma bolsa de los reportes de análisis, cuyo objetivo es otro (ya veremos). Es cuando el usuario se encuentra con un sinfín de posibilidades (vendidas como reportes “personalizables”, “configurables”, “autocustomizables” u otra palabra más o menos rara) en un momento poco oportuno. Si la tarea es rutinaria, ¿por qué el sistema me pregunta cada vez qué es lo que quiero?

Otras veces el reporte entorpece más de lo que ayuda, usualmente por algún detalle menor, que se vuelve terriblemente molesto.

Caso típico: el orden. Un ejemplo que me toca de cerca: cada vez que voy a buscar el recibo de sueldo me preguntan por el número de legajo que, obviamente, nunca recuerdo. Así que doy la única información de la que dispongo: mi nombre. Se imaginarán lo que sucede: hay que buscar secuencialmente entre todos los recibos, una y otra vez.

La “solución” a veces viene en forma de parche delirante: una segunda lista de empleados ordenada por nombre. Primero se busca allí el legajo, luego en la pila de recibos el correspondiente… un índice. Se le ha transferido al usuario parte del trabajo de la base de datos. Debería transferírsele también parte del sueldo del analista que diseñó el reporte.

La “customización” debería estar del lado del desarrollo, o de la parametrización, pero en todo caso del lado del proveedor de software. Al fin y al cabo éste debería ser producto de las horas de análisis funcional presupuestadas.

Muchas veces, amparado bajo el rótulo de “informes configurables”, el proveedor de software transfiere parte del análisis funcional al cliente -o lo que es peor, al usuario- al desligarse de la responsabilidad de decirle al sistema qué es lo que necesita. Esto no será un defecto siempre y cuando esa transferencia de costos se refleje en la factura del software.

Sin embargo, el problema de transferir esta decisión al usuario final es la posibilidad constante de error. Si para cada operación de control se solicitan más parámetros de los estrictamente requeridos para el reporte, un error en el ingreso de éstos es un error en el control.

Si se transfiere la responsabilidad al cliente –no al usuario, al cliente- y el personal -no necesariamente expertos en la administración del sistema- se equivoca en el armado de un reporte customizable podrían estar viciadas todas las operaciones de control derivadas.

Éstos son los “ABM” de los reportes. También deberían ser generados automáticamente durante el desarrollo. Es, en mi experiencia, la opción más simple.

Otra posibilidad, que dependiendo de las circunstancias podría llegar a ser más compleja o no, sería la creación de un módulo de reportes configurable. Pero… ¿no estaríamos recreando de alguna manera una herramienta de reporting, pero con menos posibilidades y orientada a un negocio específico? ¿no estamos reinventando la rueda? ¿no sería más simple utilizar una herramienta ya existente y entregar los reportes ya armados? No hay respuestas únicas. Pero éstas son preguntas que siempre deben estar presentes en la decisión.

Orientada al análisis o búsqueda de información: En este caso el usuario es un gerente, un ejecutivo de alto nivel, enfocado hacia el negocio, no hacia la operación. No sabe qué es lo que quiere, simplemente busca. ¿Qué busca? Muchas veces no lo sabe. Una variación, una anomalía, un producto que se desenvuelve mejor en un área que en otra (¿cuál? ¿en dónde? ¿por qué?).

Es, muchas veces, quien ha decidido, decidirá o puede decidir la compra, la adopción o la continuidad del software. Es El Cliente, con mayúscula.

Éste es el mundo de la “información estratégica”, y es aquí donde puede lucirse un sistema de gestión. Y puede hacerlo de dos maneras:

  1. Mostrando un conocimiento profundo del negocio, presentando reportes de análisis desconocidos para el usuario-cliente con información relevante.
  2. Presentando una interfaz que le permita navegar intuitivamente, buscar y encontrar aquélla información tan valiosa.

Para el equipo de desarrollo el primer camino es el de la experiencia, el segundo el de la pericia, la creatividad y la inversión en interfaces de usuario (los usuarios de Google Analytics sabrán a qué me refiero con pericia, la interfaz es bastante simple y permite hacer prácticamente cualquier cosa).

Las herramientas de data warehousing o almacenes de datos son una posibilidad, pero usualmente demasiado complejas para este tipo de usuarios. El desafío es adaptarlas de acuerdo al perfil concreto del cliente y del negocio en el que se desenvuelve. Delegar esta tarea en el cliente mismo, si bien es posible, implica arriesgar aquella funcionalidad en la que se podría marcar la diferencia.

En resumen: un sistema de gestión puede ser enorme, pero su desarrollo puede ser prácticamente automático. La energía debería concentrarse en las herramientas de generación automática (para las interfaces de ingreso de datos y reportes de control) ganando en bajo coste y velocidad en el desarrollo, y en la interfaz de análisis estratégico, donde puede diferenciarse de los demás productos o encontrar un nicho de negocio protegido.

lunes, 16 de febrero de 2009

Concéntrate en tus objetivos.

focus

Pase lo que pase.

Estuve toda la tarde acordándome de esta imagen (algunos de ustedes habrán tenido algo parecido en mente también) y no podía ubicarla. Era de Demotivator Blog.

Frankenstein, el líder de proyecto (IX).

ATENCIÓN: ¡No sigas si no has leído la octava parte! Y si no has leído nada empieza por el principio.


[Resumen: El módulo de pago a proveedores es terminado justo a tiempo por la recién nacida criatura de Frankenstein y pasa a pruebas. El analista a cargo tiene un extraño intercambio de palabras con el no menos extraño programador a raíz de un pequeño error en la especificación que finalmente es aclarado, pero…]

El analista se sentía mal. El cansancio mental había dado lugar al físico. Las pruebas del módulo de pago a proveedores lo estaban matando.

Los problemas habían comenzado la semana anterior, con aquel primer incidente del campo “Nombre” especificado como fecha… “Tendría que haber dejado las cosas en claro en ese momento, ahora es tarde”, pensó.

El programador había exigido –de una forma no muy sutil- que se corrigieran las especificaciones y se le asignaran las tareas correspondientes y él había accedido. Fue un grave error.

Un día después de aquello se instalaba la versión revisada del módulo. Y el formulario “Alta de responsables de aprobación de pagos” había vuelto a explotar, no sin antes revelar un sinfín de errores menores en la pantalla (una falta de ortografía, un par de tipeo, algún que otro mensaje confuso, botones no alineados). Esta vez, el problema final era que al intentar vincular un usuario que ya estaba vinculado al sistema éste explotaba por un –qué más- error de clave primaria en la base de datos.

La segunda conversación con el programador había transitado más o menos por los mismos carriles del día anterior. “Jaime” -el analista no conocía el nombre del programador y a estas alturas no deseaba saber nada más de él, así que había elegido uno a voluntad. El nombre, que surgió casi de inmediato, hacía referencia a aquel autómata del “Superagente 86”- volvió a dejar en claro con su particular estilo que no haría nada por fuera de las especificaciones o que no le fuera asignado a través del sistema de tareas.

Y él había accedido. Fue un grave error. Una semana después, con más de 200 incidentes ingresados uno por uno al sistema de asignaciones, con la quinta revisión del módulo instalada, tenía que admitir que era poco y nada lo que había avanzado realmente. Fue a hablar con Frankenstein.

-Te quería hablar de Ja… del chico éste, del nuevo.

-Increíble, ¿no?

-Si, realmente. Mirá, ya corrigió más de 200 incidentes y…

-¡En una semana! Es fantástico, este chico.

-Pero…

-¿Pero?

-Esto no funciona. Yo sé que esto te va a sorprender, me siento estúpido por no haberlo sabido parar a tiempo…

-¿Qué? ¿Hay algún problema?

-Es raro, estrictamente hablando, no, no hay. En los papeles está todo bien, quiero decir. Pero el chico se limitó a implementar lo que decían las especificaciones a rajatabla, como si no las hubiese leído realmente. El problema es que cada error, cada incongruencia -por más grosera que fuese- terminó en el sistema.

-Bueno, por fin alguien que respeta las especificaciones. Es cuestión de corregirlas.

-Si, ahora es cuestión de corregirlas y corregir el código, otra no queda. Pero el chico tendría que haberlas detectado y avisado, ¿entendés? Eso es lo que me preocupa. Hay errores que son sutiles en un documento de varias páginas, pero que al programar se vuelven demasiado groseros, demasiado obvios. No es común que pasen de largo. Si no fuera por esas formas tan extrañas que tiene… pensaría que está actuando con malicia. Pero en realidad creo que simplemente no piensa. Es eso, el chico simplemente no piensa.

-¡No es ese su trabajo! Para eso tenemos analistas, ¿no? Habrá que ajustar el trabajo de análisis y la revisión de las especificaciones –a Frankenstein le brillaron los ojos… ¿por qué limitarse a crear sólo programadores?

-Víctor… por más que ajustes las especificaciones éstas nunca serán perfectas… si el programador no le pone aunque sea un poco de ganas…

-Eso ya lo hemos discutido y estamos en desacuerdo. De todas maneras no tiene sentido que nos internemos en esas cuestiones metafísicas ahora, veremos luego. Por lo pronto pasále las correcciones y listo.

-Ése es el problema. Son demasiadas. En su mayoría pequeñeces, un sinfín de pequeñeces que hay que detallar individualmente porque si no simplemente no las corrige. No doy abasto…

Pero Frankenstein estaba cegado.

-Mirá. Las especificaciones estuvieron a cargo del equipo de analistas. Y por lo que me decís durante la codificación se las respetó a rajatabla. Creo que es responsabilidad del equipo de analistas asegurarse de que esa falta de calidad no retrase el proyecto. ¿No te parece?

El analista se sentía mal. Estaba cansado, realmente cansado. Eran las nueve de la noche, ya no podía fijar la vista en el monitor. Decidió irse a casa. Al pasar frente al cubículo de “Jaime” soportó maquinalmente el ritual de despedida al programador:

-¿Te falta mucho?

-Sí.

-Ya no queda nadie. Apagá cuando te vayas –pero sabía que “Jaime” se quedaría toda la noche.

…continuará. Actualización: capítulo X.

domingo, 15 de febrero de 2009

El fin del mundo.

Profundamente identificado.

tiraecol-284

Tira Ecol, visto mientras vagaba por Joserojas.org.

sábado, 14 de febrero de 2009

Lemmings tecnológicos.

Lemmings Los adoptadores de tecnología son como Lemmings: cuesta mucho que el primero se encamine en una dirección, pero una vez que los has conseguido el resto va detrás ciegamente aunque lo que tengan delante sea un abismo sin fondo.

Visto en La pastilla roja.

viernes, 13 de febrero de 2009

Jueguitos de Viernes: Gravity Pods.

GravityPods, o cómo hacer un buen juego con un par de líneas y mucha matemática.

gravitypods

Al fin y al cabo todo es open source…

…sólo hay que saber leer código de máquina.

eios

De Geek Hero Comic, que por si acaso les recomiendo (sobre todo a programadores, para los que tiene algunos guiños espectaculares).

jueves, 12 de febrero de 2009

En cumplimiento del deber.

“Cuando un hombre estúpido hace algo que le avergüenza, siempre dice que cumple con su deber.”

George Bernard Shaw.

Frankenstein, el líder de proyecto (VIII).

ATENCIÓN: ¡No sigas si no has leído la séptima parte! Y si no has leído nada empieza por el principio.


[Resumen: Frankenstein asigna a su criatura un módulo completo del sistema superando la resistencia de sus superiores y compañeros de equipo, quienes temen delegar tal responsabilidad “al nuevo” para que trabaje en solitario y sin supervisión. La criatura de extraño comportamiento trabaja constante e incansablemente hasta que termina.]

El módulo se integró al sistema y pasó al área de pruebas al otro día a las 10 de la mañana tal cual lo previsto en la planificación del proyecto.

Frankenstein estaba –por las razones que ustedes y yo conocemos pero que sólo serían comprendidas más adelante- visiblemente emocionado. Si bien el proyecto en general no mostraba un atraso preocupante, el módulo de pago a proveedores fue el único en pasar a pruebas a tiempo.

Imaginaba un ejército de programadores hechos a medida que revolucionarían el desarrollo de sistemas… los proyectos perfectos y a término, no más atrasos, no más imprevistos… y su nombre en bronce.

El analista a cargo de las pruebas del módulo –aquel buen compañero que había invitado a Frankenstein a ver una película- era un hombre de mediana edad pero con bastante experiencia. Sabía lidiar con los egos de los programadores, por lo que reportaba los errores de manera tal que no pareciese nunca culpa de ellos. Así, había conseguido su amistad y esa cuota de esfuerzo extra para corregir y volver a corregir hasta que todo estuviese perfecto. Era metódico, puntilloso y preciso.

Se sintió extrañado ante la reacción del “chico nuevo” ante el primer reporte.

Había comenzado por lo básico. Un formulario trivial, el de “Alta de responsables de aprobación de pagos”. Este formulario simplemente vinculaba ciertos usuarios del sistema con esa funcionalidad, apenas una asignación de permisos…

La pantalla explotaba mostrando el error en tamaño catástrofe. Luego de indagar un poco, llamó al responsable.

-Mirá este error –le dijo-, creo que se debe a que estás tomando el campo “Nombre” como de tipo fecha, ¿lo ves? ¿te parece que sea eso?

-Sí, efectivamente es eso.

-Pero el campo es de tipo alfanumérico… es el nombre del usuario, ¿no?

-Sí.

-¿Podrías corregirlo? Mientras yo voy avanzando con…

-¿Qué cosa? –interrumpió el programador.

-El error.

-¿Qué error?

-El campo “Nombre” que estás tomando como fecha y es alfanumérico, lo que provoca este error.

-No es un error. Así está especificado.

El analista miró fijamente al programador quien lo miró fijamente a su vez. Permanecieron así por unos instantes. No había malicia en la mirada “del nuevo”. Más bien recordaba –pensó el analista- la de un caballo o una vaca pastando… una mirada tranquila, transparente y… lejana.

De acuerdo con esta interpretación, sin de enojarse por lo que era a todas luces una soberana estupidez, consultó la documentación del módulo hallando –por supuesto- el pequeño desliz en la especificación.

-Efectivamente… así está especificado –dijo con una sonrisa cargada con una ironía que la criatura era incapaz de decodificar-… Mirá, para la próxima vez… es más fácil si en vez de codificar el error nos avisás y corregimos la documentación… así nos evitamos estos pasos intermedios, ¿ok?

-Eso no está en mi lista de tareas. Tal vez si hablas con Frankenstein él pueda indicarme que lo haga.

-Claro, claro… eso haré… mientras, ¿podrías corregirlo?

-¿Qué cosa?

El analista, a pesar de toda su buena voluntad, comenzaba a perder la paciencia. Sólo logró contenerse al invocar el peso de todos sus años de experiencia.

-Er… claro. Voy a pasarte la nueva documentación y a agregar un incidente en tu lista de tareas para que corri… para que implementes esta modificación.

La criatura no respondió (ya que nadie le había preguntado nada). Simplemente volvió a su lugar y se sentó, la vista fija sobre el monitor, los brazos inertes a los costados del cuerpo.

Fue la primera brisa que, con el clima aún en calma, precedió al huracán.

…continuará. Actualización: capítulo IX.

miércoles, 11 de febrero de 2009

Indicios de la Matrix.

¿Alguien puede decir sin temor a equivocarse que existe un mundo real allá afuera después de leer esto?

Círculo vicioso wikipédico-perverso (Microsiervos)

Lo trágico es que tampoco hay máquinas inteligentes del otro lado, evidentemente.

Más información aquí, por supuesto.

Sobre requerimientos, comunicación y honestidad cuando las papas queman.

Dark-Evil-41164

En Por dónde comenzar, hablando de gestión de requerimientos, Improbable ha dado a luz un párrafo genial que le da de lleno a mi falta de paciencia para con el área de análisis funcional (por lo menos con la que me toca convivir). Dice:

[…] recuerdo los valores ágiles de responsabilidad, honestidad, y demás virtudes. Pero ocurre que la gente es gente, y cuando las papas queman y alguien pregunta por determinados retrabajos o por qué se ha invertido seiscientas horas de desarrollo en algo que debería haber tardado doscientas, no es descabellado esperar que quien nos ha guiado a través de un camino sinuoso intente endilgarle la responsabilidad a otro. Quiero decir: que un Product Owner que nos ha hecho trabajar y retrabajar haciendo una cosa y luego la contraria continuamente intente explicar el poco valor conseguido luego de un tiempo considerable hablando de la falta de habilidades técnicas de los programadores.

#define evil_mode=1;

Pocas cosas son más molestas que cuando, sin haber cometido ninguna falta –condición más que fundamental para lo que sigue-, la gente se preocupa más por cubrirse que por hacer el trabajo, con actitudes como cambios que no se pasan por escrito, horas que se distribuyen entre otras tareas para ocultar retrabajos, olvidos sugerentes y demás.

Y es porque me da la sensación de que esto genera espejismos hacia la gestión del proyecto, que a falta –razonable y esperable- de conocimientos técnicos se guía por la percepción del desarrollo que nosotros exponemos, acumulada en forma de experiencia. Espejismos que luego nos juegan en contra.

Así, si nos “da vergüenza” pasar una semana con una funcionalidad que parece trivial y para la que estimamos dos horas, y en vez de poner el esfuerzo en explicar lo sucedido distribuimos esas horas en otras tareas, estamos fortaleciendo la imagen, por ejemplo, de que somos buenos estimando y de que lo que parece fácil es fácil. Estamos fijando un piso que difícilmente podamos mantener.

Pero una cosa es “distribuir horas” y otra es tirar la basura al patio del vecino (como describe el párrafo citado), siendo más conveniente (aunque harto más difícil) explicar a la gestión que los requerimientos no eran claros y que por presiones de tiempo se comenzó a programar lo antes posible, por lo que buena parte del tiempo de desarrollo fue en realidad tiempo de aprendizaje, prueba y error, ajuste y corrección sobre la marcha… una situación que simplemente se dio así y que no tiene nada de malo per sé…

…a menos que creamos que no somos tan buenos como deberíamos en lo que hacemos.

#define evil_mode = 0;

martes, 10 de febrero de 2009

Sony lanza SPS.

SPS = Stupid Piece Of Shit (¿tengo que traducir eso?). Una parodia genial a cargo de The Onion. No logro saber de cuándo es, pero en todo caso es la primera vez que lo veo, y aquí va.

“No puedo esperar a llegar a casa y pasar toda la pu** noche tratando de entender esta maldita cosa.” Muy bueno.

Visto en FayerWayer.

De los que viven en la oficina.

adicto al trabajo Un párrafo genial a cargo de Juan Carrión, en su entrada La Hipocresía Empresarial publicada en Jano 2.0:

[…]

A mí siempre me ha parecido que aquellos que “viven” literalmente en la oficina, o bien no saben hacer su trabajo de forma eficiente, o bien están haciendo el trabajo de dos personas, o bien no quieren volver a su casa. En el primer caso la solución puede ser la formación, en el segundo contratar a otra persona, en el tercero el divorcio. […]

…o todo a la vez, diría yo.

Frankenstein, el líder de proyecto (VII).

ATENCIÓN: ¡No sigas si no has leído la sexta parte! Y si no has leído nada empieza por el principio.


[Resumen: Después del fracaso de su sistema de control y de la retirada de uno de sus programadores Frankenstein se aboca sin éxito a la búsqueda de un reemplazante que cumpla con sus estándares, llegando a la conclusión de que no existe tal persona. Se dispone a crearlo y luego de dos años lo logra. Las primeras palabras de la criatura son “¿Donde está la lista de tareas?”]

El primer proyecto en el que participó la criatura fue el módulo de pago a proveedores de un ERP para una gran multinacional. Frankenstein, luego de elaborar la planificación del proyecto asignó “al nuevo” el módulo completo, ante la sorpresa de sus compañeros de equipo.

¿Te parece asignar todo el módulo a una sola persona? Trabajará aislado… encima es nuevo, recién empieza. ¿Qué pasa si se va, si se enferma, o si se retrasa demasiado? ¿Quién tendrá suficiente conocimiento del módulo como para sacar las papas del fuego en ese caso? ¿Quién hará el mantenimiento después?”

Pero Frankenstein sabía que “el nuevo” no se iría ni atrasaría ni se desmoralizaría ante el mantenimiento, por lo que insistió hasta que la asignación de tareas fue aprobada.

La joven promesa llegaba un poco antes que Frankenstein (exactamente 4 minutos y 23 segundos antes). Tenía la costumbre de esperar frente a la puerta mirando fijamente su reloj de pulsera hasta las 8.16. Luego se ponía en marcha (como despertando de un sueño profundo), llegando a su escritorio para presionar la primera tecla exactamente a las 8.30, hora oficial de entrada.

Normalmente completaba sus tareas a tiempo, pero si no lo hacía se quedaba hasta terminar con las asignaciones del día. Una vez lo encontraron temprano a la mañana, en la misma posición y con la misma ropa, los ojos rojos clavados en la pantalla. Un problema en la red de la empresa lo había retrasado, por lo que se había quedado programando toda la noche, y siguió durante todo el día.

Hablaba poco, aunque murmuraba frases sueltas mientras tipiaba. A veces se inclinaba sobre el monitor, la nariz rozando la pantalla. O se quedaba inmóvil durante varios minutos, las manos en reposo sobre el teclado y la vista fija al frente, hasta que comenzaba de nuevo.

Tipiaba a una velocidad constante e increíble durante varias horas seguidas. El programador de al lado pidió -por favor- que le dieran un teclado más silencioso, ya que el parejo trepidar de las teclas de su vecino le crispaba los nervios.

Era amable pero no socializaba ni ayudaba. Respondía siempre en forma seca, categórica, tajante, a veces sin siquiera detenerse. Ante cualquier cosa que representara una distracción afirmaba inevitablemente “No tengo tiempo asignado a eso.” y a veces -las menos- “Tal vez si hablas con Frankenstein él pueda indicarme que lo haga.”

Finalmente todos se acostumbraron a su no-presencia. Rara vez le hablaban. Nadie le pedía u ofrecía nada. Cada tanto, cuando el ruido empezaba a molestar, reemplazaban su teclado por uno nuevo.

Hasta que un día el murmullo apagado de las teclas cesó de repente. Por primera vez el programador apartó las manos del teclado. Permaneció con los brazos colgando inmóviles a los costados, la espalda recta y la vista clavada en la pantalla-. Estuvo así durante varias horas hasta que alguien se acercó.

-¿Te pasa algo?

-No.

-¿Por qué no estás trabajando?

-Terminé.

…continuará. Actualización: capítulo VIII.

lunes, 9 de febrero de 2009

Hablando de los “Best places to work”…

Hace un par de entradas -a cuento de Google como supuesta meca para desarrolladores- me preguntaba qué factor constituía a un gran lugar para trabajar y luego ensayaba una respuesta.

Luego confirmé que para algunos Google no es el paraíso y prefieren irse.

Pero la tendencia a querer ser “Un gran lugar para trabajar” –o por lo menos a querer parecerlo- ha comenzado. Por cierto que de manera muy tímida y sin garantías de continuar a futuro (y con esto de la crisis…), pero recordemos que hace un par de años un interés en ese sentido de parte de las organizaciones era impensable (por lo menos aquí en Argentina, donde en general se opina que debemos estar eternamente agradecidos por haber sido bendecidos con la gracia de tener un trabajo… cosa que es cierto de tanto en tanto).

Todo este divague para presentar una viñeta graciosa que encontré en Dilbert, un sitio que les recomiendo si es que no han pasado ya por allí, con muchos recursos además de las clásicas tiras diarias. Y aquí va la tira (no hace falta que se rompan los ojos, hagan click para verla a tamaño real):

39057.strip.sunday

Por cierto que si trabajan (como yo) en relación de dependencia y la sufren de vez en cuando estas tiras no son para leer un domingo a la noche, precisamente.

Tu proyecto está condenado al fracaso si…

  1. Todos los errores son priorizados como críticos.
  2. Todas las funcionalidades son priorizadas como triviales.
  3. Has copiado y pegado código desde The Daily WTF.
  4. Tu jefe no le encuentra la gracia a Dilbert.

Y así sigue hasta el 101.

Variable Not Found ha posteado 101 formas de saber que tu proyecto está condenado al fracaso, traducción del post 101 Ways To Know Your Software Project Is Doomed de {codesqueeze}. Imperdible.

Micromanagement y desarrollo de software.

lupa El término micromanagement refiere a un estilo de gestión que pretende controlar la ejecución de una tarea hasta el más mínimo grado de detalle.

Cerebrado describía una de sus formas en Requerimientos: cuando no son asteroides sino sólo polvo cósmico:

Un requerimiento normalmente diría:

El sistema debe detectar que el saldo de una cuenta ingresa en rojo y alertar al ejecutivo de cuentas asignado al cliente.

Pero hay veces en las que dice:

Implementar un trigger sobre la instrucción insert de la tabla cuentas_movimientos. En este trigger, cuando sld_cnt - deb_pnd + crd_pnd sea menor a 0 insertar un registro en la nueva tabla notificaciones con los siguientes valores: ....

En vez de indicar cuál es el resultado esperado de una tarea se especifica cada uno de sus pasos, quedando para el micromanagement zombie la mera ejecución de éstos.

Nos imaginamos entonces al manager obsesivo y malhumorado despotricando cada vez que alguien se aparta un milímetro del nítido camino que marcan sus instrucciones y al pobre esclavo asalariado sometido a través de toda clase de presiones a la ejecución de una lista interminable de mini-tareas de las que no puede deducir ningún objetivo a mediano plazo.

Pero lo primero que pensé es que estas relaciones no serían tan frecuentes si no hubiese también algo que ganar de cada lado. Traté de verlo en forma positiva:

  • El jefe gana en eficiencia, control, seguridad. También retiene para sí el conocimiento, la visión global del proceso. De esta manera no depende realmente de nadie y nadie puede hacerle sombra.
  • El zombie gana en tranquilidad, despreocupación, falta de responsabilidad. Su trabajo es usualmente fácil aunque tal vez –y sólo tal vez, esto hay que remarcarlo- aburrido. Probablemente su pasión transite por otros caminos.

Imagino que detrás de cada micromanager debe haber una personalidad insegura y por lo tanto desconfiada de aquellos que lo rodean y detrás de cada zombie un trabajador apático, desinteresado, ausente.

Eso puede funcionar muy bien para un picador de piedras o para un trabajador necesitado de la paga. Pero para el desarrollo de software en equipo no.

Por un lado porque las aplicaciones que requieren un equipo de desarrollo son demasiado complejas para una sola persona. Presentan desafíos que requieren experticia en varias áreas: codificación (y con distintos perfiles), administración de base de datos, análisis funcional…

Por otro lado porque en el desarrollo de software todos cometen errores todo el tiempo. Y la única forma de que eso no derive en un fracaso estrepitoso es el control mutuo bien entendido, que implica una actitud atenta y una visión crítica en cada uno de los actores.

Y porque en el desarrollo de software intervienen varios profesionales con visiones y métodos propios que no sólo hay que aprovechar sino respetar. ¿O alguien imagina al director de hospital indicando cómo debe operarse el corazón de cada paciente?

Esto puede sonar a evangelización ágil, así que aclaro: lo anterior es independiente de la metodología. Todas las metodologías proponen algún tipo de control y revisión, que puede ser burocrático y en determinados momentos o súper ágil y permanente, pero que existe. Pero finalmente algo escapará a todo control. Será el momento en el que el programador atento encontrará un problema y lo resolverá o discutirá con el resto del equipo. O el momento en el que un programador que sólo sigue instrucciones despreocupadamente… lo deje pasar.

A nivel personal la relación micromanager-zombie es una relación devastadora para ambos y para todos en el equipo. Un proyect lider que intente retener el control de todo se convertirá rápidamente en un cuello de botella y un torbellino de pequeñas decisiones –producto de su incapacidad para delegar ampliamente- lo perseguirá día y noche. Un programador -analista, administrador o tester- verá su desarrollo profesional estancado y pronto se dará cuenta de que la experiencia acumulada es inútil puesto que no ha aprendido a resolver problemas sino a implementar soluciones.

Y a nivel organizacional también. La organización se vuelve dependiente del manager que acapara el know-how del proceso y es incapaz de generar suficientes cuadros de reemplazo ya que el aprendizaje es imposible. Usualmente debajo de un micromanager de sistemas hay una alta tasa de rotación. Y ni hablar de la actualización tecnológica o metodológica. Es inviable pensar en la prosperidad de una nueva propuesta en un contexto así.

El micromanaging suele llevar al WTFismo: cuando sólo tienes un martillo (la cabeza del micromanager) todos los problemas se resuelven martillando. Si el micromanager es (o fue) experto en base de datos, todo será base de datos, si es (o fue) experto en C todo se hará en C, si aboga por determinada metodología (o participó en ella), se cumplirá a rajatabla… y así. Tanto peor en los casos en los que se impone una solución determinada independientemente de las personas que deben participar en el proceso.

¿Y entre programadores? Cuando respondemos dudas o discutimos soluciones ¿lo hacemos a vuelo de pájaro o tiramos una serie de pasos en estilo pseudocódigo? ¿Dejamos que los demás intenten por sí mismos antes de ayudar?

Los dejo con el test de Kathy Sierra:

  1. Do you pride yourself on being "on top of" the projects or your direct reports? Do you have a solid grasp of the details of every project?
  2. Do you believe that you could perform most of the tasks of your direct reports, and potentially do a better job?
  3. Do you pride yourself on frequent communication with your employees? Does that communication include asking them for detailed status reports and updates?
  4. Do you believe that being a manager means that you have more knowledge and skills than your employees, and thus are better equipped to make decisions?
  5. Do you believe that you care about things (quality, deadlines, etc.) more than your employees?

A "yes" to any of these -- even a half-hearted "maybe" -- means you might be creating Micromanagement Zombies

…y si eso no te preocupa tarde o temprano estarás en un problema… solo.