jueves, 27 de noviembre de 2008

Tipos de programadores.

Es genial la última de Sinergia sin Control. Si algún despistado no se ha suscrito a su feed, que lo haga ya mismo.

miércoles, 26 de noviembre de 2008

De desarrollador a líder de proyecto: desafíos de la gestión para el técnico recién ascendido.

¿Se puede liderar un proyecto de desarrollo de software sin conocimientos técnicos? ¿Son imprescindibles para la gestión, o sólo una ayuda? ¿Los mejores líderes son aquellos que ocuparon puestos técnicos en el pasado? ¿O los mejores son aquellos que han estudiado y ganado experiencia específicamente en la gestión, tal vez en varios rubros? ¿La gestión tiene nada, poco o mucho que ver con lo técnico?

Comencemos por dividir (arbitrariamente, claro está) a los líderes de proyecto en dos grandes grupos: los que llegan al puesto habiendo comenzando su carrera desde el lado técnico y aquellos que llegan comenzando desde del lado de la gestión de proyectos.

Los primeros (digamos "los gestores-técnicos") serían aquellos que comienzan como programadores y progresan naturalmente hacia líderes o referentes de su equipo.

Con el tiempo las funcionalidades bajo su responsabilidad son cada vez más amplias, el equipo cada vez más grande y eventualmente abandonan del todo la programación para dedicarse exclusivamente a la gestión de uno o varios proyectos.

Bajo su responsabilidad pueden caer ya no sólo programadores sino también analistas funcionales, testers, diseñadores, administradores de sistema, de base de datos, personal de mantenimiento, soporte al cliente, etc.

Los segundos (digamos "los gestores de carrera") serían los estudiantes de carreras como Administración o Gestión de Empresas, que comienzan ayudando en la gestión de proyectos (de cualquier tipo) y van progresando hasta alcanzar el liderazgo de uno.

Así que a la pregunta "¿se puede liderar un proyecto de desarrollo de software sin conocimientos técnicos?" yo respondo "sí, absolutamente".

Por supuesto que el gestor de carrera deberá tomar experiencia en el rubro, que como cualquier otro tiene sus particularidades, su jerga, sus recovecos. Dispone para ello de un marco teórico: sabe de métodos de estimación de tiempos, de seguimiento, de ajuste, de administración de recursos, de manejo de personas, de motivación, etc.

Tendrá que aprender cuáles son las diferentes etapas del desarrollo, las muchas posibilidades que existen para recorrerlas, sus ventajas y desventajas, cuáles son los requerimientos, los productos, los tiempos y el personal necesario para cada una de ellas.

Para el gestor técnico el salto es inverso y simétrico: conoce el rubro pero deberá aprender a tratar con personas, a motivar, a liderar, a coordinar más allá de lo técnico, a evaluar y negociar cuestiones económicas, políticas, emocionales.

Desde un lado o de otro se puede llegar a cualquier nivel de excelencia o chapucería.

Pero hay un tema. El conocimiento técnico ayuda, por supuesto, sólo si no se hace abuso de él. Obviamente, el único que puede presentar estas tendencias hacia el abuso del conocimiento técnico es aquel líder con un pasado como desarrollador, ya que tiene que ver justamente con ese origen.

¿A qué me refiero cuando digo tendencias hacia el abuso del conocimiento técnico? Es más fácil dar ejemplos que tratar de definirlo, así que invento algunos:

  • Imponer estimaciones de acuerdo a su conocimiento técnico. Pero ya no es él quien ejecuta las tareas (eso era antes), y puede que no acepte que los tiempos de su equipo ya no son necesariamente los que él hubiese presentado.

    Por otro lado, un gestor de carrera confía necesariamente en las estimaciones de su equipo, simplemente porque como él no puede evaluarlas técnicamente no puede discutirlas. Podrá negociarlas, requerir más esfuerzo o más recursos, pero jamás objetarlas en términos de "esto está bien o mal".

    Claro que el gestor de carrera puede imponer estimaciones. Como dije antes, a la chapucería se llega desde cualquier lado.

  • Reservarse la resolución de cuestiones técnicas y no transmitir requerimientos funcionales. Es un poco lo que comentaba en Requerimientos: cuando no son asteroides sino sólo polvo cósmico.

    Si el líder no controla su "corazoncito técnico", puede tender a resolver requerimientos y distribuir sólo directivas técnicas ("armar una base de datos así y asá") en vez de directivas funcionales ("hay que hacer un módulo de ventas").

    Pueden seguir la entrada referenciada para ver los problemas que (en mi opinión) ello ocasiona. Por otro lado, el gestor de carrera transmite sólo requerimientos funcionales ya que no conoce de soluciones técnicas.

  • Evaluar técnicamente al equipo de acuerdo a parámetros propios. Estos parámetros pueden estar obsoletos o no ser objetivos.

    Es el caso del líder de proyecto "del ciclo de vida" que evalúa "cantidad de líneas de código escritas".

    El gestor de carrera no cuenta con criterios propios para evaluar técnicamente al equipo por lo que deberá buscar parámetros objetivos: una opinión externa, una auditoría de código o similar.

    Buen momento para recalcar nuevamente lo de la chapucería: el gestor de carrera también puede confiar ciegamente en las capacidades técnicas de su equipo, o no preocuparse por ellas y evaluar sólo los resultados... hasta que todo colapsa como una cáscara vacía.

  • Desestimar nuevas herramientas, nuevos lenguajes, nuevas tecnologías. Tal vez por rechazo a perder del todo el control: si se adoptan nuevas tecnologías su conocimiento previo ya no se aplicaría al proyecto, por lo que perderá cierto grado de poder de decisión.

    Un gestor de carrera no tiene pretensiones de control técnico del proyecto. Sólo le interesará el rumbo funcional o de negocio, que es lo que cae bajo su responsabilidad.

  • Desestimar herramientas metodológicas o mejores prácticas de la gestión de proyectos, por considerarlas demasiado formales o informales, demasiado simples o complicadas, o simplemente inútiles.

    Una suerte de desprecio por la teoría del campo de la gestión de proyectos (que no es el propio), sobrevalorando las cuestiones técnicas frente a las administrativas.

    Al revés también se da: muchos gestores de carrera desprecian las tareas de codificación. Pero lejos de dañar al proyecto esto lo beneficia: cada uno a su trabajo.

Verán que todos los puntos tienen una raíz en común. En el fondo está mi propia visión del líder de proyecto: un profesional entre profesionales, un profesional de la gestión.

Una cuestión cultural, una estructura (tal vez en decadencia pero de todas maneras) muy extendida, ubica al líder de proyecto "por encima" de otros profesionales: programadores, técnicos en hardware, administradores de base de datos, etc.

Eso hace que a veces se olvide que el trabajo del líder es obtener y administrar a las personas y a los recursos, coordinar el trabajo en equipo y llevar las riendas de las negociaciones y gestiones necesarias entre el equipo y el exterior... (entre otros, claro).

El tema es, ningún profesional debería decidir en el campo del otro. Pensemos en estas situaciones: programadores decidiendo funcionalidades, líderes de proyecto imponiendo fechas en las que "tiene que estar todo", clientes requiriendo (caprichosamente) determinada tecnología, programadores haciendo testing, analistas funcionales diseñando reportes en SQL.

Son todas situaciones en las que un actor de esta comedia a la que llamamos "desarrollo" invade el terreno del otro. Es allí donde se originan los problemas.

Recordemos que el tema de este post fue: las tendencias, los sesgos que debe afrontar un técnico que deviene en líder de proyecto. No creo que ningún pasado X impida ser buen líder o que el mejor líder es aquel que estudió la teoría en una facultad. Otra vez: ambos caminos pueden conducir tanto a la chapucería como a la excelencia.

domingo, 23 de noviembre de 2008

Patos criollos: 20 desastres relacionados con el software.

En cuatro post de VariableNotFound... ¡y con más referencias al final!

Ideales para esgrimir como excusa cuando metemos la pata: "Mire, si le puede pasar a la NASA..."

Ah, por las dudas que algún despistado no entienda. Pato criollo = "cada paso una cag...".

viernes, 21 de noviembre de 2008

Juegos de viernes: Jelly Towers.

"¡Hoy es viernes! ¿Dónde estuvo mi juego? Eran las tres de la tarde y yo trabajando."

Qué costumbrista que es la gente... perdón, la verdad que lo tenía agendado y me olvidé de postearlo.

Tarde pero seguro, acá les dejo Jelly Towers, que tiene un objetivo bastante original: tenemos que alimentar a... no sé, unos gusanos, con gelatina.

