¿Diseño decente?

Hacer un buen diseño no es trivial, más aún: tampoco es trivial decir si un diseño es bueno. ¿Qué es un buen diseño? Alguien podría decir que un buen diseño es un diseño «escalable», pero que pasa si la escalabilidad no es uno de lo requisitos del problema. Creo que muchas veces se persiguen propiedades sin considerar las necesidades. En este sentido creo que una primera propiedad de un buen diseño es que resuelva el problema en cuestión.En línea con esto podríamos decir que un «mal diseño» es uno que no resuelve el problema en cuestión.

Mmmm, esto tampoco cierra. «Diseño bueno» o «diseño malo», no creo que sea una cuestión tan binaria: «bueno o malo». Pero si creo que la evaluación del diseño debe ser en función del problema que queremos resolver. Intento resaltar esto con un ejemplo concreto: puedo hacer un diseño super purista, que cumple con N propiedades, pero luego resulta no factible de ser implementado :-(. Entonces un diseño que no se implementa ya perdió. Nota al margen: creo que esto refleja la diferencia entre «la ciencia teórica» y la ingeniería.

Típicamente los problemas que tenemos que resolver tienen múltiples dimensiones representadas por: a) funcionalidades, el qué, lo que software debe hacer y 2) propiedades, atributos de calidad, el cómo, que influyen en el cómo resolvemos el problema, o sea: lo revolvemos de una forma que resulta mantenible, extensible, performante, etc, etc. A partir de esto creo que no es conveniente una evaluación «binaria» (bueno/malo), sino es que es mejor hablar en un continuo, una gama de grises entre el bueno y el malo.

Es en este grupo de propiedades que definen la solución hay una que destaca por ser de presencia «universal», o sea, que en general es requerida en toda solución: la mantenibilidad. Raro son los casos en los que resolvemos una problema de una y nunca más tenemos que tocar su código. En general nos aproximamos a la solución en forma iterativa y eso no lleva a volver una y otra vez sobre el código previamente escrito. Es ahí donde la mantenibilidad tiene un impacto decisivo en el costo (y los riesgos) de trabajar sobre código previamente escrito. Desde mi perspectiva la mantenibilidad implica: que el código sea legible, fácil de entender, que sea testeable (y que tenga pruebas), que revele su intención, que esté documentado, etc, etc.

Aquí es donde entra mi idea de «diseño decente», es un diseño que puede tener algunos puntos flojos pero que resuelve la dimensión funcional del problema y respeta ciertas premisas de mantenibilidad y testeabilidad de forma tal que nos lleva a generar una implementación que concretamente:

  1. Respeta las convenciones del lenguaje de programación (fácilmente verificable con un linter)
  2. Mantiene una clara separación entre el código de la lógica «de negocio» y el código de entrada/salida (infraestructura)
  3. Tiene pruebas automatizadas

Traigo esta idea de «diseño decente» porque es justamente lo que intento enseñar a mis alumnos.

Y un día un alumno uso ChatGPT y desaprobó

Ya desde el año pasado empecé a encontrarme con alumnos usando ChatGPT para resolver ciertas cuestiones de las materias que curso. Las situaciones que he visto son diversas.

En algunos casos alumnos ha usado chatGPT para resolver problemas técnicos (hacer troubleshooting), en algunos otros para resolver cuestiones de algoritmia y en otros para contestar preguntas teóricas. Asimismo en algunos casos los propios alumnos lo han dicho mientras que en otros casos lo descubrió algún miembro del equipo docente. En todos estos casos no tuvimos inconvenientes.

Pero esta semana nos encontramos con una nueva situación. Dimos a los alumnos un cuestionario online sobre un tema que veníamos trabajando desde hace varias semanas. Los alumnos tuvieron material de lectura, videos, actividades en clase y también oportunidades de aplicación en un TP. Luego de todo esto les dimos el cuestionario que tenia preguntas de tipo selección múltiple y también preguntas a desarrollar. Fue precisamente en estas preguntas de desarrollo donde encontramos respuestas distintas a lo esperado. Hablando con el grupo docente sobre esta situación, un docente descubrió que la respuesta había sido generada por ChatGPT. El alumno resultó desaprobado, pero no por haber usado ChatGPT sino por haber dado una respuesta incorrecta.

