Sobre la definición del Trabajo final de carrera

En las últimas semanas he recibido varias consultas sobre trabajos finales de carrera en FIUBA. Más allá de siempre recomendar dejar en claro el objetivo personal del trabajo, en estas ocasiones me encontré recurrentemente explicando una cuestión sobre la definición del trabajo y la presentación del proyecto. Lo escribo aquí para futuras referencias.

El primer paso formal del trabajo final de carrera es la presentación del plan de proyecto a la comisión curricular para su aprobación. Este un paso clave, y que a mi entender, en ocasiones subestimado. Si nos quedamos cortos en el nivel de detalle del plan de proyecto, corremos el riesgos que la comisión curricular no apruebe el proyecto. Al mismo tiempo si ponemos mucho nivel detalle sin tener suficiente conocimiento del dominio, la tecnología y el contexto, corremos el riesgos de estar embarcándonos en un trabajo mucho más extenso de lo esperado.

Entonces he aquí la clave: la formulación del plan de proyecto debe proveer el suficiente nivel detalle para que la comisión lo apruebe, pero para proveer ese nivel de detalle es necesario que tengamos suficiente conocimiento del dominio del proyecto, la tecnología que utilizaremos para la solución y el contexto del proyecto. Esta situación tiene distinto grado de “gravedad” en cada carrera/institución. En algunos casos no se pide tanto nivel de detalle en el plan de proyecto porque se espera que el proyecto incluya el esfuerzo de descubrimiento/análisis/requerimientos. Del mismo modo, en los casos en los que se pide mayor nivel de detalle se está, en cierto modo, forzando que al menos una parte importante del descubrimiento/análisis se realice previo/durante a la formulación del proyecto.

Si quisiéramos poner esto en términos formales (o de industria) podríamos pensar estas dos situaciones: en un extremo en una planificación adaptativa y en el otro en una planificación “up-front”. Al mismo tiempo si analizamos los trabajos finales desde una perspectiva de gestión de proyectos tenemos que generalmente los reglamentos establecen de forma fija los recursos/esfuerzo/presupuesto del proyecto (cada alumno debe trabajar X cantidad de horas como mínimo). También se establece un tiempo calendario máximo para completar el proyecto una vez aprobada la propuesta (por ejemplo 1 año calendario). De esta forma la dimensión variable del proyecto termina siendo el alcance y ahí la paradoja: en un planificación “up-front” muchas veces los alumnos (y también las empresas) intentan fijar un alcance, teniendo así las tres dimensiones del proyecto fijas de entrada: alcance, tiempo y recursos. Típico proyecto “llave en mano” con las ¿pocas? chances de que el proyecto llegue a buen puerto. Es así que nos encontramos con alumnos haciendo interminables trabajos finales y algunos otros que nunca siquiera lo empiezan.

La clave entonces podría estar en plantear un alcance variable, lo cual a mi parecer va mucho mejor con una planificación adaptativa que con una planificación “up-front”.

En términos formales, y dependiendo de las particularidades de la comisión curricular (o el organismo que sea que deba aprobar el plan de proyecto), puede que la mayor parte descubrimiento/análisis debamos hacerla antes o después de la aprobación del plan de proyecto. En base a lo que he hablado informalmente con miembros de las comisiones curriculares de FIUBA me queda la sensación de que en el caso de la Ingeniería el descubrimiento/análisis hay que hacerlo en su mayor parte antes de la presentación del plan de proyecto. En el caso de la Licenciatura el descubrimiento/análisis es en su mayor parte realizado una vez aprobado el plan de proyecto.

En este sentido, mi recomendación para los alumnos de Ingeniería en Informática es:

  • Conseguir un director y comenzar a trabajar
  • Presentar la propuesta formal una vez avanzando un porcentaje de ~30% del proyecto
  • Obviamente esta estrategia tiene el riesgo de avanzar en el trabajo y que luego la comisión no apruebe el plan de proyecto. Justamente es aquí donde resulta clave el rol del director para minimizar la chances de que el proyecto sea rechazado.

Continuous Delivery: Scripting para balanceador F5

