File size: 11,454 Bytes
eefea9b 18cab6d 52cc649 65c10eb 47f4dac a23c643 64d1fad ce4abf9 a2eb07f 6c068b1 18cab6d ce4abf9 4c795ba ce4abf9 4c795ba ce4abf9 bc45b1a 6c068b1 4c795ba ce4abf9 e8df581 ce4abf9 18cab6d ce4abf9 bc45b1a 6c068b1 bc45b1a 64d1fad 6c068b1 64d1fad 52cc649 64d1fad 6c068b1 52cc649 4c795ba 6c068b1 4c795ba 6c068b1 4c795ba 6c068b1 4c795ba 6c068b1 18cab6d 6c068b1 64d1fad 4c795ba 18cab6d 6c068b1 18cab6d 6c068b1 18cab6d 6c068b1 4c795ba 18cab6d 4c795ba 18cab6d 64d1fad 18cab6d 4c795ba 18cab6d 6c068b1 4c795ba 18cab6d 4c795ba 18cab6d 4c795ba 64d1fad ce4abf9 6c068b1 64d1fad 52cc649 64d1fad 52cc649 4c795ba 52cc649 4c795ba 52cc649 4c795ba 52cc649 64d1fad 52cc649 64d1fad 6c068b1 4c795ba 6c068b1 4c795ba 6c068b1 4c795ba 6c068b1 18cab6d 4c795ba 65c10eb 64d1fad 65c10eb 4c795ba ce4abf9 65c10eb ce4abf9 65c10eb 64d1fad 65c10eb 4c795ba 65c10eb ce4abf9 65c10eb 64d1fad 18cab6d 64d1fad 18cab6d 6c068b1 18cab6d 64d1fad 18cab6d 64d1fad 47f4dac 4c795ba 47f4dac 4c795ba 47f4dac 64d1fad 18cab6d 6c068b1 18cab6d 4c795ba 52cc649 65c10eb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
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()
|