Esto me llevó a reflexionar de cara a aclarar algunas ideas pues el uso de herramientas de Inteligencia Artificial será cada vez más común y me parece importante sentar posición y dar visibilidad a los alumnos. Sinceramente no veo problema en que los alumnos usen ChatGTP (o herramientas por el estilo) ya sea para mejorar la redacción, resolver problemas técnicos o incluso contestar preguntas teóricas. La cuestión será, como casi siempre, ser criterioso. No tomar como infalibles las respuestas obtenidas, analizarlas críticamente y verificar su corrección. Adicionalmente la «calidad» de las respuesta obtenidas dependerá en gran medida de que las preguntas sean las apropiadas, con lo cual quienes quieran utilizar estas herramientas tendrán que aprender a utilizarlas con cierta «destreza».

Cambios en el perfil de alumnos de MeMo2 @ FIUBA

En MeMo2@fiuba comenzamos la primera clase con 24 alumnos, al poco tiempo solo teníamos 22 y en este momento tenemos 21. Una curiosidad de este cuatrimestre es que nos ha cambiado de forma sensible el perfil de los alumnos:

  • Tradicionalmente la mayoría de los alumnos que llegaba a la materia tenia un promedio de edad de 25 años pero este cuatrimestre el promedio de edad es 23 años.
  • Al mismo tiempo vemos un cambio en la condición laboral de los alumnos, históricamente la mitad de los alumnos llegaba con alguna experiencia laboral en sistemas (en 2019 el 70% de los alumnos ya estaba trabajando en la actividad, mientras que en 2021 ese número fue de 76%). Este cuatrimestre el 83% de los alumnos no tiene experiencia laboral en sistemas.

Estas dos cuestiones impactan diversos aspectos del curso: los alumnos al ser más jóvenes tienen menos «maduración» de la vida universitaria lo cual a su vez impacta en sus hábitos de organización y estudio. Al mismo tiempo al tener menos experiencia laboral, se encuentran menos «duchos» en cuestiones de programación y sobre todo en cuestiones de troubleshooting. Estas cuestiones las confirmamos en las métricas del curso: por un lado vemos que la resolución de los ejercicios de programación les lleva más de lo habitual (saben concretamente cuanto les lleva pues les pedimos que lo reporten al completar las tareas) y al mismo tiempo vemos que el desempeño es inferior (lo cual se refleja en las calificaciones). Para equipo docente esto impacta en que aumenta la cantidad de alumnos que se inscriben en curso y al mismo tiempo aumenta el esfuerzo que los docentes deben dedicar, no solo porque hay más alumnos sino porque esos alumnos requieren más atención/asistencia/seguimiento.

Este cambio en el perfil de alumnos creemos que se debe principalmente a dos cuestiones:

  • Por un lado, el horario de cursada: el año pasado cambiamos el horario del curso, veníamos dictando el curso durante la tarde/noche (de 19 a 22) y pasamos a la mañana (de 8 a 11)
  • Por otro lado, el cambio de plan de estudio: en el nuevo plan de ingeniería informática la materia se mantiene en el octavo cuatrimestre pero requiere de una combinación distinta de correlatividades que a mi parecer es más flexible.

La cuestión es que el perfil de alumnos cambió y eso nos está llevando a hacer algunos ajustes en la dinámica del curso.

PD: he estado ausente de este espacio por tiempo record. Pasé de publicar 1 o 2 artículos por semanas a no publicar nada durante 6 semanas. Resulta que comenzó el cuatrimestre y las dos materias que tengo a mi cargo sumadas a un cliente de mi actividad privada, redujeron mucho mi tiempo disponible para escribir. En fin, I ‘am back.

Experimento: conventional reviews

Desde hace ya bastante tiempo comencé a utilizar conventional commits en mis proyectos y también en mis clases. El año pasadomientras corregía una entrega de los alumnos se me ocurrió utilizar una estrategia similar para las observaciones en las revisiones de código.