F5 es una empresa que provee un conjunto de productos relacionados a networking: firewall, balanceador, etc. Es común encontrarse con balanceador F5 en ambientes productivos de alta carga para repartir carga entre varios nodos.

Al mismo tiempo, en aplicaciones de cierta criticidad, es común que las actualizaciones se hagan siguiendo alguna estrategia tipo “canary”, esto es:

  • “Se saca” un nodo del balanceador
  • Se le instala la nueva versión de la aplicación
  • Se verifica que la aplicación funcione correctamente
  • “Se restaura” el nodo en el balanceador
  • Se repite el proceso con cada uno de los restantes nodos

Cuando pretendemos trabajar en un esquema de continuous delivery es imprescindible que este proceso se haga de forma automatizada y para ello es necesario poder interactuar con balanceador programáticamente.

Dicho esto, he aquí un fragmento de código Python para interactuar un F5 Big-IP:

# este script depende de varias variables:
# * f5_login_url (url del balanceador para obtener el token)
# * f5_user (usuario de f5 para obtener el api token)
# * f5_pass (password de f5 para obtener el api token)
# * f5_self_service_url (url de la api del balanceador)
# * node_name (nombre del nodo sobre el que queremos operar)
# * node_id (id del nodo sobre el que queremos operar)
# * pool_id (id del pool del balanceador en el que está el nodo)


import requests
import json
import sys

# primero hay que loguearse y obtener un token
login_request = '{ "username":' + f5_user + ', "password":' + f5_pass }'
response = requests.post(f5_login_url, login_request)
if response.status_code == 200:
  response_json = json.loads(response.text)
  token = response_json["token"]["token"]
else:
  token = {}
  print('No pudo obtener token', file=sys.stderr)
  exit(1)

# sacamos el nodo
headers = { 'X-F5-Auth-Token': token }
disable_request = '{"name":"Self-Service_' + node_name + '", "resourceReference":{' \
  + '"link":"https://localhost/mgmt/cm/adc-core/working-config/ltm/pool/' + pool_id \
  + '/members/' + node_id + '"},"operation":"force-offline"}'
response = requests.post(f5_self_service_url, data=disable_request, headers=headers)

# restauramos el nodo
enable_request = '{"name":"Self-Service_' + node_name + '", "resourceReference":{' \
  + '"link":"https://localhost/mgmt/cm/adc-core/working-config/ltm/pool/' + pool_id \
  + '/members/' + node_id + '"},"operation":"enable"}'
response = requests.post(f5_self_service_url, data=disable_request, headers=headers)

Espero les resulte útil.

Situaciones de Diseño #1

Hace tiempo venia con la idea de publicar una serie de videos sobre diversas técnicas/patrones/recomendaciones para lidiar con situaciones de diseño habituales. Finalmente ayer decidí poner manos a la obra y publiqué el primer video de esta serie.

La situación que aborda este primer video es cómo lidiar con lógica que depende de fechas de una forma testeable. Muchas veces cuando tenemos lógica que depende de la fecha actual, estamos tentados de utilizar directamente una llamada al componente nativo de fecha. El problema con este camino es que no resulta testeable. La clave está en encapsular el acceso a la fecha del sistema de manera tal de poner utilizar un doble de prueba (mock) en el momento de hacer nuestra pruebas automatizadas.

Les dejo aquí el video y los invito a que me dejen en los comentarios alguna otra situación que les gustaría que aborde en próximos videos.

RubyMine con Docker

En la actualidad es cada vez más habitual utilizar Docker como ambiente de desarrollo, o sea: en lugar de instalar el runtime de desarrollo en nuestro host, armamos una imagen Docker con el runtime del proyecto conteniendo también todas dependencias/libs y en nuestro host instalamos tanto solo Docker Desktop y el IDE de nuestra elección.

Esta estrategia resulta especialmente útil en stacks como Ruby donde es habitual tener que utilizar distintas versiones Ruby. Sin embargo cuando pretendemos utilizar IDEs más potentes como RubyMine, que proveen algunas funcionalidades que dependen del runtime (como es el caso de algunos refactorings), es necesario hacer algunos ajustes de configuración en el IDE. Es por ello que grabe un video explicando estos ajustes. Espero les resulte útil.

