Spaces:
Sleeping
Sleeping
Commit
·
c668a5a
1
Parent(s):
e5a882c
- __pycache__/app.cpython-312.pyc +0 -0
- __pycache__/nutrition.cpython-312.pyc +0 -0
- app.py +97 -61
__pycache__/app.cpython-312.pyc
ADDED
|
Binary file (40.4 kB). View file
|
|
|
__pycache__/nutrition.cpython-312.pyc
ADDED
|
Binary file (18.5 kB). View file
|
|
|
app.py
CHANGED
|
@@ -113,54 +113,48 @@ concept_keywords = {
|
|
| 113 |
# Grupos musculares (keywords)
|
| 114 |
# -------------------------
|
| 115 |
muscle_keywords = {
|
| 116 |
-
|
| 117 |
-
"pernas": ["perna", "pernas", "inferiores", "lower body", "treino inferior"],
|
| 118 |
"quadriceps": ["quadriceps", "quads", "coxa da frente", "frontal da coxa"],
|
| 119 |
"posterior_de_coxa": ["posterior", "posterior de coxa", "isquiotibiais", "hamstrings"],
|
| 120 |
-
"gluteo": ["gluteo", "
|
| 121 |
-
"panturrilhas": ["panturrilha", "panturrilhas", "batata da perna", "
|
| 122 |
|
| 123 |
-
|
| 124 |
-
"
|
| 125 |
"lombar": ["lombar", "parte baixa das costas", "erectores", "eretores da espinha"],
|
| 126 |
-
"trapezio": ["trapezio", "
|
| 127 |
|
| 128 |
-
# 🔹 Peito
|
| 129 |
"peito": ["peito", "peitoral", "chest"],
|
| 130 |
|
| 131 |
-
|
| 132 |
-
"
|
| 133 |
-
"
|
| 134 |
-
"
|
| 135 |
-
"antebraco": ["antebraco", "antebraço", "antebracos", "antebraços", "forearm"],
|
| 136 |
|
| 137 |
-
# 🔹 Ombros
|
| 138 |
"ombro": ["ombro", "ombros", "deltoide", "deltoides", "shoulder"],
|
| 139 |
|
| 140 |
-
# 🔹 Abdômen e core
|
| 141 |
"abdomen": ["abdomen", "abdominal", "reto abdominal", "abs"],
|
| 142 |
-
"
|
| 143 |
"core": ["core", "centro do corpo", "estabilizadores"],
|
| 144 |
|
| 145 |
-
# 🔹 Superiores
|
| 146 |
"superiores": ["superior", "superiores", "upper body", "treino superior"],
|
| 147 |
|
| 148 |
"puxar": ["puxar", "puxada", "puxadas", "pull"],
|
| 149 |
"empurrar": ["empurrar", "empurrada", "empurradas", "push"],
|
| 150 |
-
|
| 151 |
}
|
| 152 |
|
| 153 |
|
| 154 |
# Expansão de grupos compostos
|
| 155 |
group_hierarchy = {
|
| 156 |
"pernas": ["quadriceps", "posterior_de_coxa", "gluteo", "panturrilhas"],
|
| 157 |
-
"costas": ["lombar", "trapezio",
|
| 158 |
"superiores": ["peito", "dorsal", "trapezio", "biceps", "triceps", "ombro", "antebraco"],
|
| 159 |
"bracos": ["biceps", "triceps", "antebraco"],
|
| 160 |
-
"puxar": ["biceps", "
|
| 161 |
-
"empurrar": ["triceps", "peito", "ombro"
|
| 162 |
}
|
| 163 |
|
|
|
|
| 164 |
# -------------------------
|
| 165 |
# Lesões (keywords)
|
| 166 |
# -------------------------
|
|
@@ -391,57 +385,92 @@ def detectar_conceitos(prompt: str):
|
|
| 391 |
|
| 392 |
|
| 393 |
def detectar_musculos(texto: str) -> list[str]:
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
# 1️⃣ Identificar palavras-chave
|
| 398 |
-
for musculo, termos in muscle_keywords.items():
|
| 399 |
-
for termo in termos:
|
| 400 |
-
if termo in texto:
|
| 401 |
-
detectados.add(musculo)
|
| 402 |
|
| 403 |
-
|
| 404 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 405 |
for grupo, subgrupos in group_hierarchy.items():
|
| 406 |
-
if grupo in
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
for grupo, subgrupos in group_hierarchy.items():
|
| 413 |
-
if grupo in
|
| 414 |
-
|
| 415 |
|
| 416 |
-
|
|
|
|
| 417 |
|
| 418 |
# -------------------------
|
| 419 |
# Objetivos (keywords)
|
| 420 |
# -------------------------
|
| 421 |
objetivo_keywords = {
|
| 422 |
-
"hipertrofia": [
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
}
|
| 427 |
def detectar_objetivos(texto: str) -> list[str]:
|
| 428 |
-
|
|
|
|
|
|
|
|
|
|
| 429 |
objetivos_detectados = []
|
| 430 |
for objetivo, termos in objetivo_keywords.items():
|
| 431 |
for termo in termos:
|
| 432 |
-
|
|
|
|
| 433 |
objetivos_detectados.append(objetivo)
|
| 434 |
break
|
| 435 |
if not objetivos_detectados:
|
| 436 |
-
return ["hipertrofia"]
|
| 437 |
-
return objetivos_detectados
|
| 438 |
-
|
| 439 |
-
texto = texto.lower()
|
| 440 |
-
for objetivo, termos in objetivo_keywords.items():
|
| 441 |
-
for termo in termos:
|
| 442 |
-
if termo in texto:
|
| 443 |
-
return objetivo
|
| 444 |
-
return "hipertrofia" # padrão se nada for detectado
|
| 445 |
|
| 446 |
|
| 447 |
def detectar_intencao(prompt_norm: str, musculos_detectados: list[str]):
|
|
@@ -450,19 +479,27 @@ def detectar_intencao(prompt_norm: str, musculos_detectados: list[str]):
|
|
| 450 |
("split", dias) -> se detectar pedido de divisão semanal
|
| 451 |
("isolado", musculos) -> se detectar treino de músculos específicos
|
| 452 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 453 |
|
| 454 |
# 🔹 Detectar split (nº de dias por semana)
|
| 455 |
-
padrao_split = re.search(
|
|
|
|
|
|
|
| 456 |
if padrao_split:
|
| 457 |
dias = int(padrao_split.group(1))
|
| 458 |
-
|
|
|
|
| 459 |
|
| 460 |
-
# 🔹 Detectar treino isolado (músculos)
|
| 461 |
if musculos_detectados:
|
| 462 |
return "isolado", musculos_detectados
|
| 463 |
|
| 464 |
-
# 🔹 Default → treino full body
|
| 465 |
-
|
|
|
|
| 466 |
|
| 467 |
|
| 468 |
|
|
@@ -959,7 +996,6 @@ def responder(prompt: str):
|
|
| 959 |
# 🚀 TREINO
|
| 960 |
if any(c["tipo"] == "treino" and c.get("score", 0) >= 0.5 for c in conceitos):
|
| 961 |
musculos_alvo = detectar_musculos(prompt_norm)
|
| 962 |
-
# lesoes = detectar_lesoes(prompt_norm)
|
| 963 |
objetivos = detectar_objetivos(prompt_norm)
|
| 964 |
tipo, dados = detectar_intencao(prompt_norm, musculos_alvo)
|
| 965 |
|
|
|
|
| 113 |
# Grupos musculares (keywords)
|
| 114 |
# -------------------------
|
| 115 |
muscle_keywords = {
|
| 116 |
+
"pernas": ["perna", "pernas", "inferiores", "lower body", "treino inferior", "leg day", "legday", "leg"],
|
|
|
|
| 117 |
"quadriceps": ["quadriceps", "quads", "coxa da frente", "frontal da coxa"],
|
| 118 |
"posterior_de_coxa": ["posterior", "posterior de coxa", "isquiotibiais", "hamstrings"],
|
| 119 |
+
"gluteo": ["gluteo", "gluteos", "bumbum", "gluteus"],
|
| 120 |
+
"panturrilhas": ["panturrilha", "panturrilhas", "batata da perna", "gastrocnemio", "soleo"],
|
| 121 |
|
| 122 |
+
"costas": ["costas", "costa"],
|
| 123 |
+
"dorsal": ["dorsal", "latissimo", "lats", "latissimus", "latissimus dorsi", "dorso"],
|
| 124 |
"lombar": ["lombar", "parte baixa das costas", "erectores", "eretores da espinha"],
|
| 125 |
+
"trapezio": ["trapezio", "trapezio", "pescoço largo"],
|
| 126 |
|
|
|
|
| 127 |
"peito": ["peito", "peitoral", "chest"],
|
| 128 |
|
| 129 |
+
"bracos": ["braco", "braco", "bracos", "braços", "arm", "arms", "treino de bracos", "treino de braços"],
|
| 130 |
+
"biceps": ["biceps", "biceps", "bíceps"],
|
| 131 |
+
"triceps": ["triceps", "triceps", "tríceps"],
|
| 132 |
+
"antebraco": ["antebraco", "antebraco", "antebracos", "antebraços", "forearm"],
|
|
|
|
| 133 |
|
|
|
|
| 134 |
"ombro": ["ombro", "ombros", "deltoide", "deltoides", "shoulder"],
|
| 135 |
|
|
|
|
| 136 |
"abdomen": ["abdomen", "abdominal", "reto abdominal", "abs"],
|
| 137 |
+
"obliquos": ["obliquos", "obliquo", "obliquo"],
|
| 138 |
"core": ["core", "centro do corpo", "estabilizadores"],
|
| 139 |
|
|
|
|
| 140 |
"superiores": ["superior", "superiores", "upper body", "treino superior"],
|
| 141 |
|
| 142 |
"puxar": ["puxar", "puxada", "puxadas", "pull"],
|
| 143 |
"empurrar": ["empurrar", "empurrada", "empurradas", "push"],
|
|
|
|
| 144 |
}
|
| 145 |
|
| 146 |
|
| 147 |
# Expansão de grupos compostos
|
| 148 |
group_hierarchy = {
|
| 149 |
"pernas": ["quadriceps", "posterior_de_coxa", "gluteo", "panturrilhas"],
|
| 150 |
+
"costas": ["lombar", "trapezio","dorsal"],
|
| 151 |
"superiores": ["peito", "dorsal", "trapezio", "biceps", "triceps", "ombro", "antebraco"],
|
| 152 |
"bracos": ["biceps", "triceps", "antebraco"],
|
| 153 |
+
"puxar": ["biceps", "dorsal", "lombar", "trapezio", "antebraco"],
|
| 154 |
+
"empurrar": ["triceps", "peito", "ombro"]
|
| 155 |
}
|
| 156 |
|
| 157 |
+
|
| 158 |
# -------------------------
|
| 159 |
# Lesões (keywords)
|
| 160 |
# -------------------------
|
|
|
|
| 385 |
|
| 386 |
|
| 387 |
def detectar_musculos(texto: str) -> list[str]:
|
| 388 |
+
if not texto:
|
| 389 |
+
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
|
| 391 |
+
texto_norm = normalize_text(texto)
|
| 392 |
+
|
| 393 |
+
# build term -> list(muscle_key)
|
| 394 |
+
term_map = {}
|
| 395 |
+
for muscle_key, terms in muscle_keywords.items():
|
| 396 |
+
for t in terms:
|
| 397 |
+
tn = normalize_text(t)
|
| 398 |
+
term_map.setdefault(tn, []).append(muscle_key)
|
| 399 |
+
|
| 400 |
+
# sort terms by length desc to prefer multiword matches first
|
| 401 |
+
sorted_terms = sorted(term_map.items(), key=lambda x: len(x[0]), reverse=True)
|
| 402 |
+
|
| 403 |
+
detected = set()
|
| 404 |
+
for term, muscles_for_term in sorted_terms:
|
| 405 |
+
# use word-boundary-aware search for the term (term may contain spaces)
|
| 406 |
+
pattern = r"\b" + re.escape(term) + r"\b"
|
| 407 |
+
if re.search(pattern, texto_norm):
|
| 408 |
+
for m in muscles_for_term:
|
| 409 |
+
detected.add(m)
|
| 410 |
+
|
| 411 |
+
# Expansão: se um grupo composto detectado, substitui pelo(s) subgrupo(s)
|
| 412 |
+
# (somente adiciona subgrupos que existem como chaves em muscle_keywords)
|
| 413 |
+
expanded = set()
|
| 414 |
for grupo, subgrupos in group_hierarchy.items():
|
| 415 |
+
if grupo in detected:
|
| 416 |
+
# remove the group and add each subgrupo if it's a known muscle key
|
| 417 |
+
# (defensive: only add subgroups that appear in muscle_keywords)
|
| 418 |
+
for s in subgrupos:
|
| 419 |
+
if s in muscle_keywords:
|
| 420 |
+
expanded.add(s)
|
| 421 |
+
# don't add the original group
|
| 422 |
+
detected.discard(grupo)
|
| 423 |
+
|
| 424 |
+
detected.update(expanded)
|
| 425 |
+
|
| 426 |
+
# Hierarquia reversa: se um grupo e seus subgrupos estiverem presentes, priorizar subgrupos
|
| 427 |
for grupo, subgrupos in group_hierarchy.items():
|
| 428 |
+
if grupo in detected and any(s in detected for s in subgrupos):
|
| 429 |
+
detected.discard(grupo)
|
| 430 |
|
| 431 |
+
# retorno ordenado para testes determinísticos
|
| 432 |
+
return sorted(detected)
|
| 433 |
|
| 434 |
# -------------------------
|
| 435 |
# Objetivos (keywords)
|
| 436 |
# -------------------------
|
| 437 |
objetivo_keywords = {
|
| 438 |
+
"hipertrofia": [
|
| 439 |
+
"hipertrofia", "massa", "crescimento muscular", "ganhar tamanho",
|
| 440 |
+
"volume", "aumentar músculos", "ficar maior", "crescer",
|
| 441 |
+
"ganhar corpo", "musculação", "muscle growth"
|
| 442 |
+
],
|
| 443 |
+
"forca": [
|
| 444 |
+
"força", "forca", "powerlifting", "power", "pesado", "ganhar força",
|
| 445 |
+
"melhorar força", "ficar mais forte", "maximo", "1rm", "força máxima",
|
| 446 |
+
"força bruta", "strength", "strong", "stronger"
|
| 447 |
+
],
|
| 448 |
+
"condicionamento": [
|
| 449 |
+
"resistência", "resistencia", "condicionamento", "endurance",
|
| 450 |
+
"cardio", "alta repeticao", "repetições altas", "definição",
|
| 451 |
+
"tonificar", "cutting", "resistente", "leve"
|
| 452 |
+
],
|
| 453 |
+
"explosividade": [
|
| 454 |
+
"explosivo", "explosividade", "pliometria", "saltar", "sprints",
|
| 455 |
+
"potência", "potencia", "explosão", "velocidade", "agilidade", "power",
|
| 456 |
+
"rápido", "rapido", "quickness", "potente"
|
| 457 |
+
],
|
| 458 |
}
|
| 459 |
def detectar_objetivos(texto: str) -> list[str]:
|
| 460 |
+
if not texto:
|
| 461 |
+
return ["hipertrofia"]
|
| 462 |
+
|
| 463 |
+
texto = normalize_text(texto)
|
| 464 |
objetivos_detectados = []
|
| 465 |
for objetivo, termos in objetivo_keywords.items():
|
| 466 |
for termo in termos:
|
| 467 |
+
termo_norm = normalize_text(termo)
|
| 468 |
+
if termo_norm in texto:
|
| 469 |
objetivos_detectados.append(objetivo)
|
| 470 |
break
|
| 471 |
if not objetivos_detectados:
|
| 472 |
+
return ["hipertrofia"]
|
| 473 |
+
return sorted(set(objetivos_detectados))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 474 |
|
| 475 |
|
| 476 |
def detectar_intencao(prompt_norm: str, musculos_detectados: list[str]):
|
|
|
|
| 479 |
("split", dias) -> se detectar pedido de divisão semanal
|
| 480 |
("isolado", musculos) -> se detectar treino de músculos específicos
|
| 481 |
"""
|
| 482 |
+
if not prompt_norm:
|
| 483 |
+
prompt_norm = ""
|
| 484 |
+
|
| 485 |
+
texto = normalize_text(prompt_norm)
|
| 486 |
|
| 487 |
# 🔹 Detectar split (nº de dias por semana)
|
| 488 |
+
padrao_split = re.search(
|
| 489 |
+
r"\b(\d+)\s*(x|vezes|dias)(\s*(por|na|em)?\s*(semana|semanais)?)?\b", texto
|
| 490 |
+
)
|
| 491 |
if padrao_split:
|
| 492 |
dias = int(padrao_split.group(1))
|
| 493 |
+
if 1 <= dias <= 7: # ignora números como 20, 30 etc.
|
| 494 |
+
return "split", dias
|
| 495 |
|
| 496 |
+
# 🔹 Detectar treino isolado (músculos específicos)
|
| 497 |
if musculos_detectados:
|
| 498 |
return "isolado", musculos_detectados
|
| 499 |
|
| 500 |
+
# 🔹 Default → treino full body
|
| 501 |
+
full_body = ["peito", "costas", "ombro", "biceps", "triceps", "pernas", "core"]
|
| 502 |
+
return "isolado", full_body
|
| 503 |
|
| 504 |
|
| 505 |
|
|
|
|
| 996 |
# 🚀 TREINO
|
| 997 |
if any(c["tipo"] == "treino" and c.get("score", 0) >= 0.5 for c in conceitos):
|
| 998 |
musculos_alvo = detectar_musculos(prompt_norm)
|
|
|
|
| 999 |
objetivos = detectar_objetivos(prompt_norm)
|
| 1000 |
tipo, dados = detectar_intencao(prompt_norm, musculos_alvo)
|
| 1001 |
|