A mi parecer las observaciones más comunes que veo en el código de los estudiantes se pueden agrupar en las siguientes categorías:

  • Naming (n): nombres inapropiados, poco representativos, confusos, etc
  • Programación (p): métodos muy largos, números mágicos, indentación no uniforme, etc
  • Encapsulamiento (e): elementos públicos que deberían ser privados, acceso a miembros de otros objetos, etc.
  • Modelado (m): conceptos del dominio del problema representados en el código de forma inapropiada
  • Separación de incumbencias (s): clases con varias responsabilidades, poco cohesivas, mezcla de incumbencias de dominio con incumbencias accidentales, etc

Entonces a partir de esto, es que cada comentario que hago en la revisión le agrego el prefijo correspondiente.

La idea de este experimento es poder extraer información sobre las observaciones más habituales en el código de los alumnos para luego poder accionar al respecto.

Perspectivas del inicio de clases 2024 @ fiuba

Tal vez el lector esté esperando algún comentario sobre la situación crítica que afronta la UBA (y la educación pública en general en Argentina), lamento decepcionarlo. No es que la situación me sea ajena o no despierte mi interés, pero por el momento intento mantener una de las premisas de este espacio: nada de política, fútbol o religión. No estoy seguro de cuánto mantendré esta idea, porque sinceramente la situación es preocupante y es definitivamente un tema de política y visión de país. En fin, vamos a la cuestión académica que es lo que quiero compartir.

Según indica el sistema de inscripción parece que este cuatrimestre tendremos record de alumnos tanto en la materia de grado (memo2@fiuba) como en postgrado (entrega_continua@untref).

En FIUBA tenemos 36 inscriptos, record histórico, el máximo anterior había sido 32. Esta cantidad de alumnos representa nuestro primer desafío para este 2024: mantener la calidad del cursos con más del doble de alumnos que los que veníamos teniendo (el cuatrimestre pasado tuvimos 13 alumnos).

A esto se suma un segundo desafío: alumnos del nuevo plan de estudio de Ingeniería Informática que vienen con una formación distinta por haber cursado materias distintas. Por lo que estuve relevando, son alumnos que vieron más cuestiones de diseño/programación y menos de proceso de desarrollo (usuarios, requisitos, scm/ci, ambientes, etc).

El primer impacto de esta situación está en la carga de trabajo del equipo docente, por suerte contamos con varios colaboradores (ex-alumnos de la materia) que serán un factor clave en el manejo de la carga de trabajo. Es por eso que a pesar de estos dos desafíos, estamos planificando el cuatrimestre igual que el cuatrimestre anterior, que consideramos nos dio muy buenos resultados. Eventualmente ajustaremos sobre la marcha si lo vemos necesario.

Ortografía del código

En la actualidad (y desde hace buen tiempo), varios entornos de desarrollo y editores de código tienen la capacidad de detectar «errores» ortográficos de forma similar a lo que hacen los procesadores de texto como Microsoft Word y Google Docs que subrayan las palabras que desconocen.

En general esta funcionalidad de «corrección ortográfica» viene configurada para inglés. Si codeamos en inglés (cosa que muchos programadores hacen) no hay problema. Pero si aplicamos Domain-Driven Design y nuestro usuario/cliente habla castellano, entonces seguramente codeemos en castellano y ahí el IDE/editor comenzará a que llamarnos la atención. Aquí tenemos básicamente dos opciones: desactivar la verificación de ortografía o configurarla correctamente. Para esto último, independientemente de cómo sea esa configuración seguramente vamos a necesitar descargar un diccionario.

En el video que comparto a continuación explico como configurar RubyMine, el IDE de JetBrains para Ruby, pero la configuración es práctica igual para otros IDEs de JetBrains.

Bonus: para el caso de Visual Studio Code, podemos instalar la extensión Spanish – Code Spell Checker, en otro momento lo explicaré con más detalle.

Automatización de pruebas: the wrong way

Si, lo sé, el título es un poco marketinero y bastante incorrecto como suele pasar con afirmaciones tan extremas.

