{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DCCHuelga\n",
    "Los ayudantes de Programación Avanzada nos fuimos a huelga porque nos cansamos de que los profes no se acuerden de nuestros nombres. Los profesores nos dijeron que si organizamos una bienvenida donde cada ayudante se presenta, entonces se acordarían de los nombres de cada uno. Como buenos programadores 🤓, decidimos que vamos a organizar esto usando OOP."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para esto, implementamos la clase **PrograAvanzada**, la cual va a tener como atributos un semestre y una lista de ayudantes, y un método **saludo_ayudantes()**, para que cada ayudante se presente. Los profes nos facilitaron unos archivos **.csv** con los datos de cada ayudante, pero rápidamente nos dimos cuenta que esta tarea no va a ser tán fácil como pensábamos, ya que hay ayudantes con distintas carreras y distintos majors, y todos tienen datos distintos 😧. Sabemos ya por lo que vimos la semana pasada que podemos modelar la clase abstracta **Ayudante** y hacer que los otros tipos de ayudantes hereden de ella, pero cómo hacemos para añadir los ayudantes con una sola función? \n",
    "\n",
    "### Diccionarios 😎\n",
    "\n",
    "Vamos a crear la función **leer()**, que toma como argumento el nombre del archivo y nos retorna diccionarios donde la key es el nombre del parámetro y el value es el valor del argumento. Los diccionarios pueden ser retornados dentro de una lista o de un generador.\n",
    "\n",
    "También vamos a implementar el método **añadir_ayudantes()** de la clase **PrograAvanzada**, que toma como argumento el nombre del archivo e instancia y añade cada estudiante a la lista de estudiantes.\n",
    "\n",
    "Los archivos **.csv** se encuentran en la carpeta **data**, y la primera línea siempre tiene el nombre de los parámetros separados por \";\", y las líneas siguientes serán los argumentos para cada instancia, también separados por \";\".\n",
    "\n",
    "El código base está en el archivo dcchuelga.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DCCumple\n",
    "\n",
    "Se acerca tu cumpleaños y decides organizar una fiesta 🎉🎉, para ello encuentras un centro de eventos, pero tiene muchas restricciones 😨, por lo que decides revisar con tu nueva maestría de Programación Funcional y estructuras de datos si te conviene realmente el local o no!\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dentro de las restricciones del local están las siguientes:\n",
    "\n",
    "- Amigos con más de 18 años y menos de 30.\n",
    "- No aceptan personas del grupo \"B2\", la última vez rompieron todo 🤬."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Además, para organizarte mejor decides obtener lo siguiente:\n",
    "- Diccionario de Listas de personas por dieta.\n",
    "- Organizar por grupo a tus amigos (utiliza un diccionario), para esto solo necesitas su nombre.\n",
    "- Música preferida Hint: investigue la función de listas .count().\n",
    "- Edad Promedio (para esto no puedes usar len())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para realizar lo anterior cuentas con el archivo `invitados.csv`, el cual tiene por primera línea lo siguiente:\n",
    "\n",
    "`nombre, edad, grupo, dieta, musica`\n",
    "\n",
    "Donde:\n",
    "- nombre : str\n",
    "- edad : int\n",
    "- grupo : str\n",
    "- dieta : str `{O: omnivoro, V: vegetariano/vegano, C: celiaco}`\n",
    "- musica: str\n",
    "\n",
    "\n",
    "Ademas, tienes un código base (`DCCumple.py`) que puede ser de utilidad."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# I(IC2233)Tunes\n",
    "\n",
    "Decides descargar una aplicación para concentrarte e ignorar el celular, pero se te olvidó que tampoco te permitiría usar tu servicio de streaming de música preferido! 😨 En lugar de rendirte ante esta desgracia, decides utilizar tus nuevos conocimientos en estructuras e iterables para crear tu PROPIO SERVICIO DE STREAMING! \n",
    "\n",
    "Además, por suerte (y conveniencia de la trama) te topas con una interfaz casi lista, la aplicación I(IC2233)Tunes. Solo debes completar los elementos funcionales, como las Canciones y Playlists, para poder usar la aplicación correctamente.\n",
    "\n",
    "### Tu misión\n",
    "\n",
    "#### Canciones\n",
    "\n",
    "Tu primera tarea es definir las Canciones. Debes utilizar una estructura apropiada, teniendo en cuenta que (1) Una vez creadas, no necesitan ser modificadas y (2) Se debe poder acceder a su nombre y artista mediante la sintaxis:\n",
    "\n",
    "```\n",
    "cancion.nombre\n",
    "cancion.artistas\n",
    "```\n",
    "\n",
    "#### Playlists\n",
    "\n",
    "Luego, debes implementar los métodos de la clase Playlist. Para esto debes conocer los atributos de la clase:\n",
    "\n",
    "- ```self.canciones```: Una lista que representa todas las canciones de la playlist.\n",
    "- ```self.cola```: Una lista que representa la cola de reproducción de la playlist. Puede variar, acortándose a medida que se reproduce la playlist, y puede desordenarse en comparación a ```self.canciones```.\n",
    "\n",
    "Ahora sí. Los métodos que debes implementar son los siguientes:\n",
    "\n",
    "- ```mostrar_canciones(self)```: Por cada canción de la playlists, debes imprimirla en el formato:\n",
    "```\n",
    "- <nombre> - <artista>\n",
    "```\n",
    "Además, debes retornar\n",
    "\n",
    "\n",
    "- ```agregar_cancion(self, cancion)```: Dada una canción (ya instanciada en el formato debido) debes agregar la canción a la playlist, asegurándote de que esta NO esté repetida.\n",
    "\n",
    "- ```eliminar_cancion(self, cancion)```: Dada una canción instanciada, debes eliminarla de la playlist.\n",
    "\n",
    "- ```reproducir_por_nombre(self, cancion)```: Dada una canción instanciada, debes crear una cola de reproducción en el *mismo orden* que ```self.canciones```, pero desde esa canción en adelante.\n",
    "\n",
    "Por ejemplo, si self.canciones es:\n",
    "```\n",
    "[\n",
    "    Cancion(\"Fuentes de Ortiz\", \"Ed Maverick\"), \n",
    "    Cancion(\"Lisa\", \"Young Miko\"), \n",
    "    Cancion(\"drivers license\", \"Olivia Rodrigo\"), \n",
    "    Cancion(\"Breathing\", \"Yellowcard\")\n",
    "]\n",
    "```\n",
    "\n",
    "y se recibe ```reproducir_por_nombre(Cancion(\"drivers license\", \"Olivia Rodrigo\"))```, entonces self.cola debe ser:\n",
    "\n",
    "```\n",
    "[\n",
    "    Cancion(\"drivers license\", \"Olivia Rodrigo\"), \n",
    "    Cancion(\"Breathing\", \"Yellowcard\")\n",
    "]\n",
    "```\n",
    "\n",
    "- ```reproducir_al_azar(self)```: Debes crear una cola de reproducción en base a la lista original, pero **aleatorizada**.\n",
    "\n",
    "#### Playlist Iterable\n",
    "\n",
    "Además de los anteriormente mencionados, esta clase debe ser **iterable**, para poder ser utilizada en la aplicación. La forma en que decidas implementar la iteración depende de tí (puedes crear un iterador aparte o no). La iteración debe extraer la siguiente canción de la cola.\n",
    "\n",
    "El único requisito es que la estructura iteradora DEBE implementar el método ```siguiente_cancion()```. Este método debe utilizar la función ```next()``` sobre la estructura iteradora.\n",
    "\n",
    "#### Aplicación IIC2233Tunes\n",
    "\n",
    "Finalmente, cuentas con la clase IIC2233Tunes, que contiene algunos métodos que debes completar:\n",
    "\n",
    "- ```menu_ver_playlists(self)```: El único menú sin completar. Es un método que proyecta el submenú \"ver playlists\" con sus opciones. Debes manejar el input recibido y ejecutar el submenú correspondiente (detallados en el código). Aquí está el desafío: NO puedes usar If's D:\n",
    "\n",
    "*HINT*: Recuerda que puedes guardar funciones si las escribes sin sus paréntesis 👀\n",
    "\n",
    "- ```fusionar_playlists(self, p1, p2)```: Dadas dos playlists p1 y p2, debes crear una nueva playlists con sus canciones. Cada canción debe aparecer UNA SOLA VEZ en la playlist final.\n",
    "\n",
    "- ```reproducir_por_nombre(self, playlist)```: Dada una Playlist, el método consulta por el nombre y artista de una playlist. Con esa información, debes ejecutar el método correspondiente de la Playlist e iniciar su iteración.\n",
    "\n",
    "- ```reproducir_al_azar(self, playlist)```: Dada una Playlist, debes ejecutar el método correspondiente de la Playlist e iniciar su iteración.\n",
    "\n",
    "- ```siguiente_cancion(self)```: Método encargado de pedir la siguiente canción a la playlist, además de asignarla a ```self.cancion_actual```. Debe manejar correctamente el caso en que la playlist haya terminado. La implementación de este método depende tu implementación del iterable.\n",
    "\n",
    "*NOTA*: La playlist actual es asignada cuando se elige para reproducir. Esto ya está implementado.\n",
    "\n",
    "\n",
    "El código contiene comentarios acerca de qué hacer en donde se necesite algo más de detalle :)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DCCabify\n",
    "\n",
    "¡Felicidades! Te han contratado para desarrollar software para la empresa DCCabify (muy original), se te han encomedado diversas tareas, entre ellas encontrarás el leer un archivo para luego generar ciertas operaciones para que la empresa logre tomar decisiones acertadas para su público. Deberás rellenar ciertas funciones que le faltan a la *clase* *Aplicacion* para asi cumplir tu cometido en la empresa, todas estas deben ser empleadas con la mayor optimización de estructuras posibles."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Clientes.txt\n",
    "\n",
    "El archivo clientes.txt presenta la siguiente estructura:\n",
    "\n",
    "* Nombre|Numero|Gasto_por_semana \n",
    "\n",
    "Donde algun dato puede estar dañado (NULL) y/o se podrán repetir datos, ejemplo:\n",
    "\n",
    "|Juan Perez|NULL|2000\n",
    "|---|---|---\n",
    "|Carlos Bernard|942124523|5000\n",
    "|Carlos Bernard|942124523|5000"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DCCAplicacion\n",
    "\n",
    "Esta clase debera recibir en su *__init__* la ruta del archivo *clientes.txt* (no olvides paths), para luego crear los siguientes metodos:\n",
    "* ```leer_archivo(self)```: Deberas leer el archivo *clientes.txt* empleando una estructura óptima para asi ahorrar código. Luego en el método \n",
    "* ```arreglar_archivo(self)```: Deberás eliminar tanto los datos corruptos como los repetidos.\n",
    "* ```nombres_gasto(self)```: Deberás encontrar todos los nombres de las personas que gastan igual o más que *10.000* pesos a la semana.\n",
    "* ```promedio_gasto(self)```: Deberás encontrar el promedio de los que gastan más de *10.000* pesos a la semana.\n",
    "* ```recorrer_especifico(self,objetivo)```: Deberás retornar un generador que permita recorrer los *numeros* de las personas que gastan menos de *10.000* pesos a la semana si es que tu objetivo es *menor*, en el caso que objetivo sea *mayor* deberas retornar los numeros de las personas que gastan más de *10.000* pesos a la semana."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DCCafeteria ☕"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nuestra querida Pepa🐢 ha decidido crear una cafetería, para ello tiene un pequeño menú con productos, pero necesita tu ayuda para poder mostrarlos más fácilmente. ¡PERO CUIDADO! El malvado profesor Hernán🦖 le ha prohibido a Pepa utilizar `for` o `while`, por ende, tendrás que hacerlo todo utilizando los contenidos que aprendiste de estructuras iterables.\n",
    "\n",
    "Lo primero que debes hacer es modificar `obtener_producto()` para que este nos retorne un generador con los nombres de todos los Productos de la cafetería.\n",
    "\n",
    "Luego, deberás modificar `filtrar_por_categoria` para que este retorne un generador con todos los nombres de los Productos pertenecientes a la categoría indicada.\n",
    "\n",
    "Finalmente, deberás modificar `buscar_mas_barato` para retornar un generador con el nombres del Producto más económico,\n",
    "en caso de haber más de uno, debe retornarlos todos."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
