5.2 Un buen programador es un vago consciente

5.2 Un buen programador es un vago consciente

Capítulo publicado el 15/6/2022 por Enric Caumons Gou (@caumons)
  • 5 min de lectura

Esta afirmación puede parecer muy tajante y despectiva hacia el colectivo de desarrolladores de software, pero no lo es en absoluto y además me incluyo en la definición. Si lo pensamos bien, a lo largo de los días hacemos muchas tareas de forma rutinaria que no nos aportan nada especial, tanto en nuestra vida personal como profesional. Aquí es donde entran en juego la vagancia, la automatización, la tecnología, el talento y el ingenio.

Automatizar tareas repetitivas y/o aburridas

El tiempo es oro y para mí no hay nada mejor que poder automatizar algo que antes tenía que hacer manualmente y poder invertir ese tiempo en hacer otras cosas o simplemente no hacer nada. Además, cuando hacemos tareas de forma repetida, nuestra productividad se ve afectada negativamente porque nos aburrimos, no prestamos tanta atención y empezamos a cometer errores.

Cuando automatizamos tareas, buscamos patrones que se repitan y puedan ser realizados de forma autónoma por las máquinas. Sin embargo, a veces no podemos automatizar completamente los procesos o simplemente no vale la pena el esfuerzo requerido para lograrlo. En tales casos, una solución de compromiso (intermedia) puede ser muy efectiva, haciendo que el proceso sea semiautomático, por ejemplo, desarrollando un programa que asista la entrada de datos del usuario, guiándolo y validando la información introducida, de forma que le facilite el trabajo y le ahorre tener que hacer las acciones más monótonas y pesadas una y otra vez. De este modo, podremos aumentar la productividad y nos ahorraremos muchos errores humanos gracias a la automatización, aunque solo sea parcial. De hecho, esto es muy común en las fábricas, donde hay partes del proceso de producción que están totalmente automatizadas mediante el uso de software, máquinas y robots, mientras que hay otros pasos que son completamente manuales. No obstante, también hay que decir que cada vez somos capaces de automatizar más los procesos debido a los avances tecnológicos y lo que antes era imposible o no era factible hoy en día sí lo es o lo será en un futuro no muy lejano.

Además de todo esto, también hay que tener en cuenta que a veces resulta imposible obtener la solución óptima, ya que, por ejemplo, hay tantas posibles combinaciones que resultaría demasiado lento calcularlas todas. Por este motivo, en ocasiones usamos algoritmos greedy, que nos proporcionan aproximaciones suficientemente válidas.

Me acuerdo de una historia que leí hace tiempo en un libro que hablaba de una pequeña aldea que necesitaba abastecerse de agua. Dos personas se ofrecieron a traer agua, el primero de ellos cogió dos cubos y empezó a hacer viajes trayendo agua del río más cercano desde el primer día de trabajo. El segundo hombre, en cambio, empezó a diseñar y construir un sistema con una bomba y canalización para llevar el agua desde el río hasta la aldea. Pasaban los días y el primer hombre seguía haciendo viajes diariamente trayendo cubos llenos de agua, mientras el segundo seguía trabajando sin haber llevado una sola gota de agua a la aldea desde que empezó. Finalmente, después de unos cuantos días, el segundo hombre había terminado su sistema y el agua empezó a llegar a la aldea directamente sin que él tuviera que hacer nada. Evidentemente, el primero dejó de hacer viajes trayendo cubos de agua porque su sistema manual no era eficiente y había quedado obsoleto.

Casos como este me han sucedido muchísimas veces, tanto en el trabajo como en mi vida personal, voy a poner tres ejemplos. En el primero de ellos teníamos que comprobar si más de 30.000 páginas web mostraban un mapa de Google Maps a los usuarios o no. En un principio, se pensó en hacer esta tarea manualmente. Es decir, acceder a cada una de estas páginas y ver si se mostraba un mapa, navegando por las posibles diferentes pestañas dentro de la página y haciendo scroll por si el mapa estaba al final de la página. ¡Esto no era una tarea, era un castigo! Efectivamente, la tarea se pudo automatizar y ganamos días enteros de un trabajo nada gratificante.

Descripción técnica (opcional):

Una cosa es que se incluya el fichero JavaScript de la librería de Google Maps y la otra es que realmente se use para mostrar un mapa. Así que le di unas cuantas vueltas hasta que me di cuenta de que los mapas de Google contienen una clase de CSS llamada «gm-style», por tanto, si había esa clase, significaba que se estaba mostrando y, si no estaba, entonces no había mapa. Obviamente, este elemento no se encuentra en el HTML de la página porque se genera dinámicamente vía JavaScript. Por lo tanto, usé Selenium para buscar si existía un elemento con esta clase. Se podría argumentar que esta automatización puede no ser perfecta, pero hacerlo manualmente tampoco lo era y además era muchísimo más lento y costoso. Así pues, lo mejor en estos casos es aplicar una solución best effort.

