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()