Se complica que da calambre.

miércoles, 19 de noviembre de 2008

Frases: reciprocidad.

"No te trataré como una prioridad cuando me tratas como a una opción"

Visto en El pito doble por Cerebrado.

martes, 18 de noviembre de 2008

Guía para perplejos: primera vista al código en un nuevo trabajo y... ¡ups!

La anécdota es común, casi una leyenda urbana... cosas que a nadie le pasó pero a todo el mundo le contaron, y reza casi siempre en variaciones del siguiente tema:

"Durante las entrevistas de trabajo todo me pareció perfecto... se habló de implementar las últimas tecnologías y mejores prácticas, de innovación, de una rueda interminable de nuevos y desafiantes productos a implementar.

La gente con la que hablé me pareció de mucha experiencia en el rubro, sin miedo a admitir errores y con ganas de corregirlos a futuro, así que no dudé en cambiar de trabajo.

Ya en el primer día de trabajo, al bajar a detalle, a ver el código... ¡Horror..."

Luego viene una gran lista de WTF's vinculados al desarrollo de software (pueden buscar ejemplos divertidos en The Daily WTF): que tal cosa estaba horriblemente mal, que tal otra era directamente un delirio, que esto no se usa así y que lo otro no se usa asá, o que el jefe esto y el jefe lo otro... La historia en general finaliza con el protagonista huyendo despavorido sin mirar atrás.

Sin exagerar, creo que todos los que entran a un nuevo ambiente de trabajo o a un nuevo proyecto se encuentran con alguna que otra cuestión extraña, no del todo clara, o directamente... digamos... que está mal. Esto es normal, todo equipo tiene sus vicios o errores.

La situación puede ubicarse en una escala que va desde lo divertido a graves errores (siempre desde el punto de vista del ingresante) no ya puntuales, sino de concepto, tanto en el código como en el proceso, pasando por cuestiones que pueden llamarse "de criterio" donde se acepta una visión diferente a la propia sin estar de acuerdo, pero reconociendo sus razones.

La pregunta que propongo es ¿cómo actuar en un caso extremo? Lo que sigue a continuación es lo que yo hice (no "hice correctamente" sino simplemente "hice") e intentaría hacer, aclarando desde el vamos que nunca me vi en una situación así, extrema, donde "está todo mal" y "esta gente no sabe lo que hace y no entiende de razones".

Creo que lo primero y principal es ubicarse y bajarse del caballo, sobre todo si nos integramos a un desarrollo que ya está funcionando.

Es decir, desacelerar, bajar un cambio, no hacer declaraciones rimbombantes, explosivas ni mucho menos agudas o que puedan resultar hirientes para el autor o responsable de lo que se objeta. Creo que podría ser más absoluto: en principio, lo mejor es no decir ni dar a entender absolutamente nada.

¿Por qué? Vamos, reconozcamos que sería poco profesional de nuestra parte entrar a un equipo y declarar, luego de dos o tres días de trabajo "esto está todo mal". ¿Qué análisis pudimos realizar en ese tiempo? ¿Qué tanto pudimos saber en un par de días de las personas que lo hicieron, de cuándo fue y en qué circunstancias?

Así que el segundo paso es, simplemente, recabar información, conocer a las personas que nos rodean y entender cómo llegaron a eso. Todo, absolutamente todo en un desarrollo tiene su razón de ser. Obviamente los orígenes pueden no ser técnicos, pueden ser... digamos "históricos": tienen que ver con una historia que no conocemos y en la cual todavía no escribimos ni una coma.

Esta actitud pone a prueba el respeto al trabajo ajeno: podemos criticar, pero es una falta de respeto hacerlo sin conocer no sólo el problema (que puede que sólo nosotros estemos viendo) sino aunque sea un poco de su historia.

Después de un tiempo (que dependerá también de las urgencias del caso) sin que nos hayan preguntado explícitamente, se puede tantear a ver si una recomendación encuentra algún oído atento. Más que decir "esto está mal", es mejor enfocar las cosas por el lado de "se me ocurrió que podríamos cambiar esto y..."

Pueden pasar dos cosas: que seamos escuchados o que no. En el primer caso es un buen comienzo, independientemente de si "nos hacen caso" o no. Es decir, si alguien escucha y defiende "ese delirio", está bien. Es lo lógico. De a poco, cada vez con más confianza, se puede debatir o incluso pelear. Pero hay que tener en claro que para pelear hay que ganar cierta confianza.

Digresión (está bien escrito, ver RAE): en general no me peleo "mal" con mis compañeros de equipo, pero a veces pasa. Y pasa porque hay cierta confianza que permite pelearse de vez en cuando sin que eso sea catastrófico. Hasta diría que un equipo en el que no hay peleas es algo sospechoso. Si uno tiene una idea, la defiende. Y hay veces en que a uno o a otro se le suelta un tornillo o lo toma a personal (o era personal)... la vida sigue.

Está el tema del tiro por elevación: ¿qué pasa si sentimos que el problema está en una persona en particular? Puede ser un compañero, un líder de proyecto, un analista, un gestor, lo que sea. ¿Hablamos con su superior? Puede ser, nunca sin haber intentado por todos los medios debatir con él primero, y teniendo en cuenta que puede "salir mal", por lo que se vuelve más importante que nunca tener un planteo coherente, no agresivo, y una propuesta de solución.

Ahora, ¿qué pasa si realmente no vemos posibilidades de cambiar las cosas, o sentimos que no queremos hacer semejante esfuerzo? Bueno, nada. Alejarse. Buscar otro trabajo, cumpliendo lo mejor posible con la tarea que se nos asigna mientras tanto. Sin escándalos, y sobre todo, sin "tirar basura" a los que quedan para irse con un portazo, eso sólo habla mal de uno mismo.

Aclaro otra vez: que no conozco la verdad revelada, y que lo que creo o recomiendo surge más de mis errores que de mis aciertos. En el papel (o la pantalla) es todo muy fácil, pero la vida real es otra cosa. Supongo que lo único que se puede hacer en este tipo de situaciones muy complicadas es hacer el mayor esfuerzo posible.

lunes, 17 de noviembre de 2008

De la falta de visión del desarrollo profesional en las pymes.

Siempre trabajé en pequeñas y medianas empresas o emprendimientos de uno o dos socios. Aunque conozco de oídas la experiencia de la "gran consultora o empresa" por compañeros de facultad, trabajo y amigos, no es la mía. Tengo que aclararlo porque mis impresiones deben estar necesariamente sesgadas por esto.

Aclarado el punto, entramos en tema.

Es difícil que exista un Plan de Carrera institucionalizdo en una pyme. Es común que para programadores, analistas o integrantes de la rama de gestión el desarrollo profesional debe transitar otros caminos, más personales.

Esto implica estudios universitarios o cursos y certificaciones a los que la empresa puede aportar, por ejemplo brindando días para estudio o financieramente, pero la tracción tendrá que estar en cada uno. Quiero decir que no habrán ofertas institucionales, más bien hay que pedir, suplicar o exigir de acuerdo al caso. Y algunas veces la empresa entorpece más que ayuda al avance profesional.

Por otro lado, el desarrollo de software es un rubro que por su dinámica depende mucho del aprendizaje. Cuando no se aprende, cuando no se mejora o no se está al corriente de las tendencias y tecnologías, el estancamiento lleva al fracaso.

Esto es así en cualquier industria, por supuesto. Pero los cambios tecnológicos impactan más rápidamente en el desarrollo de software, por lo que el aprendizaje debe ser continuo. Actualmente es imposible decir que un producto, por más completo (funcionalmente) que esté, está "cerrado". La tecnología avanza a paso acelerado, los clientes y usuarios demandan funcionalidades impensadas hace apenas un par de años, y la competencia es feroz.

Así que las pymes tienen el difícil compromiso de crecer junto a los profesionales que la integran. Es esto o la rotación constante, o el estancamiento. En mi experiencia, la norma ha sido la rotación o el estancamiento.

Por rotación se entiende que alcanzado un punto, se percibe que:

  • No hay espacio para crecer: la estructura institucional es pequeña y los puestos escasos.

  • No hay recursos: el día a día no da tregua y no hay presupuesto para más personal que alivie la carga de trabajo dando espacio a la investigación y experimentación.

    Los profesionales son constantemente tentados con ofertas de otros proyectos y la empresa no puede retenerlos.

  • No hay una visión que dé importancia al aprendizaje y la innovación: en realidad, éste punto está en el origen de los otros dos, porque cuando existe una clara visión de aprender e innovar se buscan los medios, y usualmente aparecen.

    Pero de todas maneras, con o sin visión institucional, los profesionales del área crecen. Y cuando no hay una visión se encontrarán con que han crecido más que la empresa, o que para crecer tienen que buscar otros destinos.