No más Agile para mi

Luego de estar metido en el “mundo agile” por varios años y de ver muchos equipos y organizaciones trabajar (o intentar hacerlo) de forma agile, en 2016 decidí abordar el tema de manera formal. Me uní a un equipo de investigación en la Universidad Nacional de Tres de Febrero.

Inicialmente nos enfocamos en entender qué era eso que los equipos llamaban agile y lo contrastamos con la teoría. Hicimos varios estudios que fuimos publicando en conferencias de distinta índole y relevancia. El más relevante de ellos fue nuestro artículo “Technical and Organizational Agile Practices: A Latin-American Survey” que presentamos en la “International Conference on Agile Software Development 2018” (mejor conocida como XP).

Luego, a partir de nuestros hallazgos, cambiamos el foco de nuestra invitación y nos concentramos en estudiar la enseñanza de Agile intentando encontrar respuesta al algunos de los interrogantes que habían surgido de nuestros propios hallazgos. De este estudio también surgieron varias publicaciones de las cuales la última y más importante fue mi trabajo de especialización en UNLP “Enseñanza de métodos ágiles de desarrollo de software en Argentina, Estado del arte“.

Finalmente, el año pasado trabajamos en dos artículos más, ambos relacionados a la iniciativa HELENA (Hybrid dEveLopmENt Approaches in software systems development) que esté año fueron finalmente publicados: “What Makes Agile Software Development Agile” (aceptado para publicación en el journal IEEE Transactions on Software Engineering) y “On the Influence of Agile in the Usage of Software Development Practices” (publicado en el congreso Argentino de IEEE). Con estas publicaciones cierro un ciclo en mi camino de investigación, hasta aquí estudie agile. Confirmé formalmente algunas creencias, descubrí algunas cuestiones que no imaginaba y sobre todo analicé y reflexioné. Más allá de la publicaciones creo que el camino recorrido fue muy enriquecedor.

Algunos puntos destacados de los descubrimientos que hemos hecho en este camino:

  • La industria ha adoptado en mucho mayor grado las prácticas Agile relacionadas a organización del trabajo (como retrospectivas) que las prácticas agile de índole técnica (como integración continua)
  • En parte como consecuencia de lo anterior existe un gap relevante entre lo que se supone que es Agile a nivel conceptual y lo que se ve en la industria
  • En términos académicos Agile es enseñado en prácticamente todas las carreras de grado en informática en las universidades públicas argentinas, pero con niveles de profundidad muy variado. También aquí se ve un gap relevante entre las prácticas de organización y las prácticas técnicas.
  • Dado el alto grado de variabilidad entre lo que Agile significa conceptualmente y lo que industria llama Agile, y por otro lado el grado de variabilidad de Agile dentro de la propia industria, no tiene ningún valor para mi que una organización/equipo diga que trabaja “Agile” o que es “Agile” porque simple no queda claro que significa eso.

Al margen de todo esto, no voy a seguir investigando sobre Agile, en parte porque creo que a nivel industria el significado de Agile está muy desdibujado y en muchos casos muy distante del espíritu con el cual fue concebido.

De ahora en más mi foco de trabajo será el estudio de prácticas concretas de desarrollo de software, que al fin y al cabo es la forma que toman los mindsets en el día a día de los equipos. En este sentido me interesa particularmente el estudio del desarrollo guiado por pruebas. En futuros post compartiré más detalles sobre este tema.

A continuación comparto la lista de artículos que hemos publicado a lo largo de estos años.

Paez, N., Fontdevila, D., & Oliveros, A. (2016, Nov). Characterizing Technical and Organizational Practices in the Agile Community. IV Congreso Nacional de Ingeniería en Informática/Sistemas de Información. Salta, Argentina.

Paez, N., Fontdevila, D., Gainey, F., & Oliveros, A. (2017, Nov). An empirical study on the usage of technical and organizational practices in the Agile Community. V Congreso Nacional de Ingeniería en Informática/Sistemas de Información. Santa Fe, Argentina.

