MarvinRoque commited on
Commit
c668a5a
·
1 Parent(s): e5a882c
__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
- # 🔹 Pernas e subgrupos
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", "glúteos", "bumbum", "gluteus"],
121
- "panturrilhas": ["panturrilha", "panturrilhas", "batata da perna", "gastrocnêmio", "soleo"],
122
 
123
- # 🔹 Costas e subgrupos
124
- "costas": ["costas", "dorsal", "latissimo", "lats", "dorso", "costa"],
125
  "lombar": ["lombar", "parte baixa das costas", "erectores", "eretores da espinha"],
126
- "trapezio": ["trapezio", "trapézio", "pescoço largo"],
127
 
128
- # 🔹 Peito
129
  "peito": ["peito", "peitoral", "chest"],
130
 
131
- # 🔹 Braços (grupo e subgrupos)
132
- "bracos": ["braco", "braço", "bracos", "braços", "arm", "arms", "treino de bracos", "treino de braços"],
133
- "biceps": ["biceps", "bíceps"],
134
- "triceps": ["triceps", "tríceps"],
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
- "oblíquos": ["oblíquos", "obliquo", "oblíquo"],
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", "dorsal"],
158
  "superiores": ["peito", "dorsal", "trapezio", "biceps", "triceps", "ombro", "antebraco"],
159
  "bracos": ["biceps", "triceps", "antebraco"],
160
- "puxar": ["biceps", "costas", "lombar", "trapézio", "antebraço"],
161
- "empurrar": ["triceps", "peito", "ombro", "deltoides"]
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
- texto = texto.lower()
395
- detectados = set()
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
- # 2️⃣ Expansão genérica de todos os grupos compostos
404
- expansoes = set()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  for grupo, subgrupos in group_hierarchy.items():
406
- if grupo in detectados:
407
- detectados.remove(grupo)
408
- expansoes.update(subgrupos)
409
- detectados.update(expansoes)
410
-
411
- # 3️⃣ Hierarquia reversa: se um grupo e seus subgrupos aparecerem, priorizar os subgrupos
 
 
 
 
 
 
412
  for grupo, subgrupos in group_hierarchy.items():
413
- if grupo in detectados and any(s in detectados for s in subgrupos):
414
- detectados.remove(grupo)
415
 
416
- return list(detectados)
 
417
 
418
  # -------------------------
419
  # Objetivos (keywords)
420
  # -------------------------
421
  objetivo_keywords = {
422
- "hipertrofia": ["hipertrofia", "massa", "crescimento muscular", "ganhar tamanho", "volume"],
423
- "forca": ["força", "forca", "powerlifting", "power", "pesado", "ganhar força"],
424
- "condicionamento": ["resistência", "resistencia", "condicionamento", "endurance", "cardio", "alta repetiçao", "repetições altas"],
425
- "explosividade": ["explosivo", "explosividade", "pliometria", "saltar", "sprints", "potência", "potencia"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
  }
427
  def detectar_objetivos(texto: str) -> list[str]:
428
- texto = texto.lower()
 
 
 
429
  objetivos_detectados = []
430
  for objetivo, termos in objetivo_keywords.items():
431
  for termo in termos:
432
- if termo in texto:
 
433
  objetivos_detectados.append(objetivo)
434
  break
435
  if not objetivos_detectados:
436
- return ["hipertrofia"] # padrão
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(r"(\d+)\s*(x|vezes|dias)\s*(por\s*semana)?", prompt_norm)
 
 
456
  if padrao_split:
457
  dias = int(padrao_split.group(1))
458
- return "split", dias
 
459
 
460
- # 🔹 Detectar treino isolado (músculos)
461
  if musculos_detectados:
462
  return "isolado", musculos_detectados
463
 
464
- # 🔹 Default → treino full body isolado
465
- return "isolado", ["peito", "costas", "ombro", "braços", "pernas", "core"]
 
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