Aunque parezca contradictorio, creo que en una pyme la rotación ayuda. Evita el estancamiento. Obliga a la empresa a depender un poco menos de las personas y apoyarse un poco más en los procesos... o morir. Es bueno apoyarse en las personas, pero me parece que la norma en una pyme es el completo desbalance en este sentido. Es la clásica imagen del trabajo descordinado, desordenado e ineficiente (aunque muchas veces creativo) de estas empresas.

La partida de un socio, gerente o trabajador estrella en una pyme es un momento de crisis. Habrá que ver si los procesos (los que existan) soportan la pérdida de conocimiento que ello implica y si se logran captar profesionales que logren cubrir el espacio y mejorar.

Es decir, si la empresa sobrevive a la rotación, se verá fortalecida. Habrá superado una etapa en la que muchas fracasan.

En todo caso, obliga a la empresa a hacer lo que por falta de visión no hace de manera ordenada: cambiar, mejorar, mantenerse al día con la tecnología.

Decía al principio, rotación (con aprendizaje o muerte) o estancamiento. El estancamiento se da cuando la falta de visión hace que los profesionales que crecen se alejen, quedando siempre los más conservadores y reacios a los cambios. Si la sangre nueva no logra cambiar las cosas la rotación continuará en un proceso de selección natural en el que queden sólo los más conservadores, fortaleciendo la tendencia. El mercado decidirá cuánto puede durar esta situación.

Imagino que por aquí está la clave del conflicto constante en las pymes. El desarrollo, el aprendizaje, no es parejo, no es ordenado, se da aleatoriamente. Programadores estancos en una tecnología determinada, un un líder de proyecto "del ciclo de vida", un gerente conservador, pueden asfixiar lenta y discretamente a una pyme. Cuanto más arriba más difícil el cambio, pero no importa dónde, el conflicto será permanente.

viernes, 14 de noviembre de 2008

Frases: malicia e incompetencia.

Nunca atribuyas a la malicia lo que puede explicarse por la incompetencia.

Napoleón Bonaparte.

Juegos de viernes: Gold Miner

Gold Miner es un juego simple y terriblemente adictivo, perfecto para restarle un día de trabajo a la semana.

Parece sencillo pero se complica rápidamente...

El viejazo.

Alguna vez comenté que de un tiempo a esta parte estoy medio sensible a los viejazos (ver aquí y aquí). Para que quede claro, definí "viejazo" más o menos así:

Uno de esos momentos en que algún manejo de fechas medio desprolijo devuelve un resultado que en principio sentimos como un "way out of range" pero que después se valida.

Bueno, me acaba de pasar. Pero esto es más que un simple viejazo. Esto es como una bofetada:

(Foto de Kirk Weddle, visto en Alt1040)

Me parece imposible que alguien no sepa qué es, pero por las dudas:

¡Es el mismo flaco! A ver, yo compré ese disco cuando estaba en el secundario, un poco antes de que explotara la cosa. Nunca fui gran fanático (es el único disco de ellos que escuché con atención), pero fui a verlos (no me gustó demasiado)... quiero decir... ya era "grande" cuando ese pibe, que ahora es bastante "grande" era un bebé...

No somos nada.

jueves, 13 de noviembre de 2008

Pedrito (el líder de proyecto) y el lobo: la importancia del feedback.

Todos conocen la historia de Pedro y el lobo. Por las dudas se las refresco:

<spoiler>

Pedro era un pastor que se divertía gritando que venía el lobo sólo para molestar a la gente del pueblo, que corría inútilmente a ayudarlo. Hasta que finalmente vino el lobo. Pedro gritó pero como lo había hecho tantas veces en broma nadie le creyó... Las versiones varían: en el cuento infantil se dice que el lobo se comió unas ovejas, yo digo que también atacó a Pedro y lo dejó inválido y deforme para toda la vida.

</spoiler>

A veces sucede algo por el estilo en el desarrollo de software: se establece una fecha difícil (mas no imposible) de cumplir, la presión se hace sentir, el equipo hace un esfuerzo extra, se trabaja a las apuradas, a deshoras, se llega a tiempo o no, y luego... nada.

¿Nada? Sí, nada. Ni para bien ni para mal. Nada si se ha cumplido o alguna suerte de reprimenda o discurso sobre la responsabilidad, la confianza y los compromisos asumidos, si es que no. La vida sigue, el desarrollo continúa, se agregan funcionalidades, se corrigen errores... la presión desaparece...

Supongamos que ésa es la situación percibida, ¿cuál es el origen? Si no tenemos más información hay que inventarla. Inventemos. Me imagino tres escenarios, que se pueden ir completando a placer:

  1. La fecha límite fue artificialmente establecida para "meter presión" al equipo. La creencia subyacente puede ser que la gente se "relaja" cuando no tiene un límite de tiempo, se pierde en detalles o simplemente vaguea.

  2. La fecha era real, pero poco importante. No hay un cliente comprometido ni socios desesperados. El líder apunta que (a ojo de buen cubero) no está tan lejos de "quedar bien" hacia arriba terminando justo a tiempo (o un poco antes) si presiona hacia abajo. O tal vez era un hito interno en su línea de tiempo, y exagerar la importancia de esas fechas es su manera de tener las riendas cortas.

    Así que presiona. Si llega mejor, y se olvida de bajar las felicitaciones (o no las hubo, porque esto puede suceder a cualquier nivel). Si no se llega aparece el discurso un tanto licuado y abstracto mencionado más arriba, porque al fin y al cabo no hay una gran mala noticia.

  3. El límite existe, y sí era importante.

    Una posibilidad es que el líder haya utilizado su cintura para "zafar" de la situación y todo pasó de largo.

    Otra posibilidad es que, intentando "resguardar" al equipo de presiones excesivas, actuó como paraguas y no bajó el escarmiento.

En resumen: la fecha no existía, o sí pero no era importante, o sí pero el equipo no se enteró de las consecuencias.

Independientemente del origen o las causas subyacentes, si la comedia anterior se representa un par de veces los integrantes del equipo reaccionan como los habitantes del pueblo: simplemente se vuelven inmunes a las fechas límite y renuentes a hacer cualquier esfuerzo extra para cumplirlas.

Esta reacción es esperable, incluso la más lógica y, desde el punto de vista del equipo, la más sana. La experiencia les ha enseñado que esforzarse por alcanzar esas fechas no tiene ningún beneficio, ni su incumplimiento consecuencia alguna.

Es terríblemente difícil salir de esta situación sin un hito desagradable (como sería para Pedro aparecer sin un brazo o una pierna) o costoso (Pedro podría perder algunas ovejas), un golpe de efecto. Se necesitaría, por ejemplo, la pérdida de un cliente o la aparición de un bonus por cumplimiento de la fecha de entrega. Desagradable o costoso. Malo o menos malo (desde el punto de vista de la empresa), malo o bueno (desde el punto de vista del equipo).

Pensemos en cómo el feedback, en cualquier caso, modifica las cosas (cada punto es el correspondiente a la situación mencionada arriba):

  1. Por más que la fecha establecida sea "artifical", proporcionar feedback demuestra preocupación por el estado del proyecto, conciencia de su estado, monitoreo constante. Es decir, demuestra la importancia que se le asigna, el interés que tiene para el líder. Sea este interés ficticio o no, motiva. O por lo menos no desmotiva, como sí lo hace una fecha que luego pasa prácticamente desapercibida.
  2. Si la fecha es poco importante, se aplica el mismo razonamiento del punto anterior. Podemos además agregar que la fecha alguna importancia tiene. Si es importante para el líder puede ser importante para el equipo. Por ejemplo, quedar bien hacia arriba es un beneficio que se multiplica al ser extendido a cada uno. ¿Por qué no hacerlo?
  3. Si la fecha era realmente importante, es tal vez el peor caso. Los motivos para el compromiso están, pero no son transmitidos. No es raro notar la falta de éste.

En todo caso, la ausencia de feedback sólo puede dar indicios negativos: poco interés en el proyecto o presión acumulada en "algún lado" o manipulación grosera y finalmente inútil (BTW: ¿"manipulación" es "motivación grosera" por definición?), un líder ausente o... no perfecto (para decirlo políticamente).