Paez, N., Fontdevila, D., & Oliveros, A. (2017, November). HELENA study: initial observations of software development practices in Argentina. In International Conference on Product-Focused Software Process Improvement (pp. 443-449). Springer, Cham.

Paez, N., Fontdevila, D., Gainey, F., & Oliveros, A. (2018, May). Technical and Organizational Agile Practices: A Latin-American Survey. International Conference on Agile Software Development (pp. 146-159). Springer, Cham.

Paez, N., Oliveros, A., & Fontdevila, D. (2019, September). Initial Assessment of Agile Development in the Undergraduate Curricula. Brazilian Workshop on Agile Methods (pp. 76-84). Springer, Cham.

Paez, N., Oliveros, A., Fontdevila, D., & Zangara, M. A. (2019, Oct). Introducing Agile Methods in Undergraduate Curricula, a Systematic Mapping Study. XXV Congreso Argentino de Ciencias de la Computación (CACIC)(Universidad Nacional de Río Cuarto, Córdoba

Paez, N. (2020, April). Enseñanza de Métodos ágiles de Desarrollo de Software en Argentina. Estado del Arte. Research work for Specialization Degree in Information Technology Applied to  Education, Universidad Nacional de La Plata.

Paez, N., Fontdevila, D., & Oliveros, A. (2020, Dec) On the Influence of Agile in the Usage of Software Development Practices. IEEE Congreso Bienal de Argentina 2020 (ARGENCON)

Kuhrmann M. et. all (2021, July) What Makes Agile Software Development Agile. IEEE Transactions on Software Engineering

Pueden encontrar más detalles sobre estos artículos en Research Gate.



Ingeniería de Software para videojuegos (rpg)

El mundo de los videojuegos es muy amplio, tanto desde el punto de vista del usuario como también de los desafíos técnicos de su construcción. Personalmente no estoy metido en ninguno de estos dos aspectos. Apenas si desarrollé algunos juegos muy simples del tipo juego de mesa por turnos (tateti, teg, solitario) y como usuario me quedé en la época del Age of Empires 2.

Hoy en día siento más curiosidad por el desarrollo de video juegos que por jugarlos. Es por ello cuando dos alumnos de Fiuba me contactaron para que fuera su director en el desarrollo de un videojuego RPG que sería su trabajo final de carrera, no tarde mucho en aceptar.

Es así que luego de armar la propuesta formal del trabajo para la comisión curricular y obtener la aprobación de la misma, esta semana comenzamos a trabajar en el desarrollo.

En cierto modo el alcance está dado por una historia, un “cuentito”, una narrativa que en este caso particular está organizada en capítulos. A la hora de pensar en versiones incrementales del juego uno podría pensar en tener en primera instancia un esqueleto base (walking skeleton) que permita recorrer todos los capítulos con una funcionalidad/extensión mínima. Pero otra alternativa podría ser ver cada capítulo como potencial versión incremental del juego.

Otro elemento del proyecto a destacar es que hay todo un trabajo artístico que incluye elementos multimedia como imágenes y música. De la mano de esto viene el manejo de todos estos artefactos desde el punto de vista de versionado ya que estos archivos suelen ser muy pesados y no es conveniente meterlos a la ligera en cualquier versionador.

Desde el punto de vista del desarrollo está la cuestión del motor, o sea, es muy común que estos juegos se desarrollen con un motor, en este caso particular el juego está basado en el motor de Unreal.

El último punto que quiero destacar es la mecánica de distribución. Es habitual que los juegos de este tipo se comercialicen y distribuyan utilizando una plataforma como Steamworks, lo cual en cierto modo tiene un impacto en el diseño y la implementación del pipeline de delivery.

Más allá de todas estas cuestiones tengo aún una serie de interrogantes respecto de hasta que punto y con que variaciones pueden aplicarse ciertas técnicas de desarrollo como ser: Test-Driven Development, End-2-End automation testing e integración continua entre otras. Todas estas cuestiones y muchas más son las que espero descubrir en el desarrollo de este trabajo final.

A medida que descubra les iré contando.

Búsqueda laboral Python

Hace unos dos meses me sumé de forma permanente al equipo de radiocut.fm y ahora estamos necesitando ampliar el equipo.

Estamos buscando un desarrollad@r Python/Django. Apuntamos a una persona con al menos 3 años de experiencia con esta tecnología. Somos una empresa con una producto de software estable, tanto en términos técnicos como comerciales. Queremos ampliar el equipo para realizar mejoras en nuestro producto que nos habiliten a poder probar rápida y fácilmente hipótesis de negocio.

Dado que somos un equipo chico tendrás la oportunidad de participar de algunas decisiones de negocio y del roadmap del producto. Asimismo trabajarás con otras tecnologías más allá de Python: Android, JavaScript, Docker y Kubernetes entre otras (no hace falta tengas experiencia en estas tecnologías pero sí que estes dispuesto a aprenderlas).

Trabajamos en iteraciones semanales, con mucha atención a las prácticas técnicas: automatización de pruebas, propiedad compartida, integración continua, despliegues automatizados, etc.

Nuestra dinámica de trabajo es 100% remota aunque tenemos una oficina en el Distrito Tecnológico de la Ciudad de Buenos Aires (Parque Patricios).

Si te interesa postularte puedes contactarme aquí.

Cierre de cuatrimestre en MeMo2@fiuba

Se fue un cuatrimestre más, el noveno desde que estoy a cargo de la materia. Comencemos por los números:

  • 16 inscriptos, 2 abandonos, 1 desaprobado, 13 alumnos aprobaron la cursada
  • 41 tareas individuales incluyendo 9 cuestionarios, 7 ejercicios de programación, 12 lecturas y 11 videos
  • 2 TPs grupales
  • 1 visita de la industria
  • La evaluación general promedio de la materia nos dio 8.2, la cual es la segunda más baja en el histórico (el máximo que teníamos era 8.9). 
  • Curiosamente, contrastando con la métrica anterior, nota promedio de aprobación fue 8.3 (máximo histórico) y la conformidad con la nota fue 4.5 (máximo histórico)
  • La dedicación extra clase promedio dio 12.3, el máximo histórico (el anterior máximo era 9.7). Esto está claramente por encima de nuestra expectativa. Nuestra intención es que como máximo los alumnos dediquen unas 10 horas semanas extra clase.

Adicionalmente, este cuatrimestre medimos por primera vez el Net Promoter Score (NPS): De 1 a 10 ¿Cuán probable es que recomiendes la materia a un compañero?). No voy a entrar en detalle de cómo se calcula el NPS al procesar las respuestas, solo diré que el cálculo nos arrojó un NPS de +42 (en una escala de -100 a +100), lo que representa una calificación favorable.

