Trabajos prácticos

TP 1 - Procesador de imágenes de Pixabay

Condiciones y formato de entrega

Deberán formar sus grupos de 2 personas, clonarse este repositorio y trabajar allí.

Se tomará como entrega el código que esté allí el día Viernes 6 de Marzo a las 23:59 horas, sin excepciones. Luego de la entrega habrá una defensa individual en clase para validar que todas las personas del grupo hayan aportado al trabajo.

Criterios de evaluación y calificación

Para aprobar, deben cumplir todos los siguientes requisitos:

Para poder promocionar, deben además implementar correctamente la mayor cantidad de bonus. Ojo con esto: preferimos un programa que funciona y hace menos cosas a uno que pretende hacer un montón de cosas pero no funciona ninguna.

Además, tendremos en cuenta estos criterios de calidad para la construcción de la nota final:

Configuración del entorno

  1. Desde una consola dentro del proyecto, ejecutar pip3 install -r requirements.txt para instalar las dependencias.
  2. Crearse una cuenta en Pixabay.
  3. Obtener el API key desde la página de la documentación.
  4. Agregar la API key al código y ejecutarlo para verificar que funcione.

Consignas

El objetivo del trabajo es construir un script en Python que a partir de una query realice las siguientes acciones:

En imágenes, sería algo así:

Descargadas

Transformadas

Compilada

Para hacer esto, obviamente deberán utilizar threads y algún mecanismo de sincronización de los vistos hasta ahora: locks, semáforos y/o monitores. Las transformaciones pueden ser las que ustedes quieran, lo único que les pedimos es que sean al menos dos.

A muy alto nivel, el programa debería comportarse así:

  1. realizar una request a Pixabay para obtener las URLs de las imágenes,
  2. descargar cada una de las imágenes (en threads separados),
  3. mientras se van descargando las imágenes, aplicar las transformaciones (en un thread por cada transformación),
  4. a medida que haya imágenes transformadas, armar los trípticos (en un thread aparte).

Si por ejemplo se van a descargar 30 imágenes y aplicar 3 efectos a cada una, debería haber al menos 34 threads corriendo: los 30 que descargan las imágenes + los 3 para los efectos + el que genera los trípticos. Si lo consideran necesario, podría haber más threads, pero no vale hacerlo con menos.

Consejos para la implementación

Largarse a hacer todo de una puede ser un poco abrumante, les recomendamos dividir el problema en varias etapas que ataquen de a una complejidad a la vez. En esta línea, podrían ir haciendo el programa de manera incremental siguiendo los puntos descriptos en el apartado anterior: una primera versión que solo baje las imágenes, una segunda que además las transforme, una tercera que además las compile.

También podría servirles hacer todo sin threads y luego ir incorporándolos para cada funcionalidad. Para que no tengan que reescribir todo el código después, es muy importante que modularicen su código usando funciones y/o clases (recuerden que fuimos sus profes de Objetos 1 y sabemos de qué son capaces).

En cuanto a la sincronización, una forma posible de encararla es utilizando una lista (o cola) para cada paso del algoritmo. Lo que debería hacer cada etapa es:

Ojo :eye:: los efectos trabajan de a una imagen a la vez, pero la generación de trípticos necesita que haya al menos tres elementos para poder procesar. Tienen que contemplar esto en el mecanismo de sincronización que implementen.

Bonus

Parametrizaciones

Agregarle al script la capacidad de parametrizar:

  1. la cantidad de threads que aplica cada transformación,
  2. la cantidad de threads que arman los trípticos,
  3. la cantidad de imágenes que tiene cada tríptico (que, lógicamente, dejaría de ser un tríptico para pasar a ser un N-íptico :stuck_out_tongue:).
  4. más difícil: qué transformaciones se van a aplicar, eligiendo de una lista de transformaciones que ustedes hayan implementado. Por ejemplo, la entrada podría ser “rotacion,contraste,escala_grises” y ustedes deberían aplicar esos tres efectos,
  5. más más difícil: la cantidad de threads que se encargan de bajar las imágenes. El máximo va a coincidir con la cantidad de imágenes que se van a descargar, pero podría elegirse un valor menor (por ejemplo: usar 5 threads para bajar 30 imágenes).

Esto pueden lograrlo de tres maneras:

Elijan la que les de mayor satisfacción. :smiley:

Optimización de performance

Una vez resueltos los puntos 1 y 2 del apartado anterior, ir variando la cantidad de threads y medir el tiempo que tarda en ejecutar con cada una de las combinaciones. Registrar estos datos en el repositorio - podría ser con una tabla en el README.md o algún tiempos.txt en la raíz (por favor no usen Excel ni Word ni nada de eso, que no se puede ver directamente desde GitHub).

Con las mediciones en mano, buscar la combinación de threads que parezca más óptima.

Repositorios de ejemplo