Update app.py
Browse files
app.py
CHANGED
|
@@ -19,7 +19,7 @@ def conversar_nuti(mensaje, historial):
|
|
| 19 |
MEMORIA_NUTI.append({"user": mensaje})
|
| 20 |
respuesta = buscar_respuesta(mensaje, MEMORIA_NUTI)
|
| 21 |
MEMORIA_NUTI.append({"nuti": respuesta})
|
| 22 |
-
historial
|
| 23 |
return historial, ""
|
| 24 |
|
| 25 |
# ---------- COACH EMOCIONAL ---------- #
|
|
@@ -27,12 +27,13 @@ def conversar_coach(mensaje, historial):
|
|
| 27 |
MEMORIA_COACH.append({"user": mensaje})
|
| 28 |
respuesta = coach_emocional_inteligente(mensaje, MEMORIA_COACH)
|
| 29 |
MEMORIA_COACH.append({"coach": respuesta})
|
| 30 |
-
historial
|
| 31 |
return historial, ""
|
| 32 |
|
| 33 |
# ---------- CÁLCULO DE CALORÍAS ---------- #
|
| 34 |
def calcular_calorias(edad, peso, altura, genero, actividad, meta):
|
| 35 |
global calorias_totales, calorias_restantes
|
|
|
|
| 36 |
if genero.lower() == "mujer":
|
| 37 |
bmr = 655 + (9.6 * peso) + (1.8 * altura) - (4.7 * edad)
|
| 38 |
else:
|
|
@@ -48,7 +49,6 @@ def calcular_calorias(edad, peso, altura, genero, actividad, meta):
|
|
| 48 |
|
| 49 |
calorias_base = bmr * factores.get(actividad.lower(), 1.55)
|
| 50 |
|
| 51 |
-
# Ajuste según meta
|
| 52 |
if meta.lower() == "bajar de peso":
|
| 53 |
calorias_totales = round(calorias_base * 0.8)
|
| 54 |
elif meta.lower() == "subir de peso":
|
|
@@ -69,6 +69,7 @@ def calorias_reloj(calorias_quemadas):
|
|
| 69 |
def analizar_foto(imagen):
|
| 70 |
if imagen is None:
|
| 71 |
return "⚠️ Sube una foto de tu comida.", 0
|
|
|
|
| 72 |
comidas = [
|
| 73 |
("Ensalada de pollo", 350),
|
| 74 |
("Hamburguesa con papas", 800),
|
|
@@ -86,22 +87,25 @@ def registrar_comida(imagen):
|
|
| 86 |
global calorias_restantes, historial_comidas
|
| 87 |
info, calorias = analizar_foto(imagen)
|
| 88 |
calorias_restantes -= calorias
|
| 89 |
-
|
| 90 |
-
|
| 91 |
historial_comidas.append({"comida": info, "calorias": calorias})
|
| 92 |
return f"{info}\n\n🔥 Calorías restantes del día: **{calorias_restantes} kcal**."
|
| 93 |
|
| 94 |
def mostrar_historial():
|
| 95 |
if not historial_comidas:
|
| 96 |
return "📭 Aún no has registrado comidas hoy."
|
|
|
|
| 97 |
texto = "🍴 **Historial de comidas:**\n\n"
|
| 98 |
for i, item in enumerate(historial_comidas, 1):
|
| 99 |
texto += f"{i}. {item['comida']}\n"
|
|
|
|
| 100 |
texto += f"\n🔥 Te quedan **{calorias_restantes} kcal** por consumir hoy."
|
| 101 |
return texto
|
| 102 |
|
| 103 |
# ---------- RECETAS ---------- #
|
| 104 |
RECETAS = []
|
|
|
|
| 105 |
def subir_receta(nombre, descripcion, imagen):
|
| 106 |
if nombre and descripcion:
|
| 107 |
RECETAS.append({"nombre": nombre, "descripcion": descripcion, "imagen": imagen})
|
|
@@ -111,12 +115,13 @@ def subir_receta(nombre, descripcion, imagen):
|
|
| 111 |
def mostrar_recetas():
|
| 112 |
if not RECETAS:
|
| 113 |
return "📭 No hay recetas cargadas aún."
|
|
|
|
| 114 |
texto = "🍽️ **Recetas Recomendadas:**\n\n"
|
| 115 |
for r in RECETAS:
|
| 116 |
texto += f"**{r['nombre']}**\n{r['descripcion']}\n\n"
|
| 117 |
return texto
|
| 118 |
|
| 119 |
-
# ----------
|
| 120 |
def buscar_nutriologos(pais, estado, ciudad):
|
| 121 |
ejemplos = [
|
| 122 |
{"nombre": "Dra. Sofía Martínez", "pais": "México", "estado": "Sonora", "ciudad": "Hermosillo",
|
|
@@ -126,14 +131,44 @@ def buscar_nutriologos(pais, estado, ciudad):
|
|
| 126 |
{"nombre": "Dra. Camila Silva", "pais": "Chile", "estado": "Región Metropolitana", "ciudad": "Santiago",
|
| 127 |
"especialidad": "Salud emocional", "redes": "@camila.wellness (Instagram)", "reseña": "⭐️⭐️⭐️⭐️⭐️ 5.0"}
|
| 128 |
]
|
| 129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
if not resultados:
|
| 131 |
return "❌ No se encontraron nutriólogos en esa ubicación."
|
|
|
|
| 132 |
texto = "🧑⚕️ **Nutriólogos Recomendados:**\n\n"
|
| 133 |
for n in resultados:
|
| 134 |
-
texto +=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
return texto
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
# ---------- INTERFAZ PRINCIPAL ---------- #
|
| 138 |
def main():
|
| 139 |
with gr.Blocks(title="NutriBot IA 🥗") as app:
|
|
@@ -147,32 +182,30 @@ def main():
|
|
| 147 |
edad = gr.Number(label="Edad (años)")
|
| 148 |
peso = gr.Number(label="Peso (kg)")
|
| 149 |
altura = gr.Number(label="Altura (cm)")
|
|
|
|
| 150 |
genero = gr.Radio(["Hombre", "Mujer"], label="Género")
|
| 151 |
-
actividad = gr.Dropdown(
|
| 152 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
|
| 154 |
-
condicion = gr.Textbox(
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
|
| 157 |
guardar_datos = gr.Button("Guardar información 🧾")
|
| 158 |
salida_datos = gr.Markdown()
|
| 159 |
|
| 160 |
-
def guardar_informacion(nombre, edad, peso, altura, genero, actividad, meta, condicion, alergias):
|
| 161 |
-
perfil = {
|
| 162 |
-
"nombre": nombre,
|
| 163 |
-
"edad": edad,
|
| 164 |
-
"peso": peso,
|
| 165 |
-
"altura": altura,
|
| 166 |
-
"genero": genero,
|
| 167 |
-
"actividad": actividad,
|
| 168 |
-
"meta": meta,
|
| 169 |
-
"condicion": condicion,
|
| 170 |
-
"alergias": alergias
|
| 171 |
-
}
|
| 172 |
-
with open("perfil_usuario.json", "w") as f:
|
| 173 |
-
json.dump(perfil, f, indent=4)
|
| 174 |
-
return f"✅ Información guardada.\n**Condición:** {condicion or 'ninguna'}\n**Alergias:** {alergias or 'ninguna'}"
|
| 175 |
-
|
| 176 |
guardar_datos.click(
|
| 177 |
guardar_informacion,
|
| 178 |
inputs=[nombre, edad, peso, altura, genero, actividad, meta, condicion, alergias],
|
|
@@ -183,31 +216,32 @@ def main():
|
|
| 183 |
with gr.Tab("📸 Registro de Comidas"):
|
| 184 |
gr.Markdown("Sube una foto de tu comida y NutriBot estimará las calorías 🍽️")
|
| 185 |
imagen = gr.Image(label="Foto de tu comida", type="filepath")
|
|
|
|
| 186 |
boton_registrar = gr.Button("Registrar comida 🍎")
|
| 187 |
salida_foto = gr.Markdown()
|
| 188 |
-
boton_registrar.click(registrar_comida, inputs=
|
| 189 |
|
| 190 |
boton_historial = gr.Button("Ver historial 🍴")
|
| 191 |
salida_historial = gr.Markdown()
|
| 192 |
boton_historial.click(mostrar_historial, outputs=salida_historial)
|
| 193 |
|
| 194 |
-
# --- RELOJ --- #
|
| 195 |
with gr.Tab("⌚ Calorías del Reloj"):
|
| 196 |
calorias_quemadas = gr.Number(label="Calorías quemadas (reloj inteligente)")
|
| 197 |
boton_reloj = gr.Button("Actualizar 🔁")
|
| 198 |
salida_reloj = gr.Markdown()
|
| 199 |
-
boton_reloj.click(calorias_reloj, inputs=
|
| 200 |
|
| 201 |
# --- CHAT NUTI --- #
|
| 202 |
with gr.Tab("🤖 Chat con Nuti"):
|
| 203 |
-
chat_nuti = gr.Chatbot(label="Nuti - Tu guía de nutrición 🍎")
|
| 204 |
entrada_nuti = gr.Textbox(label="Escribe algo para Nuti...")
|
| 205 |
boton_nuti = gr.Button("Enviar")
|
| 206 |
boton_nuti.click(conversar_nuti, inputs=[entrada_nuti, chat_nuti], outputs=[chat_nuti, entrada_nuti])
|
| 207 |
|
| 208 |
# --- COACH EMOCIONAL --- #
|
| 209 |
with gr.Tab("🧘 Coach Emocional"):
|
| 210 |
-
chat_coach = gr.Chatbot(label="Coach Emocional 🌿")
|
| 211 |
entrada_coach = gr.Textbox(label="Cuéntame cómo te sientes hoy...")
|
| 212 |
boton_coach = gr.Button("Enviar")
|
| 213 |
boton_coach.click(conversar_coach, inputs=[entrada_coach, chat_coach], outputs=[chat_coach, entrada_coach])
|
|
@@ -228,12 +262,13 @@ def main():
|
|
| 228 |
# --- RETOS --- #
|
| 229 |
with gr.Tab("🎯 Retos Saludables"):
|
| 230 |
salida_retos = gr.Markdown()
|
|
|
|
| 231 |
boton_ver_retos = gr.Button("Ver Retos del Día")
|
| 232 |
boton_ver_retos.click(mostrar_retos, outputs=salida_retos)
|
| 233 |
|
| 234 |
numero_reto = gr.Number(label="Número de reto completado")
|
| 235 |
boton_completar = gr.Button("Completar Reto 🏅")
|
| 236 |
-
boton_completar.click(completar_reto, inputs=
|
| 237 |
|
| 238 |
# --- NUTRIÓLOGOS --- #
|
| 239 |
with gr.Tab("🧑⚕️ Buscar Nutriólogos"):
|
|
@@ -244,7 +279,8 @@ def main():
|
|
| 244 |
salida_nutri = gr.Markdown()
|
| 245 |
boton_buscar.click(buscar_nutriologos, inputs=[pais, estado, ciudad], outputs=salida_nutri)
|
| 246 |
|
| 247 |
-
|
|
|
|
| 248 |
|
| 249 |
if __name__ == "__main__":
|
| 250 |
main()
|
|
|
|
| 19 |
MEMORIA_NUTI.append({"user": mensaje})
|
| 20 |
respuesta = buscar_respuesta(mensaje, MEMORIA_NUTI)
|
| 21 |
MEMORIA_NUTI.append({"nuti": respuesta})
|
| 22 |
+
historial.append({"role": "assistant", "content": respuesta})
|
| 23 |
return historial, ""
|
| 24 |
|
| 25 |
# ---------- COACH EMOCIONAL ---------- #
|
|
|
|
| 27 |
MEMORIA_COACH.append({"user": mensaje})
|
| 28 |
respuesta = coach_emocional_inteligente(mensaje, MEMORIA_COACH)
|
| 29 |
MEMORIA_COACH.append({"coach": respuesta})
|
| 30 |
+
historial.append({"role": "assistant", "content": respuesta})
|
| 31 |
return historial, ""
|
| 32 |
|
| 33 |
# ---------- CÁLCULO DE CALORÍAS ---------- #
|
| 34 |
def calcular_calorias(edad, peso, altura, genero, actividad, meta):
|
| 35 |
global calorias_totales, calorias_restantes
|
| 36 |
+
|
| 37 |
if genero.lower() == "mujer":
|
| 38 |
bmr = 655 + (9.6 * peso) + (1.8 * altura) - (4.7 * edad)
|
| 39 |
else:
|
|
|
|
| 49 |
|
| 50 |
calorias_base = bmr * factores.get(actividad.lower(), 1.55)
|
| 51 |
|
|
|
|
| 52 |
if meta.lower() == "bajar de peso":
|
| 53 |
calorias_totales = round(calorias_base * 0.8)
|
| 54 |
elif meta.lower() == "subir de peso":
|
|
|
|
| 69 |
def analizar_foto(imagen):
|
| 70 |
if imagen is None:
|
| 71 |
return "⚠️ Sube una foto de tu comida.", 0
|
| 72 |
+
|
| 73 |
comidas = [
|
| 74 |
("Ensalada de pollo", 350),
|
| 75 |
("Hamburguesa con papas", 800),
|
|
|
|
| 87 |
global calorias_restantes, historial_comidas
|
| 88 |
info, calorias = analizar_foto(imagen)
|
| 89 |
calorias_restantes -= calorias
|
| 90 |
+
calorias_restantes = max(calorias_restantes, 0)
|
| 91 |
+
|
| 92 |
historial_comidas.append({"comida": info, "calorias": calorias})
|
| 93 |
return f"{info}\n\n🔥 Calorías restantes del día: **{calorias_restantes} kcal**."
|
| 94 |
|
| 95 |
def mostrar_historial():
|
| 96 |
if not historial_comidas:
|
| 97 |
return "📭 Aún no has registrado comidas hoy."
|
| 98 |
+
|
| 99 |
texto = "🍴 **Historial de comidas:**\n\n"
|
| 100 |
for i, item in enumerate(historial_comidas, 1):
|
| 101 |
texto += f"{i}. {item['comida']}\n"
|
| 102 |
+
|
| 103 |
texto += f"\n🔥 Te quedan **{calorias_restantes} kcal** por consumir hoy."
|
| 104 |
return texto
|
| 105 |
|
| 106 |
# ---------- RECETAS ---------- #
|
| 107 |
RECETAS = []
|
| 108 |
+
|
| 109 |
def subir_receta(nombre, descripcion, imagen):
|
| 110 |
if nombre and descripcion:
|
| 111 |
RECETAS.append({"nombre": nombre, "descripcion": descripcion, "imagen": imagen})
|
|
|
|
| 115 |
def mostrar_recetas():
|
| 116 |
if not RECETAS:
|
| 117 |
return "📭 No hay recetas cargadas aún."
|
| 118 |
+
|
| 119 |
texto = "🍽️ **Recetas Recomendadas:**\n\n"
|
| 120 |
for r in RECETAS:
|
| 121 |
texto += f"**{r['nombre']}**\n{r['descripcion']}\n\n"
|
| 122 |
return texto
|
| 123 |
|
| 124 |
+
# ---------- BUSCAR NUTRIÓLOGOS ---------- #
|
| 125 |
def buscar_nutriologos(pais, estado, ciudad):
|
| 126 |
ejemplos = [
|
| 127 |
{"nombre": "Dra. Sofía Martínez", "pais": "México", "estado": "Sonora", "ciudad": "Hermosillo",
|
|
|
|
| 131 |
{"nombre": "Dra. Camila Silva", "pais": "Chile", "estado": "Región Metropolitana", "ciudad": "Santiago",
|
| 132 |
"especialidad": "Salud emocional", "redes": "@camila.wellness (Instagram)", "reseña": "⭐️⭐️⭐️⭐️⭐️ 5.0"}
|
| 133 |
]
|
| 134 |
+
|
| 135 |
+
resultados = [
|
| 136 |
+
n for n in ejemplos
|
| 137 |
+
if n["pais"].lower() == pais.lower()
|
| 138 |
+
or n["estado"].lower() == estado.lower()
|
| 139 |
+
or n["ciudad"].lower() == ciudad.lower()
|
| 140 |
+
]
|
| 141 |
+
|
| 142 |
if not resultados:
|
| 143 |
return "❌ No se encontraron nutriólogos en esa ubicación."
|
| 144 |
+
|
| 145 |
texto = "🧑⚕️ **Nutriólogos Recomendados:**\n\n"
|
| 146 |
for n in resultados:
|
| 147 |
+
texto += (
|
| 148 |
+
f"**{n['nombre']}** - {n['especialidad']} "
|
| 149 |
+
f"({n['ciudad']}, {n['pais']})\n📱 {n['redes']}\n💬 {n['reseña']}\n\n"
|
| 150 |
+
)
|
| 151 |
+
|
| 152 |
return texto
|
| 153 |
|
| 154 |
+
# ---------- FUNCIÓN PARA GUARDAR DATOS ---------- #
|
| 155 |
+
def guardar_informacion(nombre, edad, peso, altura, genero, actividad, meta, condicion, alergias):
|
| 156 |
+
perfil = {
|
| 157 |
+
"nombre": nombre,
|
| 158 |
+
"edad": edad,
|
| 159 |
+
"peso": peso,
|
| 160 |
+
"altura": altura,
|
| 161 |
+
"genero": genero,
|
| 162 |
+
"actividad": actividad,
|
| 163 |
+
"meta": meta,
|
| 164 |
+
"condicion": condicion,
|
| 165 |
+
"alergias": alergias
|
| 166 |
+
}
|
| 167 |
+
with open("perfil_usuario.json", "w") as f:
|
| 168 |
+
json.dump(perfil, f, indent=4)
|
| 169 |
+
|
| 170 |
+
return f"✅ Información guardada.\n**Condición:** {condicion or 'ninguna'}\n**Alergias:** {alergias or 'ninguna'}"
|
| 171 |
+
|
| 172 |
# ---------- INTERFAZ PRINCIPAL ---------- #
|
| 173 |
def main():
|
| 174 |
with gr.Blocks(title="NutriBot IA 🥗") as app:
|
|
|
|
| 182 |
edad = gr.Number(label="Edad (años)")
|
| 183 |
peso = gr.Number(label="Peso (kg)")
|
| 184 |
altura = gr.Number(label="Altura (cm)")
|
| 185 |
+
|
| 186 |
genero = gr.Radio(["Hombre", "Mujer"], label="Género")
|
| 187 |
+
actividad = gr.Dropdown(
|
| 188 |
+
["Sedentario", "Ligero", "Moderado", "Activo", "Muy activo"],
|
| 189 |
+
label="Nivel de actividad física"
|
| 190 |
+
)
|
| 191 |
+
meta = gr.Radio(
|
| 192 |
+
["Bajar de peso", "Mantener peso", "Subir de peso"],
|
| 193 |
+
label="🎯 Meta personal"
|
| 194 |
+
)
|
| 195 |
|
| 196 |
+
condicion = gr.Textbox(
|
| 197 |
+
label="🩺 Condición alimenticia o enfermedad",
|
| 198 |
+
placeholder="Ejemplo: diabetes, hipertensión, intolerancia a la lactosa..."
|
| 199 |
+
)
|
| 200 |
+
|
| 201 |
+
alergias = gr.Textbox(
|
| 202 |
+
label="🚫 Alergias alimenticias",
|
| 203 |
+
placeholder="Ejemplo: maní, gluten, mariscos..."
|
| 204 |
+
)
|
| 205 |
|
| 206 |
guardar_datos = gr.Button("Guardar información 🧾")
|
| 207 |
salida_datos = gr.Markdown()
|
| 208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
guardar_datos.click(
|
| 210 |
guardar_informacion,
|
| 211 |
inputs=[nombre, edad, peso, altura, genero, actividad, meta, condicion, alergias],
|
|
|
|
| 216 |
with gr.Tab("📸 Registro de Comidas"):
|
| 217 |
gr.Markdown("Sube una foto de tu comida y NutriBot estimará las calorías 🍽️")
|
| 218 |
imagen = gr.Image(label="Foto de tu comida", type="filepath")
|
| 219 |
+
|
| 220 |
boton_registrar = gr.Button("Registrar comida 🍎")
|
| 221 |
salida_foto = gr.Markdown()
|
| 222 |
+
boton_registrar.click(registrar_comida, inputs=imagen, outputs=salida_foto)
|
| 223 |
|
| 224 |
boton_historial = gr.Button("Ver historial 🍴")
|
| 225 |
salida_historial = gr.Markdown()
|
| 226 |
boton_historial.click(mostrar_historial, outputs=salida_historial)
|
| 227 |
|
| 228 |
+
# --- CALORÍAS DEL RELOJ --- #
|
| 229 |
with gr.Tab("⌚ Calorías del Reloj"):
|
| 230 |
calorias_quemadas = gr.Number(label="Calorías quemadas (reloj inteligente)")
|
| 231 |
boton_reloj = gr.Button("Actualizar 🔁")
|
| 232 |
salida_reloj = gr.Markdown()
|
| 233 |
+
boton_reloj.click(calorias_reloj, inputs=calorias_quemadas, outputs=salida_reloj)
|
| 234 |
|
| 235 |
# --- CHAT NUTI --- #
|
| 236 |
with gr.Tab("🤖 Chat con Nuti"):
|
| 237 |
+
chat_nuti = gr.Chatbot(label="Nuti - Tu guía de nutrición 🍎", type="messages")
|
| 238 |
entrada_nuti = gr.Textbox(label="Escribe algo para Nuti...")
|
| 239 |
boton_nuti = gr.Button("Enviar")
|
| 240 |
boton_nuti.click(conversar_nuti, inputs=[entrada_nuti, chat_nuti], outputs=[chat_nuti, entrada_nuti])
|
| 241 |
|
| 242 |
# --- COACH EMOCIONAL --- #
|
| 243 |
with gr.Tab("🧘 Coach Emocional"):
|
| 244 |
+
chat_coach = gr.Chatbot(label="Coach Emocional 🌿", type="messages")
|
| 245 |
entrada_coach = gr.Textbox(label="Cuéntame cómo te sientes hoy...")
|
| 246 |
boton_coach = gr.Button("Enviar")
|
| 247 |
boton_coach.click(conversar_coach, inputs=[entrada_coach, chat_coach], outputs=[chat_coach, entrada_coach])
|
|
|
|
| 262 |
# --- RETOS --- #
|
| 263 |
with gr.Tab("🎯 Retos Saludables"):
|
| 264 |
salida_retos = gr.Markdown()
|
| 265 |
+
|
| 266 |
boton_ver_retos = gr.Button("Ver Retos del Día")
|
| 267 |
boton_ver_retos.click(mostrar_retos, outputs=salida_retos)
|
| 268 |
|
| 269 |
numero_reto = gr.Number(label="Número de reto completado")
|
| 270 |
boton_completar = gr.Button("Completar Reto 🏅")
|
| 271 |
+
boton_completar.click(completar_reto, inputs=numero_reto, outputs=salida_retos)
|
| 272 |
|
| 273 |
# --- NUTRIÓLOGOS --- #
|
| 274 |
with gr.Tab("🧑⚕️ Buscar Nutriólogos"):
|
|
|
|
| 279 |
salida_nutri = gr.Markdown()
|
| 280 |
boton_buscar.click(buscar_nutriologos, inputs=[pais, estado, ciudad], outputs=salida_nutri)
|
| 281 |
|
| 282 |
+
# LÍNEA IMPORTANTE: NO USAR SSR
|
| 283 |
+
app.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False)
|
| 284 |
|
| 285 |
if __name__ == "__main__":
|
| 286 |
main()
|