Entre los temas a mejorar hay 1 que particular se destaca: la gran carga de trabajo requerida por el TP2. A nuestro parecer el TP2 de este cuatrimestre era más simple y acotado que los de los cuatrimestre anteriores, pero creemos que la mayoría de los alumnos tuvieron complicaciones al implementar la persistencia de objetos en una base de datos relacional. En este sentido estamos considerar agregar más soporte sobre esta temática, ya sea generando documentación/videos, código de ejemplo e incluso algunos ejercicios para resolver en clase.

¿Qué significa calificar con un 10?

Ayer por la tarde estaba cerrando las calificaciones de MeMo2 y mientras lo hacía se me cruzaron algunas ideas que quiero compartir.

De entrada, dado que 10 suele ser la calificación máxima, uno podría pensar que un 10 equivale a haber hecho todo bien. Sin embargo no siempre es así.

En mi época de estudiante en mi carrera de grado recuerdo haber cursado una materia en la que el algoritmo de calificación era: al que mejor resolvió el problema un 10 (y luego de ahí para abajo) incluso esa solución no sea la mejor solución conceptual. Personalmente no comparto este criterio pero simplemente lo menciono como un ejemplo de que un 10 no siempre implica haber hecho todo bien.

El problema o mejor dicho la limitación que tiene el reservar el 10 solo para el caso en que “está todo bien”, no da lugar a la equivocación, al error, el cual es en muchos casos una oportunidad de aprendizaje. Es por esto que cuando decido calificar con un 10 no es un hecho que el alumno haya hecho todo bien. O sea, si el alumno hizo todo bien, no hay duda: tendrá un 10. Pero puede también que el alumno haya cometido algunos errores y aún así tenga un 10. Al fin y al cabo lo que uno pretende evaluar es el aprendizaje y en ese sentido uno podría pensar que haberse equivocado y aprendido de esa equivocación termina siendo un aprendizaje más significado que haber hecho todo bien de entrada.