En el segundo ejemplo se trata de filtrar imágenes separadas en dos grandes grupos. El primer grupo de imágenes estaba ligado a una hoja de cálculo de un libro de Excel y constaba de unas 10.000 imágenes, mientras que el segundo estaba relacionado con una tabla de una base de datos de Access y constaba de unas 38.000 imágenes. En total estamos hablando de unas 48.000 imágenes organizadas en más de 300 directorios. En un inicio se quería hacer manualmente, hasta que se vio que era una locura y aquí entró de nuevo en acción la «vagancia». ¿Por qué tenemos que pasarnos días enteros clasificando imágenes si podemos automatizarlo? Pues bien, efectivamente, automaticé el proceso y en menos de una jornada ya teníamos las imágenes clasificadas en los dos grupos correspondientes, según las reglas de negocio que tenían que cumplir. Por ejemplo, eliminar las imágenes de ciertos directorios, eliminar las que no empezaran por unas letras en concreto, eliminar también las imágenes donde los campos X e Y de la tabla de Access estuvieran informados o solo estuviera informado uno de ellos, pero contuviera al menos dos palabras… No sigo para no aburrirte, pero ya te puedes hacer una idea de que tener que hacer esto a mano no es trivial, es muy tedioso y no se lo deseo a nadie.

El tercer ejemplo, el cual ilustra perfectamente la vagancia en su exponente máximo, es hacer un programa, llamado Play, con Python 3 y una base de datos SQLite (usando una Raspberry Pi) para crear listas de reproducción de ficheros multimedia de audio y vídeo. De esta forma, no tengo que acordarme del capítulo o canción por la que voy, ya que con solo pulsar un botón la reproducción continúa donde la había dejado. Además, no contento con esto, al cabo de un tiempo creé MediaLib, otro proyecto del cual también he hablado al principio del libro y que amplía y mejora las funcionalidades de Play.

Podría poner muchísimos más ejemplos, pero creo que con estos tres es suficiente para hacerse una idea de por dónde van los tiros.

Cada error supone uno o más problemas que interrumpen su vagancia

Si estamos hablando de automatización para librarnos de tener que hacer trabajos rutinarios que no nos aportan nada y nos quitan mucho, entonces tenemos que asegurarnos de que nuestra vagancia no se verá interrumpida fácilmente. ¿Qué significa esto? Pues que tenemos que hacer las cosas bien para que sean robustas y no fallen a la primera de cambio.

Siguiendo con los ejemplos anteriores, cuando automaticé la búsqueda de mapas, las primeras versiones del software fallaban a los pocos minutos: había URL que se quedaban cargando indefinidamente, otras que no existían o que daban error al intentar acceder, etc. Así pues, tuve que implementar un sistema de recuperación de errores robusto para que el programa fuera resiliente y, por lo tanto, se pudiera recuperar sin necesidad de intervención humana cuando encontrara cualquiera de estos problemas. Después de pulirlo unas cuantas veces, conseguí un script que funcionó durante horas seguidas de forma totalmente autónoma, mientras yo podía ir haciendo otras cosas.

Si llevamos al extremo la comprobación de la resiliencia de nuestros sistemas, nos encontramos con la ingeniería del caos, que es la disciplina de experimentar en un sistema, con la finalidad de generar confianza en su capacidad para soportar condiciones turbulentas en producción. Dicho con otras palabras, consiste en hacer pruebas en los entornos reales para comprobar que funcionarán según lo previsto ante condiciones adversas. Por ejemplo, en el caso de Netflix, usan un conjunto de herramientas llamado «Simian Army» para provocar errores en producción de forma automatizada y así poder mejorar los puntos débiles encontrados. De este modo, pueden prepararse mejor para cuando ocurran fallos reales no provocados. Parece increíble, ¿verdad?

¡Únete a la comunidad para no perderte nada!

¡Quiero unirme!

¿Qué te ha parecido este capítulo?

¡Compártelo!

¡Suscríbete al feed para estar al día cada vez que se publique un nuevo capítulo!

Comprar libro

${ commentsData.total }

Todavía no hay comentarios. ¡Sé el primero!

Inicia sesión para publicar, responder o reaccionar a los comentarios.

Esta web utiliza cookies. Si continúas usándola, asumiremos que estás de acuerdo.