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 ---------- # MEMORIA_NUTI = [] MEMORIA_COACH = [] calorias_totales = 0 calorias_restantes = 0 historial_comidas = [] # ---------- CHATBOT NUTI ---------- # 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, "" # ---------- COACH EMOCIONAL ---------- # 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, "" # ---------- CÁLCULO DE CALORÍAS ---------- # 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**." # ---------- CALORÍAS DEL RELOJ ---------- # 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." # ---------- FOTO DE COMIDA ---------- # 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 ---------- # 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 # ---------- BUSCAR NUTRIÓLOGOS ---------- # 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 # ---------- FUNCIÓN PARA GUARDAR DATOS ---------- # 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'}" # ---------- INTERFAZ PRINCIPAL ---------- # def main(): with gr.Blocks(title="NutriBot IA 🥗") as app: gr.Markdown("# 🧠 Bienvenido a **NutriBot IA** 🍎") gr.Markdown("Comer sano, inteligente y divertido.🌿") # --- DATOS PERSONALES --- # 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 ) # --- REGISTRO DE COMIDAS --- # 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) # --- CALORÍAS DEL RELOJ --- # 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) # --- CHAT NUTI --- # 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]) # --- COACH EMOCIONAL --- # 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]) # --- RECETAS --- # 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) # --- RETOS --- # 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) # --- NUTRIÓLOGOS --- # 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) # LÍNEA IMPORTANTE: NO USAR SSR app.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False) if __name__ == "__main__": main()