Un líder de proyecto tiene muchas tareas y atribuciones. Pero para un equipo de profesionales todas pueden resumirse en una: establecer un medio en donde la información fluya, ya sea comunicando o facilitando u obligando a los demás a comunicarse, en todas la direcciones.

Hay mucho que comunicar en un proyecto de software: los requerimientos, las restricciones, los recursos, los avances, las novedades, los cambios, todo. En un equipo de profesionales, un líder no impone sino comunica... bueh, esto dependerá también de qué tan profesional sea el líder ¿no?

El hecho es que siendo un sistema de comunicación (ver artículos relacionados), cualquier problema de comunicación en un integrante del equipo, y más en el lider, es muy problemático.

Sobre esto último, algunos relacionados:

La autopista del desarrollo.

Una clase sobre buenos modales.

Comunica... ¿QUÉ?

Del desarrollo de software como sistema de comunicación y la importancia de poder leer y escribir.

Problemas eléctricos...

Andamos con problemas eléctricos en la oficina, así que quería recordarles a mis compañeros de trabajo (y a todo el mundo) que...

Frases: procrastinador profesional.

Me gustan las fechas límite. Me encanta el zumbido que producen al pasar de largo.

- Douglas Adams

Visto en Microsiervos.

miércoles, 12 de noviembre de 2008

Frases: información.

Si tienes información, úsala. Si no la tienes, búscala. Si no la encuentras ¡inventa!

- No sé de quién es (¡ayuda!)

Factores de motivación.

Llego un poco tarde, así que supongo que algunos ya habrán leído Motivación - La lista, de tictac.

En este post ordena los resultados de una propuesta de armar una lista de "elementos que os motivan, motivaron u os motivarían como empleados".

Creo que se ha armado un buen resumen, con el que coincido muchísimo:

  • Confiar en las personas que tengo alrededor.
  • Transparencia y comunicación.
  • Empleabilidad (yo diría "usabilidad").
  • Flexibilidad, variedad y movilidad.
  • Gozo intelectual.

Son sólo los títulos, los detalles aquí.

Un artículo mío más o menos relacionado, aquí.

martes, 11 de noviembre de 2008

Frases: siempre hacia delante.

Jamás retrocedas. Sólo da media vuelta y sigue avanzando.

Programar es sólo escribir.

Hace un tiempo, en Codificando... divagando... es lo mismo comentaba qué era lo que pasaba por mi cabeza cuando programaba... mejor dicho, cuando escribía código, que no es lo mismo. Tenía curiosidad por saber si mi forma de escribir código era "rara" o "normal":

[...] Y es que no, no estoy pensando si se entiende por ello el buscar una solución a un problema, o el buscar algo en la memoria. Más bien estoy en un estado parecido al de este mismo momento (ésa es la idea que me llamó la atención). Estoy escribiendo, como quien escribe un documento, una carta, o lo que sea. Y como todo autor, le escribo a un lector imaginario (¡en serio!) [...]

Hoy me encuentro en Coding Horror con Coding: It's Just Writing, en el que se comenta un poco el mismo paralelismo entre la escritura de código y la escritura, a secas.

Me agendo para leer un artículo de Donald Knuth al que se hace referencia, Literate Programming (sugerente, el título):

Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.

The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style. Such an author, with thesaurus in hand, chooses the names of variables carefully and explains what each variable means. He or she strives for a program that is comprehensible because its concepts have been introduced in an order that is best for human understanding, using a mixture of formal and informal methods that reinforce each other.

lunes, 10 de noviembre de 2008

Frases: Admitir los errores.

Un hombre nunca debe avergonzarse por reconocer que se equivocó, que es tanto como decir que hoy es más sabio de lo que fue ayer.

Swift, Jonathan

Codificación: datos de la aplicación como recursos XML embebidos (parte IV).

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

IV. Que funcione.

Ya tenemos nuestras clases de definición de menú alimentadas por un recurso incrustado en el ensamblado, ahora vamos desde el front-end.

Dejemos Form1 para pruebas. Agregamos un nuevo formulario: frmPrincipal, y en él un TreeView, trvMenu. El código del formulario será:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace EjemploRecursosXMLEmbebido
{
    public partial class frmPrincipal : Form
    {
        public frmPrincipal()
        {
            InitializeComponent();            
            CargarMenu(Menues.Raiz, this.trvMenu.Nodes);
        }

        private void CargarMenu(MenuItem definicionMenu, TreeNodeCollection contenedor)
        {
            TreeNode menuNodo = CrearNodo(definicionMenu);
            foreach (MenuItem definicionSubmenu in definicionMenu.Submenues())
                CargarMenu(definicionSubmenu, menuNodo.Nodes);

            contenedor.Add(menuNodo);
        }

        private TreeNode CrearNodo(MenuItem menu)
        {
            TreeNode nodo = new TreeNode();
            nodo.Text = menu.Titulo;
            nodo.Name = menu.Id;

            return nodo;
        }


    }
}

Son solamente dos procedimientos: CargarMenu, que recorre recursivamente la estructura de definiciones de menú y CrearNodo, que es una función que crea el nodo correspondiente a cada definición de ítem de menú.

Dejé para este momento el tema "que haga algo" para ejemplificar las bondades del encapsulamiento del XML en esta manera.

¿Qué sucede cuando seleccionamos alguna opción en el menú? Por lo pronto, nada. Lo lógico sería que de alguna manera se visualice el front-end de la funcionalidad correspondiente. Necesitaremos algunas definiciones extra para avanzar.

Sólo a modo de ejemplo (no me gusta mucho cómo queda), implementaremos el front-end de cada funcionalidad como un UserControl. Así que colocamos un SplitContainer (splitContainer1) en el formulario. Éste lo divide visualmente en dos controles Panel (splitContainer1.Panel1 y splitContainer1.Panel2). En splitContainer1.Panel1 colocamos trvMenu. En splitContainer1.Panel2 cargaremos un UserControl creado dinámicamente cuando el usuario haga click en un ítem del menú.

Comencemos con sólo dos funcionalidades del menú: Compras/Presupuestos y Compras/Ordenes.

Primero, agregamos dos nuevos UserControl al proyecto: uscComprasPresupuestos y uscComprasOrdenes. Pongamos cualquier cosa dentro de ellos. Yo he puesto simplemente un Label con el nombre de la funcionalidad.

Segundo, agregamos código al evento NodeMouseDoubleClick en frmPrincipal para que cargue el control correspondiente de acuerdo al menú que ha recibido el evento:

private void trvMenu_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
    UserControl frontendUC = null;
    switch (e.Node.Name)
    {
        case "compras_presupuestos":
            frontendUC = new uscComprasPresupuestos();
            break;

        case "compras_ordenes":
            frontendUC = new uscComprasOrdenes();
            break;
    }

    //si no tiene front end asociado no hace nada
    if (frontendUC == null)
        return;

    //si ya hay un front-end cargado, lo eliminamos.
    if (this.splitContainer1.Panel2.Controls.Count > 0)
        this.splitContainer1.Panel2.Controls.RemoveAt(0);

    frontendUC.Dock = DockStyle.Fill;
    this.splitContainer1.Panel2.Controls.Add(frontendUC);

}

Este código tiene un switch en el que se selecciona el control correspondiente de acuerdo al nombre del nodo (recordemos que habíamos asignado a cada nodo un nombre igual al id del menú en su definición en el archivo XML). Si no hay un UserControl asociado al menú no hace nada. Si lo hay, elimina el correspondiente a la opción anteriormente seleccionada y crea el nuevo, colocándolo en splitContainer1.Panel2.

Probemos... ok, funciona (por lo menos en mi máquina funciona).

A algunos la solución les parecerá buenísima... ¡manos a la obra! ¡Ya tenemos la estructura de la aplicación, ahora a programar funcionalidad! Hay como 200 funcionalidades que implementar, son 200 controles por crear, así que ¡rápido!

A otros la solución les hará un poco de ruido... "qué incómodo ese switch... por más que tengo los datos del menú en XML, sigo teniendo que agregar la línea que crea el UserControl... no es como crear el nodo a mano en diseño, pero... bueno, empecemos y veremos qué pasa".

Otros con más experiencia verán que ese switch va a convertirse en un problema, y ni hablar de cuando los menúes empiecen a "moverse" por los cambios estéticos y de funcionalidad... ¿quién mantendrá eso ordenado y legible dentro de un par de meses, con 200 o más entradas case, y probablemente con muchas "de basura"?

