|
|
import gradio as gr |
|
|
import random |
|
|
import json |
|
|
from datetime import datetime |
|
|
from chatbot_nuti import buscar_respuesta |
|
|
from coach_emocional import coach_emocional_inteligente |
|
|
from retos_saludables import mostrar_retos, completar_reto |
|
|
|
|
|
|
|
|
MEMORIA_NUTI = [] |
|
|
MEMORIA_COACH = [] |
|
|
|
|
|
calorias_totales = 0 |
|
|
calorias_restantes = 0 |
|
|
historial_comidas = [] |
|
|
|
|
|
|
|
|
def conversar_nuti(mensaje, historial): |
|
|
MEMORIA_NUTI.append({"user": mensaje}) |
|
|
respuesta = buscar_respuesta(mensaje, MEMORIA_NUTI) |
|
|
MEMORIA_NUTI.append({"nuti": respuesta}) |
|
|
historial.append({"role": "assistant", "content": respuesta}) |
|
|
return historial, "" |
|
|
|
|
|
|
|
|
def conversar_coach(mensaje, historial): |
|
|
MEMORIA_COACH.append({"user": mensaje}) |
|
|
respuesta = coach_emocional_inteligente(mensaje, MEMORIA_COACH) |
|
|
MEMORIA_COACH.append({"coach": respuesta}) |
|
|
historial.append({"role": "assistant", "content": respuesta}) |
|
|
return historial, "" |
|
|
|
|
|
|
|
|
def calcular_calorias(edad, peso, altura, genero, actividad, meta): |
|
|
global calorias_totales, calorias_restantes |
|
|
|
|
|
if genero.lower() == "mujer": |
|
|
bmr = 655 + (9.6 * peso) + (1.8 * altura) - (4.7 * edad) |
|
|
else: |
|
|
bmr = 66 + (13.7 * peso) + (5 * altura) - (6.8 * edad) |
|
|
|
|
|
factores = { |
|
|
"sedentario": 1.2, |
|
|
"ligero": 1.375, |
|
|
"moderado": 1.55, |
|
|
"activo": 1.725, |
|
|
"muy activo": 1.9 |
|
|
} |
|
|
|
|
|
calorias_base = bmr * factores.get(actividad.lower(), 1.55) |
|
|
|
|
|
if meta.lower() == "bajar de peso": |
|
|
calorias_totales = round(calorias_base * 0.8) |
|
|
elif meta.lower() == "subir de peso": |
|
|
calorias_totales = round(calorias_base * 1.15) |
|
|
else: |
|
|
calorias_totales = round(calorias_base) |
|
|
|
|
|
calorias_restantes = calorias_totales |
|
|
return f"🎯 Tu meta es **{meta.lower()}**.\n🔥 Puedes consumir aproximadamente **{calorias_totales} calorías por día**." |
|
|
|
|
|
|
|
|
def calorias_reloj(calorias_quemadas): |
|
|
global calorias_restantes |
|
|
calorias_restantes += calorias_quemadas |
|
|
return f"⌚ Has quemado **{calorias_quemadas} kcal**. Te quedan **{calorias_restantes} kcal** disponibles hoy." |
|
|
|
|
|
|
|
|
def analizar_foto(imagen): |
|
|
if imagen is None: |
|
|
return "⚠️ Sube una foto de tu comida.", 0 |
|
|
|
|
|
comidas = [ |
|
|
("Ensalada de pollo", 350), |
|
|
("Hamburguesa con papas", 800), |
|
|
("Taco de carne", 250), |
|
|
("Pizza", 700), |
|
|
("Fruta con yogurt", 200), |
|
|
("Sushi", 450), |
|
|
("Pollo con arroz", 500), |
|
|
("Pasta con salsa", 600) |
|
|
] |
|
|
nombre, calorias = random.choice(comidas) |
|
|
return f"🍽️ Parece que comiste **{nombre}** (~{calorias} kcal).", calorias |
|
|
|
|
|
def registrar_comida(imagen): |
|
|
global calorias_restantes, historial_comidas |
|
|
info, calorias = analizar_foto(imagen) |
|
|
calorias_restantes -= calorias |
|
|
calorias_restantes = max(calorias_restantes, 0) |
|
|
|
|
|
historial_comidas.append({"comida": info, "calorias": calorias}) |
|
|
return f"{info}\n\n🔥 Calorías restantes del día: **{calorias_restantes} kcal**." |
|
|
|
|
|
def mostrar_historial(): |
|
|
if not historial_comidas: |
|
|
return "📭 Aún no has registrado comidas hoy." |
|
|
|
|
|
texto = "🍴 **Historial de comidas:**\n\n" |
|
|
for i, item in enumerate(historial_comidas, 1): |
|
|
texto += f"{i}. {item['comida']}\n" |
|
|
|
|
|
texto += f"\n🔥 Te quedan **{calorias_restantes} kcal** por consumir hoy." |
|
|
return texto |
|
|
|
|
|
|
|
|
RECETAS = [] |
|
|
|
|
|
def subir_receta(nombre, descripcion, imagen): |
|
|
if nombre and descripcion: |
|
|
RECETAS.append({"nombre": nombre, "descripcion": descripcion, "imagen": imagen}) |
|
|
return f"✅ Receta '{nombre}' añadida correctamente." |
|
|
return "⚠️ Ingresa nombre y descripción." |
|
|
|
|
|
def mostrar_recetas(): |
|
|
if not RECETAS: |
|
|
return "📭 No hay recetas cargadas aún." |
|
|
|
|
|
texto = "🍽️ **Recetas Recomendadas:**\n\n" |
|
|
for r in RECETAS: |
|
|
texto += f"**{r['nombre']}**\n{r['descripcion']}\n\n" |
|
|
return texto |
|
|
|
|
|
|
|
|
def buscar_nutriologos(pais, estado, ciudad): |
|
|
ejemplos = [ |
|
|
{"nombre": "Dra. Sofía Martínez", "pais": "México", "estado": "Sonora", "ciudad": "Hermosillo", |
|
|
"especialidad": "Nutrición deportiva", "redes": "@nutrisofi (Instagram)", "reseña": "⭐️⭐️⭐️⭐️⭐️ 4.9"}, |
|
|
{"nombre": "Lic. Andrés Gómez", "pais": "México", "estado": "CDMX", "ciudad": "Coyoacán", |
|
|
"especialidad": "Nutrición clínica", "redes": "@andresnutricion (TikTok)", "reseña": "⭐️⭐️⭐️⭐️ 4.7"}, |
|
|
{"nombre": "Dra. Camila Silva", "pais": "Chile", "estado": "Región Metropolitana", "ciudad": "Santiago", |
|
|
"especialidad": "Salud emocional", "redes": "@camila.wellness (Instagram)", "reseña": "⭐️⭐️⭐️⭐️⭐️ 5.0"} |
|
|
] |
|
|
|
|
|
resultados = [ |
|
|
n for n in ejemplos |
|
|
if n["pais"].lower() == pais.lower() |
|
|
or n["estado"].lower() == estado.lower() |
|
|
or n["ciudad"].lower() == ciudad.lower() |
|
|
] |
|
|
|
|
|
if not resultados: |
|
|
return "❌ No se encontraron nutriólogos en esa ubicación." |
|
|
|
|
|
texto = "🧑⚕️ **Nutriólogos Recomendados:**\n\n" |
|
|
for n in resultados: |
|
|
texto += ( |
|
|
f"**{n['nombre']}** - {n['especialidad']} " |
|
|
f"({n['ciudad']}, {n['pais']})\n📱 {n['redes']}\n💬 {n['reseña']}\n\n" |
|
|
) |
|
|
|
|
|
return texto |
|
|
|
|
|
|
|
|
def guardar_informacion(nombre, edad, peso, altura, genero, actividad, meta, condicion, alergias): |
|
|
perfil = { |
|
|
"nombre": nombre, |
|
|
"edad": edad, |
|
|
"peso": peso, |
|
|
"altura": altura, |
|
|
"genero": genero, |
|
|
"actividad": actividad, |
|
|
"meta": meta, |
|
|
"condicion": condicion, |
|
|
"alergias": alergias |
|
|
} |
|
|
with open("perfil_usuario.json", "w") as f: |
|
|
json.dump(perfil, f, indent=4) |
|
|
|
|
|
return f"✅ Información guardada.\n**Condición:** {condicion or 'ninguna'}\n**Alergias:** {alergias or 'ninguna'}" |
|
|
|
|
|
|
|
|
def main(): |
|
|
with gr.Blocks(title="NutriBot IA 🥗") as app: |
|
|
gr.Markdown("# 🧠 Bienvenido a **NutriBot IA** 🍎") |
|
|
gr.Markdown("Comer sano, inteligente y divertido.🌿") |
|
|
|
|
|
|
|
|
with gr.Tab("👤 Datos Personales"): |
|
|
with gr.Row(): |
|
|
nombre = gr.Textbox(label="Nombre completo") |
|
|
edad = gr.Number(label="Edad (años)") |
|
|
peso = gr.Number(label="Peso (kg)") |
|
|
altura = gr.Number(label="Altura (cm)") |
|
|
|
|
|
genero = gr.Radio(["Hombre", "Mujer"], label="Género") |
|
|
actividad = gr.Dropdown( |
|
|
["Sedentario", "Ligero", "Moderado", "Activo", "Muy activo"], |
|
|
label="Nivel de actividad física" |
|
|
) |
|
|
meta = gr.Radio( |
|
|
["Bajar de peso", "Mantener peso", "Subir de peso"], |
|
|
label="🎯 Meta personal" |
|
|
) |
|
|
|
|
|
condicion = gr.Textbox( |
|
|
label="🩺 Condición alimenticia o enfermedad", |
|
|
placeholder="Ejemplo: diabetes, hipertensión, intolerancia a la lactosa..." |
|
|
) |
|
|
|
|
|
alergias = gr.Textbox( |
|
|
label="🚫 Alergias alimenticias", |
|
|
placeholder="Ejemplo: maní, gluten, mariscos..." |
|
|
) |
|
|
|
|
|
guardar_datos = gr.Button("Guardar información 🧾") |
|
|
salida_datos = gr.Markdown() |
|
|
|
|
|
guardar_datos.click( |
|
|
guardar_informacion, |
|
|
inputs=[nombre, edad, peso, altura, genero, actividad, meta, condicion, alergias], |
|
|
outputs=salida_datos |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Tab("📸 Registro de Comidas"): |
|
|
gr.Markdown("Sube una foto de tu comida y NutriBot estimará las calorías 🍽️") |
|
|
imagen = gr.Image(label="Foto de tu comida", type="filepath") |
|
|
|
|
|
boton_registrar = gr.Button("Registrar comida 🍎") |
|
|
salida_foto = gr.Markdown() |
|
|
boton_registrar.click(registrar_comida, inputs=imagen, outputs=salida_foto) |
|
|
|
|
|
boton_historial = gr.Button("Ver historial 🍴") |
|
|
salida_historial = gr.Markdown() |
|
|
boton_historial.click(mostrar_historial, outputs=salida_historial) |
|
|
|
|
|
|
|
|
with gr.Tab("⌚ Calorías del Reloj"): |
|
|
calorias_quemadas = gr.Number(label="Calorías quemadas (reloj inteligente)") |
|
|
boton_reloj = gr.Button("Actualizar 🔁") |
|
|
salida_reloj = gr.Markdown() |
|
|
boton_reloj.click(calorias_reloj, inputs=calorias_quemadas, outputs=salida_reloj) |
|
|
|
|
|
|
|
|
with gr.Tab("🤖 Chat con Nuti"): |
|
|
chat_nuti = gr.Chatbot(label="Nuti - Tu guía de nutrición 🍎", type="messages") |
|
|
entrada_nuti = gr.Textbox(label="Escribe algo para Nuti...") |
|
|
boton_nuti = gr.Button("Enviar") |
|
|
boton_nuti.click(conversar_nuti, inputs=[entrada_nuti, chat_nuti], outputs=[chat_nuti, entrada_nuti]) |
|
|
|
|
|
|
|
|
with gr.Tab("🧘 Coach Emocional"): |
|
|
chat_coach = gr.Chatbot(label="Coach Emocional 🌿", type="messages") |
|
|
entrada_coach = gr.Textbox(label="Cuéntame cómo te sientes hoy...") |
|
|
boton_coach = gr.Button("Enviar") |
|
|
boton_coach.click(conversar_coach, inputs=[entrada_coach, chat_coach], outputs=[chat_coach, entrada_coach]) |
|
|
|
|
|
|
|
|
with gr.Tab("🍽️ Recetas del Nutriólogo"): |
|
|
nombre_rec = gr.Textbox(label="Nombre de la receta") |
|
|
descripcion = gr.Textbox(label="Descripción o ingredientes") |
|
|
imagen_receta = gr.Image(label="Imagen (opcional)") |
|
|
boton_subir = gr.Button("Subir receta") |
|
|
salida_subir = gr.Textbox(label="Estado") |
|
|
boton_subir.click(subir_receta, inputs=[nombre_rec, descripcion, imagen_receta], outputs=salida_subir) |
|
|
|
|
|
boton_ver = gr.Button("Ver recetas disponibles 🍲") |
|
|
salida_recetas = gr.Markdown() |
|
|
boton_ver.click(mostrar_recetas, outputs=salida_recetas) |
|
|
|
|
|
|
|
|
with gr.Tab("🎯 Retos Saludables"): |
|
|
salida_retos = gr.Markdown() |
|
|
|
|
|
boton_ver_retos = gr.Button("Ver Retos del Día") |
|
|
boton_ver_retos.click(mostrar_retos, outputs=salida_retos) |
|
|
|
|
|
numero_reto = gr.Number(label="Número de reto completado") |
|
|
boton_completar = gr.Button("Completar Reto 🏅") |
|
|
boton_completar.click(completar_reto, inputs=numero_reto, outputs=salida_retos) |
|
|
|
|
|
|
|
|
with gr.Tab("🧑⚕️ Buscar Nutriólogos"): |
|
|
pais = gr.Textbox(label="País") |
|
|
estado = gr.Textbox(label="Estado") |
|
|
ciudad = gr.Textbox(label="Ciudad") |
|
|
boton_buscar = gr.Button("Buscar Nutriólogos 🌍") |
|
|
salida_nutri = gr.Markdown() |
|
|
boton_buscar.click(buscar_nutriologos, inputs=[pais, estado, ciudad], outputs=salida_nutri) |
|
|
|
|
|
|
|
|
app.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
main() |
|
|
|