Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -100,24 +100,46 @@ def load_data():
|
|
| 100 |
return None, None
|
| 101 |
alimentos_data, lista_condiciones = load_data()
|
| 102 |
|
|
|
|
| 103 |
FOOD_TO_COMPOUND_MAP = {
|
| 104 |
-
#
|
| 105 |
"pan": ["gluten"], "trigo": ["gluten"], "harina de trigo": ["gluten"], "cebada": ["gluten"],
|
| 106 |
"centeno": ["gluten"], "pasta": ["gluten"], "galletas": ["gluten"], "avena": ["gluten"], "pizza": ["gluten"], "torta": ["gluten"],
|
|
|
|
| 107 |
"leche": ["lácteos", "caseína", "lactosa"], "queso": ["lácteos", "caseína", "lactosa", "histamina", "tiramina"],
|
| 108 |
"yogur": ["lácteos", "caseína", "lactosa"], "mantequilla": ["lácteos", "caseína", "lactosa"], "crema": ["lácteos"], "helado": ["lácteos"],
|
| 109 |
-
|
| 110 |
-
"
|
|
|
|
|
|
|
| 111 |
"azucar": ["azúcar", "fructosa"], "dulces": ["azúcar"], "refrescos": ["azúcar", "fructosa"], "gaseosas": ["azúcar", "fructosa"],
|
| 112 |
-
"miel": ["fructosa"], "jarabe de maiz": ["fructosa"],
|
|
|
|
| 113 |
"vino tinto": ["histamina", "tiramina", "sulfitos"], "vino rojo": ["histamina", "tiramina", "sulfitos"],
|
| 114 |
-
"cerveza": ["histamina", "tiramina", "purinas"], "chocolate": ["cafeína", "tiramina", "níquel"],
|
| 115 |
-
"embutidos": ["histamina", "tiramina", "nitritos"], "pescado enlatado": ["histamina"], "tomate": ["histamina", "solaninas"],
|
|
|
|
|
|
|
|
|
|
| 116 |
"carne": ["alfa-gal", "proteínas", "purinas", "hierro"], "carnes rojas": ["purinas", "alfa-gal", "hierro"],
|
| 117 |
"mariscos": ["purinas", "sulfitos", "alérgenos", "yodo"], "huevo": ["alérgenos"], "soya": ["alérgenos"],
|
| 118 |
-
"café": ["cafeína", "ácidos"]
|
| 119 |
}
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
# --- LÓGICA DE BÚSQUEDA Y ANÁLISIS ---
|
| 122 |
|
| 123 |
# ... (La función extract_and_infer_with_gemini no cambia) ...
|
|
@@ -149,13 +171,13 @@ def extract_and_infer_with_gemini(query, condiciones):
|
|
| 149 |
# --- FUNCIÓN DE BÚSQUEDA MODIFICADA ---
|
| 150 |
def find_best_matches_hybrid(entities, data):
|
| 151 |
"""
|
| 152 |
-
Motor de búsqueda híbrido (v4.
|
| 153 |
"""
|
| 154 |
if not entities or not data: return []
|
| 155 |
|
| 156 |
user_symptoms = set(s.lower().strip() for s in entities.get("sintomas", []))
|
| 157 |
user_foods = set(f.lower().strip() for f in entities.get("alimentos", []))
|
| 158 |
-
|
| 159 |
|
| 160 |
candidate_terms = set(user_foods)
|
| 161 |
for food in user_foods:
|
|
@@ -166,17 +188,23 @@ def find_best_matches_hybrid(entities, data):
|
|
| 166 |
for index, entry in enumerate(data):
|
| 167 |
score_details = {'condition': 0, 'food': 0, 'symptoms': 0, 'total': 0}
|
| 168 |
|
| 169 |
-
#
|
| 170 |
entry_condition = entry.get("condicion_asociada", "").lower().strip()
|
| 171 |
-
|
|
|
|
|
|
|
| 172 |
score_details['condition'] = 100
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
|
| 174 |
-
#
|
| 175 |
entry_compounds_text = entry.get("compuesto_alimento", "").lower()
|
| 176 |
if any(term in entry_compounds_text for term in candidate_terms):
|
| 177 |
score_details['food'] = 20
|
| 178 |
|
| 179 |
-
#
|
| 180 |
entry_symptoms_keys = set(s.lower().strip() for s in entry.get("sintomas_clave", []))
|
| 181 |
symptom_score = 0
|
| 182 |
for user_symptom in user_symptoms:
|
|
@@ -193,7 +221,6 @@ def find_best_matches_hybrid(entities, data):
|
|
| 193 |
|
| 194 |
if not results: return []
|
| 195 |
|
| 196 |
-
# Ordenar por puntuación total descendente
|
| 197 |
sorted_results = sorted(results, key=lambda x: x['score']['total'], reverse=True)
|
| 198 |
return sorted_results
|
| 199 |
|
|
|
|
| 100 |
return None, None
|
| 101 |
alimentos_data, lista_condiciones = load_data()
|
| 102 |
|
| 103 |
+
# DICCIONARIO DE TRADUCCIÓN AMPLIADO (v3.1)
|
| 104 |
FOOD_TO_COMPOUND_MAP = {
|
| 105 |
+
# Gluten
|
| 106 |
"pan": ["gluten"], "trigo": ["gluten"], "harina de trigo": ["gluten"], "cebada": ["gluten"],
|
| 107 |
"centeno": ["gluten"], "pasta": ["gluten"], "galletas": ["gluten"], "avena": ["gluten"], "pizza": ["gluten"], "torta": ["gluten"],
|
| 108 |
+
# Lácteos
|
| 109 |
"leche": ["lácteos", "caseína", "lactosa"], "queso": ["lácteos", "caseína", "lactosa", "histamina", "tiramina"],
|
| 110 |
"yogur": ["lácteos", "caseína", "lactosa"], "mantequilla": ["lácteos", "caseína", "lactosa"], "crema": ["lácteos"], "helado": ["lácteos"],
|
| 111 |
+
# Fenoles y Salicilatos
|
| 112 |
+
"manzana": ["salicilatos", "fructosa"], "almendras": ["salicilatos", "arginina"], "uvas": ["salicilatos"], "pasas": ["salicilatos"],
|
| 113 |
+
"naranja": ["salicilatos"], "brócoli": ["salicilatos", "goitrógenos", "fodmaps"], "cúrcuma": ["salicilatos"],
|
| 114 |
+
# Azúcares y Fructosa
|
| 115 |
"azucar": ["azúcar", "fructosa"], "dulces": ["azúcar"], "refrescos": ["azúcar", "fructosa"], "gaseosas": ["azúcar", "fructosa"],
|
| 116 |
+
"miel": ["fructosa", "fodmaps"], "jarabe de maiz": ["fructosa"],
|
| 117 |
+
# Aminas (Histamina, Tiramina)
|
| 118 |
"vino tinto": ["histamina", "tiramina", "sulfitos"], "vino rojo": ["histamina", "tiramina", "sulfitos"],
|
| 119 |
+
"cerveza": ["histamina", "tiramina", "purinas", "gluten"], "chocolate": ["cafeína", "tiramina", "níquel", "arginina"],
|
| 120 |
+
"embutidos": ["histamina", "tiramina", "nitritos"], "pescado enlatado": ["histamina"], "tomate": ["histamina", "solaninas", "ácidos"],
|
| 121 |
+
# FODMAPs
|
| 122 |
+
"aguacate": ["fodmaps", "polioles"], "cebolla": ["fodmaps"], "ajo": ["fodmaps"], "legumbres": ["fodmaps", "gos"],
|
| 123 |
+
# Otros
|
| 124 |
"carne": ["alfa-gal", "proteínas", "purinas", "hierro"], "carnes rojas": ["purinas", "alfa-gal", "hierro"],
|
| 125 |
"mariscos": ["purinas", "sulfitos", "alérgenos", "yodo"], "huevo": ["alérgenos"], "soya": ["alérgenos"],
|
| 126 |
+
"café": ["cafeína", "ácidos"], "nueces": ["arginina", "salicilatos", "níquel"]
|
| 127 |
}
|
| 128 |
|
| 129 |
+
# NUEVO DICCIONARIO DE SINÓNIMOS DE CONDICIONES
|
| 130 |
+
CONDITION_SYNONYMS = {
|
| 131 |
+
"síndrome del intestino irritable (sii).": [
|
| 132 |
+
"intolerancia a los fodmaps",
|
| 133 |
+
"intolerancia a los gos (fodmap)",
|
| 134 |
+
"intolerancia a gomas fermentables"
|
| 135 |
+
],
|
| 136 |
+
"gota / hiperuricemia.": ["acido urico aumentado"],
|
| 137 |
+
"intolerancia a la lactosa.": ["déficit de lactasa"],
|
| 138 |
+
"enfermedad celíaca (clásica).": ["dermatitis herpetiforme"]
|
| 139 |
+
# Puedes añadir más sinónimos aquí en el futuro
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
|
| 143 |
# --- LÓGICA DE BÚSQUEDA Y ANÁLISIS ---
|
| 144 |
|
| 145 |
# ... (La función extract_and_infer_with_gemini no cambia) ...
|
|
|
|
| 171 |
# --- FUNCIÓN DE BÚSQUEDA MODIFICADA ---
|
| 172 |
def find_best_matches_hybrid(entities, data):
|
| 173 |
"""
|
| 174 |
+
Motor de búsqueda híbrido (v4.1) con manejo de sinónimos de condiciones.
|
| 175 |
"""
|
| 176 |
if not entities or not data: return []
|
| 177 |
|
| 178 |
user_symptoms = set(s.lower().strip() for s in entities.get("sintomas", []))
|
| 179 |
user_foods = set(f.lower().strip() for f in entities.get("alimentos", []))
|
| 180 |
+
inferred_condition_raw = entities.get("condicion_probable", "").lower().strip()
|
| 181 |
|
| 182 |
candidate_terms = set(user_foods)
|
| 183 |
for food in user_foods:
|
|
|
|
| 188 |
for index, entry in enumerate(data):
|
| 189 |
score_details = {'condition': 0, 'food': 0, 'symptoms': 0, 'total': 0}
|
| 190 |
|
| 191 |
+
# --- PONDERACIÓN 1: COINCIDENCIA DE CONDICIÓN (CON SINÓNIMOS) ---
|
| 192 |
entry_condition = entry.get("condicion_asociada", "").lower().strip()
|
| 193 |
+
|
| 194 |
+
# Comprobación directa
|
| 195 |
+
if inferred_condition_raw and inferred_condition_raw == entry_condition:
|
| 196 |
score_details['condition'] = 100
|
| 197 |
+
# Comprobación de sinónimos
|
| 198 |
+
elif inferred_condition_raw and entry_condition in CONDITION_SYNONYMS:
|
| 199 |
+
if inferred_condition_raw in CONDITION_SYNONYMS[entry_condition]:
|
| 200 |
+
score_details['condition'] = 100
|
| 201 |
|
| 202 |
+
# --- PONDERACIÓN 2: COINCIDENCIA DE ALIMENTOS/COMPUESTOS ---
|
| 203 |
entry_compounds_text = entry.get("compuesto_alimento", "").lower()
|
| 204 |
if any(term in entry_compounds_text for term in candidate_terms):
|
| 205 |
score_details['food'] = 20
|
| 206 |
|
| 207 |
+
# --- PONDERACIÓN 3: COINCIDENCIA DE SÍNTOMAS ---
|
| 208 |
entry_symptoms_keys = set(s.lower().strip() for s in entry.get("sintomas_clave", []))
|
| 209 |
symptom_score = 0
|
| 210 |
for user_symptom in user_symptoms:
|
|
|
|
| 221 |
|
| 222 |
if not results: return []
|
| 223 |
|
|
|
|
| 224 |
sorted_results = sorted(results, key=lambda x: x['score']['total'], reverse=True)
|
| 225 |
return sorted_results
|
| 226 |
|