En realidad, en este momento no es demasiado importante la actitud a tomar. Pero en un par de meses será fundamental. Créanme, ese switch va a ser un problema. Si alguen lo detecta ahora, bien. Si lo corrige, mejor. Pero dentro de un tiempo, si no se corrige va a crecer transformándose en algo muy feo.

En la próxima entrada de la serie veremos una de las soluciones posibles para aislar al front-end de los problemas del crecimiento y los cambios en el menú.

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

domingo, 9 de noviembre de 2008

Test: ¿Qué lenguaje de programación es?

En Name that code se nos presentan algunas líneas de código y tendremos que responder de qué lenguaje de programación se trata.

No me fue mal... 75%. aunque saqué varias por descarte.

Name That Code
Created by OnePlusYou - Free Dating Site

Las personas: el activo de las empresas... no.

Un poco a cuento de las cuestiones laborales sobre las que venía reflexionando, dos perlitas:

1) Yoriento referencia una frase vista en el blog de Escolar, atribuída a "Eusebi Cima, vicepresidente de Fomento del Trabajo (la patronal catalana) y presidente de la patronal Fepime, sobre las ayudas de 1.500 euros para los empresarios que contraten a parados con cargas familares":

"Desgraciadamente, lo que necesitamos son ayudas para despedir a la gente. Hay un ajuste de mercado, una crisis muy grave, se está generando desocupación y no puestos de trabajo. Ahora no es el momento de crear este tipo de ayudas."

2) Un extracto (muy iluminado, a mi entender) del blog de Javier Llinares (no tiene relación directa con el punto 1):

Yo no estoy de acuerdo en que las personas sean el mejor activo que tienen las empresas, ni siquiera estoy de acuerdo en que las personas sean un activo de las empresas, ya que si fuesen algo que poner en el balance, en lugar de en la cuenta de resultados, creo que lo que serían es un renting.

Las personas son un activo para ellas mismas, nunca para las empresas, ya que para que algo sea considerado un activo, tiene que existir cierto nivel de posesión, y naturalmente las personas solo se pertenecen a ellas mismas.

El resaltado es mío. Les recomiendo el artículo completo.

sábado, 8 de noviembre de 2008

Qué significa NINJA en "Crisis NINJA".

Voy a deschavar (con alguna vergüenza) mi desconexión absoluta de la actualidad en estos días (que no de la realidad, que es bien diferente) y de paso hacer un favor a quienes no se atrevían a preguntar.

Acabo de leer en el blog de Javier Llinares Salas, por primera vez, el significado de NINJA, término que ha estado dando muchas vueltas estos meses:

NINJA = No income, no job, no assets, es decir que un ninja es una persona que no tiene ingresos, no tiene trabajo y no tiene propiedades.

Un rayo de luz al interior de mi zócalo...

viernes, 7 de noviembre de 2008

Gestión del tiempo.

No quisiera que esta joyita se perdiera entre los links de "lo que leo":

La teoría de gestión no sirve para los proyectos importantes.

"Las cosas realmente importantes de la vida, ni se pueden elegir, ni se pueden medir".

Jueguitos de viernes: Assembler.

Assembler es un juego de ingenio bastante original, en el que tenemos que arreglárnoslas para colocar unas cajas en los espacios indicados... no es tan fácil como parece...

Un poco corto para mi gusto, deja con ganas.

Máxima seguridad.

Espero que el afán de aumentar la seguridad en mi oficina no llegue a esto...

Visto en The Daily WTF.

jueves, 6 de noviembre de 2008

Codificación: datos de la aplicación como recursos XML embebidos (parte III).

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

III. Encapsulamiento.

Con lo que tenemos hasta aquí ya podríamos armar nuestro menú de ejemplo copiando y pegando el código de prueba que tenemos y modificándolo para recorrer los datos de acuerdo a las necedidades del caso.

Pero hay un tema extremadamente importante que aclarar antes de seguir: cuidado con XML. Podemos definirlo y utilizarlo muy fácilmente, y así de fácil se nos puede ir de las manos. Ya he comentado algunos ejemplos en este blog:

  • XML * Inconciencia.
  • XML (donde comenzaba con la muy acertada frase: "XML is like Violence, if it doesn't solve the problem, use some more").
  • Pobre XML.

XML es una muy buena herramienta para guardar los datos, pero nunca, nunca jamás (créanme) accedan directamente a ellos desde toda la aplicación.

En este sentido son asimilables a una base de datos: no accedemos a ellos creando una conexión y los objetos necesarios para ejecutar un comando SQL en cada módulo, clase o procedimiento en el que los necesitamos. Siempre creamos una capa de datos que puede ser más o menos compleja y con más o menos funcionalidades de acuerdo al caso, pero nunca, nunca accedemos a ellos directamente.

Las razones principales son:

  • Claridad del código.
  • Si cada vez que deseamos obtener información de un menú hacemos

    
    //......
    
                string resourceName = "EjemploRecursosXMLEmbebido.Menu.xml";
                
                XmlDocument menuesXML = new XmlDocument();
                using (Stream s = this.GetType().Assembly.GetManifestResourceStream(resourceName))
                {
                    menuesXML.Load(s);
                }
    
    //.... (etcétera)...
            
    

    Estaremos ensuciando el procedimiento con todo este montón de cuestiones acerca de los recursos, los streams y demás que dificultan la lectura.

  • Mantenimiento.
  • Imaginemos que utilizamos el código anterior en muchas clases de nuestro proyecto. El simple hecho de cambiar el nombre del recurso implicaría buscar la cadena "EjemploRecursosXMLEmbebido.Menu.xml" por todos lados y reemplazarla.

    Es fácil cometer errores al utilizar XPath. Tal vez no todos los programadores del equipo están familiarizados con él. En cada acceso podría cometerse un error diferente.

  • Mejoras, nuevas funcionalidades, reutilización.
  • Veremos que hay mucho para mejorar en la utilización de recursos XML. Las posibilidades son muchas y usualmente iremos aprendiendo sobre la marcha, a medida que surjan las necesidades. Por ello es que necesitamos tener encapsulado el acceso, para poder modificarlo sin que el resto del sistema se vea afectado.

Espero haberlos convencido. Si es así, estarán dispuestos a crear un par de clases que encapsulen el recurso y lo hagan invisible al resto de la aplicación.

Examinemos la estructura de cada nodo que representa un ítem del menú:

<menu id="compras">
  <titulo>Compras</titulo>
  <submenues>
    <!-- lista de elementos menu con la misma estructura-->
  </submenues>
</menu>

Podemos crear una clase (MenuItem) que encapsule ese nodo y exponga los datos que contiene como propiedades:

using System;
using System.Collections.Generic;
using System.Xml;

namespace EjemploRecursosXMLEmbebido
{
    public class MenuItem
    {
        XmlNode _nodo;

        public MenuItem(XmlNode nodo)
        {
            _nodo = nodo;
        }

        public string Id
        {
            get { return _nodo.SelectSingleNode("@id").InnerText; }
        }

        public string Titulo
        {
            get { return _nodo.SelectSingleNode("titulo").InnerText; }
        }

        public IEnumerable<MenuItem> Submenues()
        {
            XmlNodeList submenues = _nodo.SelectNodes("submenues/menu");

            foreach (XmlNode menuNodo in submenues)
                yield return new MenuItem(menuNodo);

        }

    }
}

Y otra clase que nos dé acceso al recurso (Menues):

using System;
using System.Xml;
using System.IO;
using System.Collections.Generic;

namespace EjemploRecursosXMLEmbebido
{
    public static class Menues
    {
        private static XmlDocument _menuDocument;
        private const string _resourceName = "EjemploRecursosXMLEmbebido.Menu.xml";
        
        static Menues()
        {
            _menuDocument = new XmlDocument();
            using (Stream s = typeof(Menues).Assembly.GetManifestResourceStream(_resourceName))
                _menuDocument.Load(s);
        }

        public static MenuItem Raiz
        {
            get { return new MenuItem(_menuDocument.SelectSingleNode("menu")); }
        }

    }
}

Ya estamos listos para otra prueba. Colocamos un nuevo botón sobre el formulario, cuyo código será:

        private void button2_Click(object sender, EventArgs e)
        {
            foreach (MenuItem menuItem in Menues.Raiz.Submenues())
            {
                MessageBox.Show(menuItem.Titulo);
            }
        }

Vemos que ahora, para nuestro front-end de pruebas, el XML simplemente no existe, ni siquiera "sabe" que es un recurso XML. Simplemente solicita a la clase Menues el menú raíz y recorre sus submenúes mostrando el título.