La cuestión es que hoy en día muchas organizaciones/equipos con la intención de abrazar los beneficios de Agile/DevOps descubren que es necesario tener pruebas automatizadas. Hasta ahí vamos bien.

La cuestión se empieza a torcer cuando para automatizar la pruebas ponen gente exclusivamente para hacer eso mientras que los desarrolladores siguen trabajando sin alteración alguna en su dinámica. ¡ooops! No es por ahí.

Es cierto que es necesario tener pruebas automatizadas y que en general sin importar cómo se hagan, es mejor que nada. Pero la teoría y la evidencia indican que en un contexto Agile/DevOps la automatización de pruebas requiere del involucramiento activo de los desarrolladores. Los desarrolladores deben hacer su parte automatizando las pruebas unitarias y luego trabajando de forma cercana con usuarios y testers en las pruebas de aceptación. Podrá después haber algún trabajo adicional de automatización de pruebas para generar un set de regresión, pero si lo desarrolladores hacen lo que acabo de mencionar, entonces este esfuerzo adicional agrega poco valor.

Claro que esto no es trivial, nunca dije que lo fuera. Se requiere de algunas habilidades (duras y blandas) adicionales respecto del enfoque tradicional de desarrollo y testing. Para poder escribir pruebas unitarias necesitamos saber hacerlo pero más allá de eso necesitamos que la arquitectura/código de nuestra aplicación nos lo permitan. También se requieren de algunas habilidades de comunicación/colaboración para que desarrolladores y testers trabajen más cerca y de forma temprana.

Algunas de estas cuestiones las menciono en esta entrevista del año pasado y también la trato con cierta profundidad en mi Taller de Prácticas Técnicas.

Curso online de Extreme Programming

En enero comencé con un experimento, desarrollar una aplicación real (para un cliente mio) en sesiones online, abiertas y de 15 minutos. Como de costumbre, el desarrollo lo hice aplicando prácticas de Extreme Programming como ser Specification by Example, Test-Driven Development, Continuous Integration, Entrega Incremental, Story Slicing, etc., y utilizando algunas técnicas de diseño/programación como ser arquitectura hexagonal, mocks, etc.

Fueron en total 20 sesiones (unas 5 horas) en las que completé 2 mini-releases de la aplicación en cuestión. Luego, edité los videos de las sesiones, los complementé con algunos videos más y con ello le di forma un video-curso en la plataforma Udemy. La versión actual del curso tiene más de 7 horas de video y durante marzo repetiré la experiencia para agregar más funcionalidades y con ello sumar al menos otras 10 horas de video.

Los interesados en el curso lo pueden en la plataforma Udemy (aquí).

Nuevo Proyecto con AI

Hace un par de semanas comencé a trabajar en nuevo proyecto. Se trata de un equipo que trabaja en Inteligencia Artificial, más precisamente en cuestiones de procesamiento de leguaje natural (AI/NLP).

Para ser más preciso debo decir que comencé a trabajar con este equipo el año pasado pero en un rol distinto. El aquel momento colaboré con algunas cuestiones técnicas de diseño, testeabilidad, etc., de una API que el equipo utiliza para exponer sus servicios de AI. Ahora estoy en un rol distinto, estoy metido completamente en el equipo en un rol que yo denominaría como «XP Coach». La idea es ayudar al equipo a trabajar de forma ordenada con un proceso de delivery predecible y mejorable.

