Ironhack – Semana 6

Esta semana nos tocaba hacer el proyecto de back-end y aplicar todo lo que hemos visto las semanas anteriores: Node.js, Express.js, MongoDB, Passport.js, nodemailer, login social, APIs… Mi compañero, Brais Vidal, y yo, decidimos hacer una app que recomendase películas y la llamamos Movie Pals.

Movie Pals screenshot
Captura de pantalla de Movie Pals

Demo: http://movie-pals-app.herokuapp.com
GitHub: github.com/reservoirDevelopers/moviepals

El domingo quedamos para hablar de algunos detalles y la verdad es que desde un principio teníamos ideas bastante ambiciosas. La idea más ambiciosa de todas fue intentar programar un motor de recomendaciones. Encontramos un video de YouTube de The Coding Train en el que hacía una versión simplificada de un motor de recomendaciones basado en un algoritmo que aparece en el libro Programming Collective Intelligence de Toby Segaran.

Si queréis ver el video es “Nearest Neighbors Recommendation Engine” (enlaces: parte 1parte 2parte 3). El código que él crea en los vídeos está en su repo de GitHub: CodingTrain/website.

Si no habéis visto videos de The Coding Train, os lo recomiendo, porque es muy entretenido verle programar. Mi vídeo favorito hasta el momento es aquel en el que intenta programar un juego de Snake en 15 minutos. Para empezar la longitud del vídeo te hace spoiler de que no le sale bien, pero es gracioso cuando se empieza a dar cuenta de las cosas que no funcionan y empieza a repetir “Boy, oh, boy!”.

Durante la semana repetimos la estructura de tiempo de la semana 3: kata de CodeWars por la mañana y trabajo en el proyecto el resto del tiempo. Tuvimos un workshop sobre expresiones regulares claro, conciso y muy útil. Además nos enseñaron a desplegar la app en Heroku y desplegar la base de datos en MongoDB Atlas.

Antes de contaros como fue el desarrollo de la app, tengo que decir que en el primer proyecto no conseguí sacar ni una kata de CodeWars en tiempo y esta semana he hecho bien 3 de las 4 que hicimos. 🥳 También me he dado cuenta de que sacarlas o no tiene una clara correlación con mis niveles de frustración con el proyecto en ese momento de la mañana. 😂

Como en la semana 3, os cuento como se repartió el trabajo durante la semana:

  • Lunes: hicimos los modelos para la base de datos. Ya os he contado en otras entradas que usamos MongoDB que es una base de datos no relacional. En nuestro caso decidimos hacer tres: una para usuarios, una para películas, una para críticas de películas. A partir de los modelos creamos las rutas y las vistas de películas y usuarios. También estuvimos mirando la documentación de la API que utilizamos para extraer datos de películas, TheMovieDB, y empezando a hacer llamadas de prueba.
  • Martes y miércoles: aquí vino el lío de adaptar el algoritmo que vimos durante el fin de semana a nuestro proyecto. El algoritmo que elegimos no es ideal, porque es una simplificación de los que se suelen utilizar para sistemas de recomendación y porque no es escalarle entre otras cosas. Pero el mayor problema que hemos tenido al implementarlos, es que el algoritmo original utiliza sólo procesos síncronos, pero el nuestro no. Voy a intentar explicarlo por pasos:
    • Nuestro algoritmo calcula la distancia euclídea entre las valoraciones de dos usuarios. No os asustéis con el nombre, mirad el link a wikipedia y veréis que este concepto lo conocéis desde la secundaria. 😊 Consiste en que se itera por todas las películas que ha visto el usuario1 y se busca si el usuario2 ha valorado alguna de esas películas. Si es así, se resta a la valoración del usuario1, la valoración del usuario2. Esta diferencia entre la valoración de cada película se eleva al cuadrado. Por cada película en la que coincidan se hace esta operación y se van sumando las diferencias al cuadrado. Para limitar el resultado a un número que cuanto mayor sea nos indique más afinidad de gustos entre los dos usuarios, partimos 1 por el número que resulta de la operación anterior.
    • La implementación se hace guardando en dos variables la respuesta de la llamada a la base de datos para obtener los datos de los dos usuarios que queremos comparar. Los datos que devuelve, los pasamos por un Promise.all([promise1, promise2]) y, entonces, efectuamos el cálculo de la similitud que he explicado.
    • Hasta aquí bien, pero claro, lo que queremos es comparar cada usuario con todos los demás usuarios en la base de datos para obtener una lista limitada (un “top 5”, por ejemplo) con los usuarios con gustos más afines. Entonces necesitamos un bucle. ¿Véis el problema antes de que os lo cuente? El bucle es un proceso síncrono, que tiene que llamar al proceso asíncrono de cálculo de similitud descrito anteriormente. Nos encontramos con que el cálculo de similitud no se resolvía cuando lo necesitábamos para continuar y hacer una ordenación de los resultados. Ahora, viéndolo con calma, se me ocurren soluciones para esto, pero en su momento nos supuso un quebradero de cabeza importante. Finalmente con la ayuda del Lead Teacher y los TAs, lo arreglamos un poco, pero perdimos mucho tiempo en ello. Ese tiempo dedicado a otros aspectos de la app habría hecho que el resultado final fuera mucho más vistoso.
  • Jueves: trabajé en las vistas y rutas de los usuarios mientras mi compañero ampliaba las funcionalidades de películas y de críticas.
  • Viernes: por la mañana tuve un momento de crisis porque la tarde anterior estuve haciendo cambios en funciones básicas como el registro de usuarios y varias cosas dejaron de funcionar. No eran buenas noticias teniendo en cuenta que presentábamos por la tarde. Con ayuda del Lead Teacher conseguimos arreglarlo. A las dos de la tarde ya teníamos todo listo para presentar aunque hay algunas funcionalidades de la app que nos hubiera gustado trabajar más.

Aunque no logramos terminar todo lo que queríamos porque, como ya dije, fuimos muy ambiciosos, estoy muy orgullosa del resultado y muy contenta con todo el proceso de creación porque he aprendido muchísimo. Tengo la sensación que si lo hiciera todo desde cero ahora, lo haría más rápido y mejor porque he entendido bien qué cosas no funcionaron y por qué.

A pesar de la cantidad de tiempo que gastamos en ello, no me arrepiento de haber intentado hacer el motor de recomendación. Data science y machine learning me llaman mucho la atención y ha sido interesante leer sobre este tema e intentar hacer algo nuevo.

Trabajar con Brais ha sido una muy buena experiencia. Tiene una gran capacidad de trabajo, muy buenas ideas y esa retranca gallega (un sentido del humor muy nuestro) que echaba en falta como gallega viviendo en Madrid. Al final, nuestro #GaliciaTeam ha salido genial. 👍

Eso es todo amigos. La semana que viene React. Ya os iré contando. 😉

Leave a Reply

Your email address will not be published. Required fields are marked *