Pero seguimos sin tener un menú como la gente. Paciencia...

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

miércoles, 5 de noviembre de 2008

Humor: Entrevista de trabajo.

Un sujeto está en una entrevista de trabajo.

El psicólogo le dice:

- Le voy a realizar un test final para su admisión.

- Perfecto -dice el candidato.

Entonces el psicólogo le pregunta:

- Usted está en una calle oscura y ve a lo lejos dos faros viniendo en su dirección, ¿usted qué piensa que es?

- Un auto.

- Un auto es muy poco, ¿Qué tipo de auto? ¿Un BMW, un Audi, un Volkswagen?

- ¿Y cómo lo voy a saber?

- Hummm… -dice el psicólogo, que continúa:

- Le voy a hacer otra pregunta: usted está en la misma calle oscura y ve sólo un farol viniendo en su dirección, ¿qué es?

- Una moto.

- Si, pero ¿qué tipo de moto? ¿Una Yamaha, una Honda, una Suzuki?

- Pero si es una calle oscura ¿cómo lo voy a saber (ya medio nervioso)?

- Hummm... Aquí va la última pregunta: en la misma calle oscura usted ve de nuevo un solo farol pero más pequeño y percibe que viene más lento, ¿qué es?

- Una bicicleta.

- Si, pero ¿qué tipo de bicicleta?, ¿una Orbea, una BH?

- ¡¡No sé!!

- Lo siento pero no ha pasado el test.

Entonces el candidato, medio triste con el resultado, dice al psicólogo:

- Aunque no he pasado el test me pareció muy interesante. ¿Puedo hacerle una pregunta, en la misma linea de razonamiento?

- ¡Claro que puede!

- Usted señor, está a la tarde casi noche en una calle mal iluminada. Ahí ve una mujer muy maquillada, con un vestido rojo muy corto, girando su cartera, ¿qué es?

- Ah! Es una puta.

- Si, pero ¿qué puta? ¿Su hermana? ¿Su hija? ¿Su mujer? ¿O la puta que lo parió?

Cuac.

Es realmente irresistible, como dice apuntesgestion, de donde me lo robé.

Reflexiones sobre el trabajo: la metáfora de la autopista y la metáfora del barco.

Soy del tipo de desarrolladores que siempre trabaja en una empresa (nunca digas nunca jamás). Ése es el contexto que me gusta y en el que me siento cómodo: sistemas medianos más que grandes (pero no pequeños), trabajo en equipo, y ciertos temas que me serían una pesada carga ya resueltos: infraestructura, organización, insumos, administración, ventas, contacto con el cliente, esas cosas.

Sin embargo, he aprendido a ser crítico, muy crítico de las relaciones laborales. Entre compañeros de equipo, de trabajo, con dueños, jefes y subordinados, proveedores y clientes, y sus respectivos empleados. Todas. Por supuesto no siempre en voz alta, que tampoco es cuestión de andar metiendo cuchara en todo.

Crítico en el sentido de pensar en las idiosincracias, las falencias, los riesgos y los beneficios de esas relaciones. De poner todo el tiempo personas, situaciones y sentimientos al respecto en la balanza, verificando constantemente si me conviene o no, si quiero o estoy dispuesto a otra cosa, y analizando lo mismo en las personas que me rodean.

Creo haber encontrado una sola y sólo una norma absoluta, cuya aplicación es beneficiosa siempre, incluso cuando estamos en un entorno en el que no se la respeta: autocontrol y transparencia (¡son dos! ufa, una era mejor).

Autocontrol es, simplemente, no explotar, no actuar compulsivamente, no dejar de pensar, de medir, de valuar y evaluar absolutamente todo. Es llevar siempre cortas nuestras propias riendas... los que me conocen saben que por más que lo intento... bueh, uno hace lo que puede. Me ha servido siempre que he podido.

En la segunda me va mejor: transparencia. Si algo molesta, decirlo (vincularlo con la primera: no a cualquiera y de cualquier manera, evaluar), explicitarlo. Si algo deja de molestar, o se hace soportable, también. Dejar en claro cómo nos afectan las acciones de los demás, anunciar lo que vamos a hacer, hacernos previsibles.

Esta segunda puede desecharse si uno no tiene aires de ser una buena persona. Pero si uno tiene una conciencia y no le gusta que le moleste por las noches, es bueno seguirla. Contrariamente a lo que a veces se piensa, no nos pone en desventaja ante nadie.

Me gusta aplicar al trabajo la imagen de la autopista, que alguna vez desarrollé para el equipo de desarrollo: vamos todos por la misma autopista.

Algunos viajamos juntos, algunos queremos llegar al mismo destino, no necesariamente todos. Algunos van en ciclomotor y otros en un Mercedes. En un tramo acotado, todos deberíamos ir hacia la misma dirección.

Lo que es importante, como en la autopista, es no hacer maniobras bruscas o inesperadas. Si hay un choque algunos morirán, otros saldrán heridos y otros ilesos... pero independientemente de las consecuencias a nadie le conviene (como regla general).

Pero cada uno va como quiere y puede. Como en las autopistas, siempre hay un loco dando vueltas o jugando carreras, con mayor o menor suerte para él y para los demás.

Otra imagen o metáfora muy utilizada es la del barco: vamos todos en el mismo barco.

Es decir, somos un equipo, una tripulación. Nuestra suerte está estrechamente relacionada, viajamos con viento en popa, nos golpea la tormenta o nos hundimos todos juntos y por igual.

Cada uno se embarca y aporta sus conocimientos para llegar a destino (si es que lo hay) o navegar indefinidamente.

Es una linda imagen para tener en mente. Muy heroica en tiempos difíciles. Es una imagen que cada dueño o jefe gusta de ver en la cabeza de sus empleados. Es una imagen muy conveniente de tener en la cabeza de quien trabaja para nosotros.

Si todo va bien es una imagen que lo puede llevar a muy buen puerto, o que nos puede llevar a buen puerto. Siempre y cuando la tengan los demás, dándonos ventaja si no la tenemos nosotros.

Como en Matrix, hay situaciones que la rompen y nos devuelven a la realidad. Pero no a la cruda, dura, y horrible realidad. A la realidad, con todos sus blancos, negros y grises.

Esto se aplica en todos los niveles. Si lo vemos desde arriba, es ingenuo contar con que los empleados tienen un compromiso a toda prueba... de hecho lo es contar con que tienen algún compromiso. Ese compromiso hay que obtenerlo y mantenerlo negociando, dando y recibiendo, y el compromiso pasado no garantiza el futuro. De hecho ni siquiera la negociación lo garantiza. Cualquiera de las partes puede levantarse y abandonar la mesa sin previo aviso ni motivos ni explicaciones (una maniobra brusca, un volantazo), y es una situación a la que hay que arriesgarse o estar preparado.

Volviendo a la imagen del barco, es bueno que "hacia abajo" esté lo más difundida posible. Fomentándola (o creyendo en ella) el de arriba se lleva algunas piezas gratis...

...o una sorpresa. Es un certificado de defunción por adelantado apoyar demasiado un emprendimiento en una o varias personas, por más capaces que sean. Salvo que sea uno mismo, o personas con las que uno tiene un fuerte vínculo por fuera de lo laboral o profesional.

Visto desde abajo esa idea de "todos juntos remando para adelante" puede llevar a cumplir los objetivos grupales olvidando (o en contra de) los propios sólo para encontrarse de un día para el otro chapoteando entre las olas pensando en ese salvavidas que tan generosamente (o no, lo mismo da) ofrecimos en trueque (por un par de billetes que ahora flotan a nuestro alrededor, para más detalles).

Dependiendo de lo fuerte de la tormenta, en ese barco todos somos lastre, incluido el barco mismo.

Y sin ser tan drásticos (tal vez me entusiasmé un poco), puede llevar a negociar a menos o a no poner límite a lo negociable.

No es malo pensar: si me gano la lotería y me voy a recorrer el mundo ahora, ya mismo (digo, para desvincular estas preguntas de la idea de conflicto): ¿me iría conforme con lo que yo aporté en relación a lo que me pagaron? ¿si estuviera del otro lado del mostrador, también? La respuesta debería ser "sí", todo el tiempo, siempre. Está en cada uno responder esas preguntas y mantener la balanza nivelada, nadie lo va a hacer por nosotros.