Entre los desafíos que veo podría mencionar que el equipo trabaja en forma remota todo el tiempo, en parte porque los miembros del equipo están distribuidos en 2 países. Esta distribución geográfica está condimentada por una diferencia de zona horaria entre los países de 2 horas. Otro desafío es mi rudimentario conocimiento de temas de AI/NLP, pero esta cuestión me parece un tema menor en el sentido que para el trabajo que a mi me toca no es necesario ser un especialista en cuestiones de este dominio. Pero creo que definitivamente el mayor desafío pasa por la naturaleza de los entregables del equipo. O sea, básicamente el principal artefacto del equipo es un modelo de AI/NPL expuesto vía una API para que otros equipos de lo organización lo consuman y lo integren en aplicaciones «consumibles por los «usuarios humanos». La cuestión es que el trabajo tiene mucho de experimentación lo cual implica ciertas particularidades a la hora de organizar el trabajo dentro de un contexto típico de agile/scrum/xp. Si bien tenemos algunas tareas que pueden representarse como simples User Stories, muchas otras no calzan naturalmente como User Stories. Por ejemplo: no siempre son estimables y no siempre es posible establecer criterios de aceptación. Un caso concreto: hay que mejorar un modelo, de entrada no sabemos cuánto podremos mejorarlo ni cuánto nos llevará hacerlo; al mismo tiempo es posible que si invertimos más tiempo podamos mejorarlo más, pero no es seguro. Respuestas a esta situación y varias otras serán parte de futuros posts.

Herramientas de gestión de backlog: estas NO

No voy decir qué herramienta no utilizar. En lugar de ello voy a contar cómo me gusta trabajar y cuales son incomodidades/limitaciones que me he encontrado con ciertas herramientas pero sin dar nombres.

Parte de la motivación de escribir este artículo tiene que ver con que en más de una vez veo equipos trabajando de una determinada forma que ni a ellos mismos les convence y ante la pregunta de porqué lo hacen me dicen cosas tales como «Es que la herramienta lo maneja así» o «Nos gustaría hacerlo de otra forma pero nuestra herramienta no lo soporta«. Estas situaciones caen dentro de lo que yo suelo denominar «Poner el caballo delante del carro». En fin, voy con mi lista.

Identificación de ítems: me gusta poder referirme a los ítems del backlog de forma rápida con un número, onda: «el ítem 14», «el ítem 182». Resulta muy práctico y directo sin ambigüedades. Hay herramientas que en lugar identificador los ítems con secuencias numéricas por proyecto, utilizan identificadores largos tipo GUID o tienen una secuencia global para todos los proyectos entonces estos IDs tienden a ser números muy largos como «1234599934» y resulta incómodo utilizarlos para identificar los ítems en una charla.

Ítems linkeables: me gusta poder compartir links directos a cada ítem, es algo que parece trivial pero he visto herramientas que no lo soportan, solo es posible compartir un link al backlog y luego uno manualmente debe posicionarse en el ítem en cuestión.

Libertad en los tipos de items: en general tiendo a no hacer distinción en los tipos de ítems, por eso me resulta indiferente si la herramienta soporta o no distintos tipos de ítems (story, tasks, etc). Pero hay herramientas que fuerzan a que todo ítem sea de algún tipo (hasta ahí, ok) y junto con ello «le imponen ciertas reglas» (por ejemplo: cierto tipo de ítem no se puede estimar) mmm, esto ya es demasiado.

Prioridad y costo: todo ítem de backlog tiene una prioridad para el negocio y un costo (estimado) asociado de construcción, entonces espero que la herramienta provea soporte explícito para estos dos datos. No todas las herramientas lo hacen. El hecho de poder tener estas propiedades individualizadas permite a posteriori hacer ciertas operaciones de reporte 7 análisis.

Iteraciones: generalmente me inclino por un esquema de entrega continua pero igualmente me gusta trabajar en iteraciones para así poder establecer una cadencia de reflexión y planificación. Hay herramientas que no soportan iteraciones.

Reporting: al cabo de un par de iteraciones me gusta poder sacar algunas métricas y proyecciones de la evolución del proyecto. Hay herramientas que vienen con un nutrido set de reportes, otras tienen algún reporte pero permiten exportar la información. Pero hay otras que nada de eso.

Para cerrar, soy consciente que aún cuando la herramienta no soporte cierta funcionalidad, es posible que podamos, como decimos en Argentina, «atarlo con alambre», buscarle la vuelta, onda: si la herramienta no tiene soporte para indicar la estimación entonces la podemos cargar en la descripción. Mmmm, demasiado rudimentario para mi gusto.

En fin, el mercado está plagado de herramientas para gestionar el backlog, cada uno que use lo que guste pero procuren no poner el carro delante del caballo.