Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 200 additions & 0 deletions recetario.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
"""Interfaz de consola para consultar las recetas de recetas_saludables.csv."""

import csv
import os
import sys
import unicodedata

RUTA_CSV = os.path.join(os.path.dirname(os.path.abspath(__file__)), "recetas_saludables.csv")


def cargar_recetas(ruta):
with open(ruta, encoding="utf-8", newline="") as fichero:
return list(csv.DictReader(fichero))


def normalizar(texto):
descompuesto = unicodedata.normalize("NFD", texto.lower())
return "".join(c for c in descompuesto if not unicodedata.combining(c))


def a_numero(texto, por_defecto=0.0):
try:
return float(texto)
except (TypeError, ValueError):
return por_defecto


def mostrar_cabecera(titulo):
print("")
print(titulo)
print("-" * len(titulo))


def mostrar_resumen(receta):
print("[{:>3}] {:<45} {:>4} kcal {:>3} min {}".format(
receta["id"],
receta["nombre"][:45],
receta["calorias_kcal"],
receta["tiempo_min"],
receta["dificultad"],
))


def mostrar_listado(recetas):
if not recetas:
print("No hay recetas que cumplan ese criterio.")
return
for receta in recetas:
mostrar_resumen(receta)
print("Total: {} receta(s).".format(len(recetas)))


def mostrar_detalle(receta):
mostrar_cabecera("{} (id {})".format(receta["nombre"], receta["id"]))
print("Categoría : {}".format(receta["categoria"]))
print("Raciones : {}".format(receta["raciones"]))
print("Tiempo : {} min".format(receta["tiempo_min"]))
print("Dificultad: {}".format(receta["dificultad"]))
print("")
print("Ingredientes:")
for ingrediente in receta["ingredientes"].split("|"):
print(" - {}".format(ingrediente.strip()))
print("")
print("Preparación:")
print(" {}".format(receta["preparacion"]))
print("")
print("Valores nutricionales por ración:")
print(" Calorías : {} kcal".format(receta["calorias_kcal"]))
print(" Proteínas : {} g".format(receta["proteinas_g"]))
print(" Carbohidratos: {} g".format(receta["carbohidratos_g"]))
print(" Grasas : {} g".format(receta["grasas_g"]))
print(" Azúcares : {} g".format(receta["azucares_g"]))
print(" Fibra : {} g".format(receta["fibra_g"]))
print("")
print("Fuente nutricional: {}".format(receta["fuente_nutricional"]))
print("Fuente receta : {}".format(receta["fuente_receta"]))


def preguntar(mensaje):
return input(mensaje).strip()


def listar_todas(recetas):
mostrar_cabecera("Todas las recetas")
mostrar_listado(recetas)


def ver_detalle(recetas):
identificador = preguntar("\nId de la receta: ")
for receta in recetas:
if receta["id"] == identificador:
mostrar_detalle(receta)
return
print("No existe ninguna receta con el id '{}'.".format(identificador))


def buscar_por_nombre(recetas):
texto = preguntar("\nTexto a buscar en el nombre: ")
if not texto:
print("Hay que escribir algún texto.")
return
buscado = normalizar(texto)
mostrar_cabecera("Recetas cuyo nombre contiene '{}'".format(texto))
mostrar_listado([r for r in recetas if buscado in normalizar(r["nombre"])])


def buscar_por_ingrediente(recetas):
texto = preguntar("\nIngrediente a buscar: ")
if not texto:
print("Hay que escribir algún ingrediente.")
return
buscado = normalizar(texto)
mostrar_cabecera("Recetas con '{}'".format(texto))
mostrar_listado([r for r in recetas if buscado in normalizar(r["ingredientes"])])


def filtrar_por_categoria(recetas):
categorias = sorted({r["categoria"] for r in recetas})
print("\nCategorías disponibles: {}".format(", ".join(categorias)))
texto = preguntar("Categoría: ")
buscada = normalizar(texto)
mostrar_cabecera("Recetas de la categoría '{}'".format(texto))
mostrar_listado([r for r in recetas if normalizar(r["categoria"]) == buscada])


def filtrar_por_calorias(recetas):
maximo = a_numero(preguntar("\nCalorías máximas (kcal): "), -1.0)
if maximo < 0:
print("Hay que introducir un número positivo.")
return
encontradas = [r for r in recetas if a_numero(r["calorias_kcal"]) <= maximo]
encontradas.sort(key=lambda r: a_numero(r["calorias_kcal"]))
mostrar_cabecera("Recetas de hasta {:.0f} kcal".format(maximo))
mostrar_listado(encontradas)


def mostrar_estadisticas(recetas):
if not recetas:
print("No hay recetas cargadas.")
return
calorias = [a_numero(r["calorias_kcal"]) for r in recetas]
proteinas = [a_numero(r["proteinas_g"]) for r in recetas]
tiempos = [a_numero(r["tiempo_min"]) for r in recetas]
mostrar_cabecera("Estadísticas del recetario")
print("Recetas : {}".format(len(recetas)))
print("Calorías mín/media/máx: {:.0f} / {:.1f} / {:.0f}".format(
min(calorias), sum(calorias) / len(calorias), max(calorias)))
print("Proteínas medias : {:.1f} g".format(sum(proteinas) / len(proteinas)))
print("Tiempo medio : {:.1f} min".format(sum(tiempos) / len(tiempos)))


OPCIONES = [
("1", "Listar todas las recetas", listar_todas),
("2", "Ver el detalle de una receta", ver_detalle),
("3", "Buscar por nombre", buscar_por_nombre),
("4", "Buscar por ingrediente", buscar_por_ingrediente),
("5", "Filtrar por categoría", filtrar_por_categoria),
("6", "Filtrar por calorías máximas", filtrar_por_calorias),
("7", "Estadísticas", mostrar_estadisticas),
]


def mostrar_menu():
mostrar_cabecera("RECETARIO SALUDABLE")
for clave, descripcion, _ in OPCIONES:
print("{}. {}".format(clave, descripcion))
print("0. Salir")


def main():
if not os.path.exists(RUTA_CSV):
print("No se encuentra el fichero {}".format(RUTA_CSV))
return 1

recetas = cargar_recetas(RUTA_CSV)
print("Cargadas {} recetas de {}".format(len(recetas), os.path.basename(RUTA_CSV)))
acciones = {clave: funcion for clave, _, funcion in OPCIONES}

while True:
mostrar_menu()
try:
opcion = preguntar("Elige una opción: ")
except (EOFError, KeyboardInterrupt):
print("")
return 0
if opcion == "0":
print("¡Hasta la próxima!")
return 0
if opcion in acciones:
try:
acciones[opcion](recetas)
except (EOFError, KeyboardInterrupt):
print("")
return 0
else:
print("Opción no válida.")


if __name__ == "__main__":
sys.exit(main())
Loading