¿Conclusión? Manejen con cuidado, y si alguien les dice de subirse a un barco síganle la corriente, pero tengan cuidado de comenzar a creer que el barco realmente está ahí.

martes, 4 de noviembre de 2008

Religiones del mundo (Religions of the world).

No tiene nada que ve con nada de este blog, es simplemente demasiado gracioso como para no compartirlo. A no ofenderse que hay para todos, incluso para ateos:

Taoism: Shit Happens.
Hare Krishna: Shit Happens Rama Rama Ding Ding.
Hinduism: This Shit Happened Before.
Islam: If Shit Happens, Take A Hostage.
Zen: What Is The Sound Of Shit Happening?
Buddhism: When Shit Happens, Is It Really Shit?
Confucianism: Confucius Say, "Shit Happens."
7th Day Adventist: Shit Happens On Saturdays.
Protestanism: Shit Won't Happen If I Work Harder.
Catholicism: If Shit Happens, I Deserve It.
Jehovah's Witness: Knock, Knock, "Shit Happens."
Unitarian: What Is This Shit?
Mormon: Shit Happens Again & Again & Again.
Judaism: Why Does This Shit Always Happen To Us?
Rastafarianism: Let's Smoke This Shit.
Southern Baptist: Send Us Money And Shit Won't Happen.
CALVINISM: Shit happens because you don't work hard enough.
HEDONISM: There's nothing like a good shit happening.
MOONIES: Would You Like To Buy Some Shit?
STOICISM: This shit is good for me.
ZOROASTRIANISM: Shit only happens half the time.
CHRISTIAN SCIENCE: Shit is in your mind.
Environmentalism: You produce shit, so you have to eat it.
Socialism: Sorry, we are out of shit today.
Feminism: That's not funny!
Atheism: There is no shit.
Atheism: Can you believe this shit?

Lo ví en lol god - About Shit y lo busqué y copié de skepticfiles.

Codificación: datos de la aplicación como recursos XML embebidos (parte II).

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

II. La definción del archivo XML.

Para empezar con algo realmente simple, supongamos la siguiente estructura de menú definida en XML:

<?xml version="1.0" encoding="utf-8" ?>
<menu id="inicio">
  <titulo>Mi ERP 0.0.1</titulo>
  <submenues>
    <menu id="compras">
      <titulo>Compras</titulo>
      <submenues>
        <menu id="compras_presupuestos">
          <titulo>Presupuestos</titulo>
        </menu>
        <menu id="compras_ordenes">
          <titulo>Ordenes</titulo>
        </menu>
        <menu id="compras_seguimiento">
          <titulo>Seguimiento</titulo>
        </menu>
      </submenues>
    </menu>
    <menu id="ventas">
      <titulo>Ventas</titulo>
      <submenues>
        <menu id="ventas_catalogo">
          <titulo>Catálogo</titulo>
        </menu>
        <menu id="ventas_pedidos">
          <titulo>Pedidos</titulo>
        </menu>        
      </submenues>
    </menu>    
  </submenues>
</menu>

Como verán, es una organización recursiva de elementos menu. Cada uno de ellos tiene un atributo id que lo identifica unívocamente, un elemento título que corresponde al texto a mostrar al usuario y un elemento submenues que contiene una lista de elementos menu, cada uno de ellos con las mismas características.

En el ejemplo estamos definiendo la siguiente estructura de menú:

Mi ERP 0.0.1
 Compras
  Presupuestos
  Ordenes
  Seguimiento
 Ventas
  Catálogo
  Pedidos

Es lo mínimo indispensable para sacar algo por pantalla. Así que lo primero que tenemos que hacer es agregar un nuevo archivo xml al proyecto y establecerlo como recurso embebido. Esto último le indica al compilador que debe incrustar el archivo xml en el ensamblado.

Ya estamos listos para escribir la definción (o mejor, copiar y pegar el ejemplo anterior) y hacer una pequeña prueba: colocamos un botón sobre el formulario del proyecto. El código para el botón será:

        private void button1_Click(object sender, EventArgs e)
        {
            string resourceName = "EjemploRecursosXMLEmbebido.Menu.xml";
            
            XmlDocument menuesXML = new XmlDocument();
            using (Stream s = this.GetType().Assembly.GetManifestResourceStream(resourceName))
            {
                menuesXML.Load(s);
            }

            XmlNodeList titulos = menuesXML.SelectNodes("descendant::titulo");
            foreach (XmlNode titulo in titulos)
                MessageBox.Show(titulo.InnerText);

        }

(Nota: hay que agregar los using a los namespaces System.IO y System.Xml para que compile.)

La idea es cargar el archivo en un objeto XmlDocument para poder acceder a los datos por código utilizando XPath, que es el lenguaje de consulta para XML. Como prueba presentamos un MessageBox para cada título de menú en el archivo.

Aquí ya tenemos un par de líneas para resaltar. Por un lado, noten el nombre que se le asigna al recurso embebido: [nombre del ensamblado].[nombre del archivo (con extensión)]. En nuestro caso: "EjemploRecursosXMLEmbebido.Menu.xml".

El archivo se encuentra incrustado como recurso en el ensamblado. Para recuperarlo tenemos que obtener una referencia al ensamblado que lo contiene (clase Assembly) y a través del método GetManifestResourceStream obtener un Stream. Todo es lo hace la instrucción

using (Stream s = this.GetType().Assembly.GetManifestResourceStream(resourceName))

que coloca la referencia al Stream en la variable s.

Luego pasamos esa referencia como parámetro al método Load de un objeto XmlDocument. En nuestro caso, la variable menuesXML contiene al documento, por lo que hacemos:

menuesXML.Load(s);

El resto del código obtiene todos los nodos "titulo" del documento y muestra el texto que contiene.

La magia se termina aquí (no era mucha). Investigando un poco de XPath ya se podría recorrer el documento e ir cargando los datos en, por ejemplo, un TreeView. Lo que haremos de aquí en más será brindarle estructura a la solución de manera de hacerla funcional (todo muy lindo, pero esto no hace nada) y más sólida, mantenible y reutilizable.

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

lunes, 3 de noviembre de 2008

Codificación: datos de la aplicación como recursos XML embebidos (parte I).

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

Hoy tengo ganas de meter las manos en el barro y jugar un poco. Esta es la primera entrega de un artículo en el quiero ejemplificar algunas técnicas de manejo de recursos en C# con Visual Studio que hemos ido perfeccionando en el trabajo y que nos han resultado de muchísima utilidad.

I. Resumen.

Utilizamos recursos cuando se trata de almacenar datos propios de la aplicación que no deben ser modificados durante la ejecución y que conviene tener en un repositorio propio más que hardcodeados por todo el código.

El ejemplo típico, el texto que corresponde a etiquetas y mensajes con la posibilidad de que se requieran varios juegos por idioma, tiene un tratamiento muy específico (ver Recursos en aplicaciones (MSDN)).

Pero aquí pretendo ejemplificar el tratamiento de recursos que a) no dependen del idioma en el que el usuario esté utilizando la aplicación y b) son más complejos que un diccionario de cadenas de texto.

Para desarrollar el código, utilizaré como ejemplo el menú de la aplicación: supongamos que tenemos una aplicación con una estructura de funcionalidades organizada en menúes y submenúes, y que no queremos que ésta sea configurable por el usuario ni que pueda ser modificada de manera alguna luego de la compilación y el pasaje a producción.

Con estas especificaciones podríamos crear un menú directamente sobre el formulario principal del sistema utilizando el diseñador. Sin embargo, esto es muy incómodo cuando la aplicación es grande, y difícil de modificar y mantener a futuro. Por otro lado, estaríamos mezclando conceptualmente la estructura de funcionalidades (propia del negocio) con la forma específica de presentarlo al usuario. Si un día en vez de un menú queremos presentarla en un Treeview, o de cualquier otra manera, estaremos en problemas.

Empezaremos con algo simple y "que funcione" y luego lo iremos refinando.

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

domingo, 2 de noviembre de 2008

Responsabilidades en el desarrollo de software: Del error a la catástrofe.

Este post viene a cuento del intercambio iniciado en Iboisset's Ruminations, en los comentarios de la entrada Responsabilidad de Qué.

La frase que da el puntapié inicial es de diazjc, en Twitter:

En nuestro sector lo que veo es que el informático no sabe el coste real de sus fallos, de sus acciones, su responsabilidad.

Dos artículos me vinieron inmediatamente a la mente. Al primero lo había referenciado en Gestores vs. realidad. Es Cuando los ingenieros se ponen en la piel de los gestores, de Historias de la ciencia. Llegué a él a través de Engañemos a la realidad, artículo de Un Punto Azul Pálido que también viene al caso.