Feliz 200 años UBA

Ingresé a la UBA en 1998, me llevó 3 cuatrimestres completar las 6 materias del Ciclo Básico Común. Es así que mi ingreso a la Facultad de Ingeniería fue recién a mediados de 1999.

En 2001 cursé la materia Algoritmos y Programación 3 que marcó un hito en mi formación y en mi carrera. Recuerdo mi exaltación cuando nos dijeron que el trabajo práctico de la materia era programar un juego tipo TEG. Estaba como loco, yo era fanático del TEG y tenía la intención de hacer una versión para jugar en computadora cuando me recibiera de ingeniero, y de repente tenía que programarlo en una materia de segundo año. Excelente. Tal era mi motivación que recuerdo que ese cuatrimestre estaba cursando Análisis Matemático 2 y decidí abandonarla para poder dedicar más tiempo a programar el TEG. Valió la pena, nos sacamos un 10. En parte, ese 10 posibilitó que el profesor Fontela me ofreciera sumarme al equipo docente de la materia. Ni lo dudé y así empezó mi relación con Carlos Fontela quien ha sido mi mentor en la docencia. Trabajé en el equipo de Carlos durante más de 15 años, aprendí muchísimo, de Carlos, de los otros docentes y de los alumnos que pasaron por el curso. Es por esto que le estoy eternamente agradecido a Carlos.

En 2002 cursé la materia Teoría de Algoritmos donde conocí a la profesora Rosita Wachenchauzer con quien también tuve la oportunidad de ejercer la docencia. Años más tarde Rosita fue mi directora de tesis. Mis agradecimientos también para Rosita.

En 2006 cursé mi última materia, Introducción de a los Sistemas Distribuidos. En 2007 completé mi tesis de ingeniería.

Si bien mi desempeño docente comenzó 2001, no fue hasta 2003 que fui nombrado formalmente como docente auxiliar (ayudante de segunda, el único cargo docente al que pueden acceder los estudiantes). Desde entonces vengo concursando y recorriendo toda la carrera docente: ayudante de segunda, ayudante de primera, jefe de trabajos prácticos y profesor.

Hoy en día, 23 años después de haber ingresado como estudiante, sigo en UBA pero ahora como profesor. Estoy a cargo de la materia Métodos y Modelos de la Ingeniería de Software 2 (95.21).

Creo que la UBA tiene muchas virtudes pero sin duda también mucho por mejorar. Hay falencias que viví en mi época de estudiante que fueron resueltas pero hay algunas otras que aún hoy siguen sin solución (ya escribiré de esto en otro momento).

Poco me importan “los laureles” de la UBA, sus posiciones en los rankings, quienes pasaron por sus aulas, los logros de sus graduados y demás datos. La UBA me formó en muchos sentidos y hasta en un punto creo que la formación académica no fue necesariamente el factor más relevante. Si, obtuve un título y contento estoy con ello, pero haber estudiando en la UBA formó mi carácter y todo un conjunto de habilidades que exceden los conocimientos particulares en ingeniería de software. En UBA conocí muchos profesionales que admiro y con algunos de los cuales aún hoy tengo el placer de trabajar. Hoy en día, en mi rol de profesor sigo aprendiendo. ¿Habría sido lo mismo en otra casa de estudios? Tal vez sí, tal vez no, no lo sé y tampoco importa. Estudié en UBA y sigo siendo parte de UBA. Gracias UBA, felices 200 años.