Se comenta el accidente del Challenger. Sin entrar en detalles aquí (el artículo es absolutamente recomendable), resumo lo que viene al caso:

[...]Los ingenieros de Morthon Thiokol volvieron a advertir a sus jefes y a los responsables de la NASA del Centro de Vuelo Espacial Marshall, quienes gestionaban las relaciones con el contratista, que las frías temperaturas de la Florida podían tener un efecto negativo sobre las juntas tóricas.[...]

[...]La presión desde arriba, las dudas sobre los datos y la insistencia en que pensara “como un gestor y no como un ingeniero” fueron suficientes para que Lund cambiara de parecer. Se sumó a los otros gestores de Morthon Thiokol y, pasando por alto la opinión de sus ingenieros, certificó la seguridad de los cohetes aceleradores para el lanzamiento.[...]

[...]Como ingeniero, me vais a permitir unas reflexiones. Estoy seguro que Bob Lund, el ingeniero al que presionaron “para que se pusiera en la piel de un gestor”, se sintió terriblemente responsable por ceder ante la presión. Sin embargo, sospecho que Mason, aquel ejecutivo que le presionó, se lavó las manos de cualquier responsabilidad, ya que él nunca tuvo que estampar su firma para garantizar la seguridad de los cohetes aceleradores y no era responsable de la seguridad de los mismos.[...]

El segundo es uno que referenciaba en La cadena del error. Es un artículo de TCAS Aviation Blog (a cuento de las repercusiones del accidente del avion de Spanair en Barajas) que había aparecido como referencia en Dirección de proyectos:

[...]Que un avión salga en hora es un milagro. ¿O no?

No es tanto un milagro si no un éxito del sistema, que funciona. Pero está claro que no siempre. Normalmente cuando alguno de esos elementos no funciona en el momento que le corresponde o de la manera que toca, se producen incidencias en la operación de mayor o menor calado, y que normalmente afectan tan sólo a la puntualidad o a la economía, nunca a la seguridad.

¿Pero qué pasa cuando son varios elementos los que fallan simultáneamente?

Ahí es donde entra el concepto de la cadena del error. Imaginemos que desde el primer “mal funcionamiento del sistema” hasta el último hay cinco eslabones, y el quinto significa un accidente. Es relativamente fácil que el primero aparezca, puede incluso que el segundo lo haga, es posible que aparezca un tercero, pero alguien, en algún momento (incluso sin llegar a saberlo) debería haber roto alguno de esos eslabones, impidiendo así que llegara el cuarto, y mucho menos el quinto. [...]

Creo que se entiende hacia dónde voy... volvamos al desarrollo de software.

En principio, diferenciemos claramente "error" o "fallo" de "catástrofe" o "desastre". Según la RAE:

  • Fallo: Falta, deficiencia o error.
  • Catástrofe: (1) Suceso infausto que altera gravemente el orden regular de las cosas. (5) Cambio brusco de estado de un sistema dinámico, provocado por una mínima alteración de uno de sus parámetros.

¿Cuál es el coste real de un fallo de un informático? ¿Cuál es su responsabilidad?

Un negocio es un sistema, diseñado por una o varias personas, con el objetivo de ganar dinero. Un sistema de software es uno de tantos subsistemas de un negocio. Puede ser más o menos importante, central o periférico (no es lo mismo la venta de pañales que una red social con publicidad), pero nunca deja de ser parte de ese sistema más grande, el negocio.

Ese subsistema de software es construído por muchas personas (necesariamente) que conforman, junto con otros elementos, un sistema de desarrollo de software. Ahí están "los informáticos". Muchas veces este sistema de desarrollo excede los límites de lo que llamamos "empresa": puede estar compuesto por personas del lado del "cliente" y del lado de "el proveedor del sistema".

El objetivo del subsistema de software está acotado por el del sistema "negocio" al que pertenece. Lo que quiero dejar en claro en este punto es que el objetivo del subsistema "software" no puede ser "ganar dinero", porque ése es el objetivo del sistema "negocio" que lo contiene.

En el lenguaje cotidiano, cuando hablamos de "desastre" o "catástrofe" informática estamos hablando de pérdida de dinero o de cualquier situación que pueda traducirse en tal. Si hay una pérdida de dinero, el sistema que está fallando es el "negocio", porque ganar dinero es su objetivo, y no lo está cumpliendo, o deja de cumplirlo por un período de tiempo determinado, o en vez de ganarlo lo está perdiendo.

Ahora, ¿quién o quiénes son los responsables del negocio? ¿"El informático"?

El origen de una catástrofe (léase: evento que implica pérdida de dinero, fallo del negocio) puede estar en el subsistema de software. Es como decir que el primer eslabón en la cadena del error (que mencionaba arriba, en el artículo sobre el accidente de Spanair) se encuentra en ese subsistema.

No puedo hablar de otros subsistemas (recursos humanos, gerencia, ventas, facturación...), pero si hay algo que conozco bien son las características generales de un subsistema de software.

Una de ellas es: este sistema, tarde o temprano, fallará (probablemente como cualquier otro, pero yo soy experto en éste, y no quiero pisar terreno desconocido).

Si un programador dice que su código no tiene errores miente o peca de soberbia, y se equivoca.

Si un administrador de base de datos manipula la base sin un resguardo, está pecando de soberbia (eventualmente se equivocará). Si lo están obligando o presionando a ello estamos en una situación como la que describíamos arriba, hablando del Challenger.

Lo mismo sucede cuando se administran redes, proyectos de desarrollo, o cualquier elemento informático.

Cuando un líder de proyecto presiona a los programadores para que escriban código sin errores, no hace más que mostrarle al mundo su absoluto desconocimiento del desarrollo.

Cuando un cliente o empresario se apoya únicamente en un sistema informático para hacer funcionar su negocio está pecando de soberbia, ceguera, optimismo, pensamiento mágico, mala administración, falta de previsión... muchas cosas. Pero bueno, es su negocio y es libre de llevarlo como le venga en gana.

Entonces, cuando un cliente o empresario se queja de que el software le ha hecho perder dinero, demuestra que no ha sabido o sido capaz de crear un sistema de negocio tolerante a un fallo en uno de sus subsistemas. Un subsistema con alta probabilidad de fallo, característica harto conocida por todo el mundo.

¿O ha sido engañado por alguien?

Volvamos a la frase:

"[...] no sabe el coste real de sus fallos [...]" : No, no lo sabemos. No lo sabemos porque somos parte de un sistema externo (de desarrollo de software) que crea un subsistema (de software) que es parte del sistema en el cual se puede hablar de "coste" (el negocio)... y a veces ni siquiera eso (si el sistema de software es de depósito, por ejemplo, habría que agregar un nivel más).

A ver, yo escribo una línea de código para un sistema que conozco bien en cuanto a su flujo de información (lo administrativo), pero del cual desconozco completamente sus números monetarios, su aporte al negocio (porque se me ocultan, y en todo caso no me interesan más que como curiosidad). ¿Cómo podría evaluar el coste de un fallo? ¿Si el software falla, puede mantenerse la operatoria "a mano"? ¿Cómo podría saber yo eso?

Sólo saben decir 'ya está arreglado, ya no falla': obviamente. Es lo único que podemos decir. Es la única información de la que, como informáticos, disponemos (cuando la tenemos, que no es siempre).

Ésta es la dura verdad, aunque podemos ser soberbios y pensar que realmente somos responsables por todo lo que ocurre en "el negocio".

Lo demás, es limar asperezas. Podemos asumir responsabilidad sobre un sistema que no controlamos para quedar bien con el cliente. Puedo no decirle al jefe del equipo que el problema no está aquí para quedar bien o para no enojarlo. Puedo no decir "¿dónde están los procedimientos alternativos?", arremangarme y corregir las cosas lo más rápidamente posible. Podemos tener conciencia de equipo y ayudar en todo lo posible.

Si éstas son las actitudes que el autor de la frase siente en falta, puede ser. La vida es más fácil cuando están presentes. Pero hay veces en las que es difícil ser comprensivo y ponerse la camiseta cuando un cliente, líder de proyecto o jefe de lo que sea descarga su ira hablándonos de números sin sentido, pidiendo explicaciones que no quiere escuchar, y exigiendo que hagamos lo imposible: no generar errores.

(Las imágenes en caricatura de este post fueron encontradas en El ciclo de la vida, en "El rincón de Basulto".)