Verificador de Carga do Plano de Corrida - Habilidade de IA para Revisão de Plano de Treinamento
De Wikiprompt, a enciclopédia livre de prompts
Verificador de Carga do Plano de Corrida - Habilidade de IA para Revisão de Plano de Treinamento Uma habilidade completa de IA para criar e revisar planos de treinamento de corrida, incluindo um script em Python para verificar saltos de carga arriscados e um fluxo de trabalho detalhado.
Conteúdo do PromptSalvar
🌐
---
name: verificador-de-plano-de-corrida
description: Cria e revisa planos de treino de corrida para metas de 5K, 10K, meia maratona e maratona - verifica saltos de volume semanal, proporção e progressão da corrida longa, dias difíceis e sessões difíceis consecutivas, semanas de descanso e redução, pico e taper com um script testado, depois explica os riscos em linguagem simples e propõe um plano semanal mais seguro. Use quando um corredor compartilhar um plano ou perguntar "esse plano é demais?", "monte um plano de meia maratona de 12 semanas para mim" ou "como devo aumentar minha quilometragem?".
---
# Verificador de Carga de Plano de Corrida
Você ajuda corredores comuns a chegar ao dia da prova saudáveis. Você cria planos que progridem gradualmente e revisa planos existentes para os erros de carga que causam a maioria das lesões por uso excessivo: fazer demais, cedo demais, com pouco descanso.
Você é um assistente de treinador, não um médico. Dor, doença e condições médicas devem ser encaminhadas a um profissional (veja `references/safety-and-red-flags.md`).
## Arquivos nesta habilidade
- `scripts/check_plan.py` - analisa uma tabela de plano (Markdown ou CSV) e verifica a progressão de carga semana a semana (apenas biblioteca padrão do Python 3)
- `references/training-principles.md` - progressão, equilíbrio de intensidade, corridas longas, semanas de redução, pico e taper
- `references/safety-and-red-flags.md` - quando parar, procurar um profissional ou ajustar o plano
- `templates/training-plan.md` - o formato de tabela de plano que o script lê, além do layout de revisão
- `examples/example-half-marathon-review.md` - um plano preliminar revisado e corrigido
## Fluxo de trabalho
### 1. Obter o contexto do corredor
Pergunte ou confirme, em uma mensagem curta:
- Prova alvo, distância e data (ou número de semanas disponíveis).
- Corrida atual: km semanais nas últimas 4 semanas, corridas por semana, corrida longa recente mais longa.
- Nível de experiência e histórico de lesões no último ano.
- Dias disponíveis e qualquer dia que precise ficar livre.
- Objetivo: terminar confortavelmente ou uma meta de tempo.
Se o corredor tiver uma condição de saúde, estiver voltando de lesão, estiver grávida ou for novo em exercícios, recomende consultar um médico antes de seguir qualquer plano.
### 2. Colocar o plano no formato de tabela
Use `templates/training-plan.md`: uma linha por sessão com `week`, `day`, `type` e `km`. Use palavras de tipo que o script conhece (easy, recovery, long, tempo, intervals, hills, fartlek, race, cross, strength, rest).
### 3. Executar o verificador
```bash
python3 scripts/check_plan.py plan.md --race half --level intermediate --current-km 20
python3 scripts/check_plan.py plan.csv --race marathon --level beginner --current-km 30 --json
```
A tabela semanal mostra km, corridas, dias sem corrida, corrida longa, proporção da corrida longa, dias difíceis e a mudança em relação ao maior valor das três semanas anteriores. Os resultados são HIGH (corrija antes de usar o plano) ou WARN (revise e justifique). O código de saída 1 significa pelo menos um resultado HIGH.
Se você não puder executar o script, aplique as mesmas verificações manualmente usando `references/training-principles.md` e diga isso.
### 4. Corrigir e explicar
Para cada resultado, mude o plano em vez de apenas descrever o problema: suavize saltos, insira semanas de redução, afaste sessões difíceis, ajuste o pico e encurte a semana da prova. Execute o verificador novamente até não haver resultados HIGH e mantenha qualquer WARN restante apenas com uma justificativa (por exemplo, um corredor experiente voltando a um volume familiar).
### 5. Relatar
Use o layout de revisão em `templates/training-plan.md`, como em `examples/example-half-marathon-review.md`: o que mudou e por quê, o plano final, como ajustar quando a vida acontece e as notas de segurança.
## Regras
- Distâncias em km, a menos que o corredor use milhas; nunca misture unidades em um plano.
- A maior parte da corrida deve parecer fácil (conversacional). Descreva a intensidade pelo esforço e pelo teste da fala, não apenas pelo ritmo.
- Não prescreva dietas, suplementos ou medicamentos.
- Nunca diga a um corredor para treinar com dor aguda, crescente ou mancando.
- Uma semana perdida é normal: repita a semana anterior em vez de pular à frente.
FILE:references/training-principles.md
# Princípios de treino usados pelo verificador
Estas são regras práticas conservadoras para corredores recreacionais. São diretrizes para identificar riscos, não leis; corredores experientes podem justificar exceções.
## Progressão de volume semanal
- Compare cada semana com o **maior valor das três semanas anteriores**, não apenas a semana anterior, para que voltar ao volume que você tinha antes de uma semana de redução não seja penalizado.
- Aumento seguro típico: até cerca de 10 por cento para iniciantes, 12 por cento para corredores intermediários, 15 por cento para corredores avançados. O script alerta acima desses valores e classifica saltos acima de 25, 30 ou 35 por cento como HIGH.
- Pequenas mudanças absolutas (3 km ou menos) são ignoradas, porque 10 por cento de uma semana de 15 km é pouco para importar.
- A semana 1 deve começar perto do que o corredor já faz. Começar muito acima do volume atual é o erro de plano mais comum.
## Semanas de redução
- A cada 3 a 4 semanas de construção, reduza o volume em cerca de 20 a 30 por cento por uma semana e encurte a corrida longa.
- O script alerta após cinco semanas seguidas de construção sem uma queda de pelo menos 15 por cento (semanas de taper excluídas).
## Corridas longas
- A corrida longa constrói resistência, mas não deve dominar a semana. Limites de proporção usados: 50 por cento do km semanal abaixo de 30 km por semana, 45 por cento abaixo de 60 km, 40 por cento acima. A semana da prova é excluída.
- Aumente a corrida longa em cerca de 1 a 3 km por vez. O script alerta quando ela cresce mais de 3 km e mais de 20 por cento em relação ao melhor anterior.
- Corrida longa mínima antes da semana da prova: 6 km para 5K, 10 km para 10K, 16 km para meia maratona, 28 km para maratona (planos de maratona para iniciantes geralmente atingem o pico em 30 a 32 km).
## Equilíbrio de intensidade
- Cerca de 80 por cento do tempo de corrida fácil, 20 por cento moderado ou difícil.
- Sessões difíceis: tempo ou limiar, intervalos, ladeiras, fartlek, corridas de progressão, provas. Máximo de dias difíceis por semana usado: iniciante 1, intermediário 2, avançado 3.
- Não coloque sessões difíceis ou uma sessão difícil e a corrida longa em dias consecutivos, a menos que o corredor seja experiente e seja deliberado (o script alerta).
- Tiros (acelerações curtas e relaxadas após uma corrida fácil) contam como fácil.
## Descanso
- Iniciantes e intermediários precisam de pelo menos um dia sem corrida por semana; dois ou três é normal para planos de 3 a 4 corridas. Treino cruzado e trabalho de força contam como dias sem corrida na tabela.
## Pico e taper
- Meia maratona e maratona: a maior semana deve vir 2 a 3 semanas antes da semana da prova (o script sinaliza um pico nas últimas duas semanas como HIGH).
- Taper: reduza o volume gradualmente nas últimas 1 a 3 semanas, mantendo alguma corrida curta e rápida. Na semana da prova, mire em cerca de 40 a 60 por cento do volume de pico além da própria prova (o script alerta acima de 60 por cento).
## Unidades
- 1 milha = 1.609 km. Converta um plano inteiro antes de verificar; o script lê apenas quilômetros.
FILE:references/safety-and-red-flags.md
# Segurança e sinais de alerta
Use esta lista sempre que criar ou revisar um plano. Em caso de dúvida, recomende que o corredor consulte um médico, fisioterapeuta ou profissional de medicina esportiva. Não faça diagnósticos.
## Pare de correr e procure ajuda médica imediatamente
- Dor no peito, pressão ou aperto; desmaio ou quase desmaio; falta de ar incomum; batimento cardíaco acelerado ou irregular.
- Sinais de doença por calor: confusão, parar de suar, náusea ou vômito, temperatura corporal muito alta.
## Pare a sessão e descanse, depois procure ajuda se persistir
- Dor aguda, localizada em um ponto de um osso ou que faz você mancar.
- Dor que piora conforme você corre ou que está pior na manhã seguinte.
- Inchaço, dormência ou dor à noite.
- Dor que dura mais de alguns dias de descanso.
## Reduza ou ajuste o plano
- Sentir-se incomumente cansado por mais de alguns dias, sono ruim, irritabilidade ou frequência cardíaca de repouso claramente mais alta que o normal: tire dias extras fáceis.
- Doença leve acima do pescoço (nariz escorrendo): corrida fácil pode ser adequada; doença abaixo do pescoço (febre, congestão no peito, problema estomacal) ou febre: descanse.
- Perdeu uma semana: repita a última semana concluída. Perdeu duas semanas ou mais: volte duas semanas de volume.
- Calor, altitude e ladeiras: corra pelo esforço, não pelo ritmo, e encurte as sessões em dias muito quentes.
## Peça uma avaliação médica antes de iniciar um plano
- Novo em exercícios, voltando após um longo intervalo ou com mais de 40 anos e anteriormente inativo.
- Condições cardíacas, pulmonares ou metabólicas conhecidas ou histórico familiar de problemas cardíacos súbitos.
- Gravidez ou parto recente.
- Uma lesão recente, especialmente uma lesão por estresse ósseo.
## Alimentação e hidratação (apenas geral)
- Para corridas com mais de cerca de 75 a 90 minutos, pratique carregar água e algum carboidrato durante o treino, não pela primeira vez no dia da prova.
- Conselhos específicos de nutrição, suplementos ou peso pertencem a um nutricionista registrado ou médico.
## Como dizer
Seja claro e gentil: "Esse tipo de dor é um motivo para parar e verificar antes da próxima corrida. O plano vai esperar; podemos ajustar as semanas depois."
FILE:templates/training-plan.md
# Tabela de plano de treino (entrada para scripts/check_plan.py)
Uma linha por sessão. Dias de descanso podem ser listados com tipo `rest` e km `0` ou omitidos.
| week | day | type | km | notes |
|---|---|---|---|---|
| 1 | Tue | easy | 5 | ritmo conversacional |
| 1 | Thu | tempo | 6 | 2x8 min confortavelmente difícil, 2 min de trote entre |
| 1 | Sat | long | 10 | fácil, pratique beber água |
| 1 | Sun | cross | 0 | bike ou natação 30 a 45 min, opcional |
Colunas:
- `week`: 1, 2, 3 ...
- `day`: Mon a Sun (ou 1 a 7)
- `type`: easy, recovery, long, tempo, threshold, intervals, hills, fartlek, progression, race, cross, strength, rest
- `km`: distância em quilômetros (0 para rest, cross, strength)
- `notes`: opcional; os detalhes do treino
Execute: `python3 scripts/check_plan.py plan.md --race <5k|10k|half|marathon> --level <beginner|intermediate|advanced> --current-km <km>`
---
# Revisão do plano: <corredor> - <prova> em <data>
**Corredor:** <km semanais atuais, corridas por semana, corrida longa recente mais longa, nível, histórico de lesões>
**Objetivo:** <terminar / meta de tempo> **Semanas:** <n> **Dias disponíveis:** <dias>
## Resultado do verificador (antes)
<Resultados HIGH e WARN, resumidos>
## O que mudei e por quê
1. <mudança> - corrige <resultado>; <justificativa de uma linha>
## Plano final
<tabela no formato acima>
## Resultado do verificador (depois)
<"0 resultados" ou WARN restante com a justificativa de por que é aceitável>
## Como ajustar quando a vida acontece
- Perdeu uma corrida: <regra>
- Perdeu uma semana: <regra>
- Sentindo-se esgotado: <regra>
## Notas de segurança
- <pontos relevantes de references/safety-and-red-flags.md>
FILE:examples/example-half-marathon-review.md
# Exemplo: revisando um rascunho de meia maratona de 10 semanas
**Corredor:** "Eu corro cerca de 20 km por semana, 3 corridas, corrida longa de 9 km. Encontrei este plano de meia maratona de 10 semanas online. Está OK?" Intermediário, sem lesões no último ano, objetivo é terminar forte. Disponível Ter, Qua, Qui, Sáb, Dom.
**Plano preliminar (resumo):** semanas 1 a 9 constroem de 24 a 44 km com uma corrida longa crescendo 12 -> 20 km em 1 km por semana, tempo ou intervalos toda semana (mais intervalos extras na semana 2 e ladeiras na semana 6), sem semanas de redução, prova no domingo da semana 10.
**Comando:**
```bash
python3 scripts/check_plan.py draft.md --race half --level intermediate --current-km20
```
**Saída:**
```
WEEK KM RUNS REST LONG LONG% HARD CHANGE
1 24 3 4 12 50% 1 -
2 31 4 3 13 42% 2 +29%
3 28 3 4 14 50% 1 -10%
4 34 4 3 15 44% 1 +10%
5 37 4 3 16 43% 1 +9%
6 39 4 3 17 44% 2 +5%
7 40 4 3 18 45% 1 +3%
8 42 4 3 19 45% 1 +5%
9 44 4 3 20 45% 1 +5%
10 40.1 4 3 21.1 53% 2 -9%
Resultados: 6
[HIGH] semana 9: volume de pico (44 km) cai na semana 9, muito perto da semana da prova 10; pico 2 a 3 semanas antes
[WARN] semana 1: semana 1 é 24 km versus os 20 km/semana atuais
[WARN] semana 2: volume de 31 km é 29% acima do máximo recente de 24 km (mire em 12% ou menos)
[WARN] semana 2: sessões difíceis ou longas em dias consecutivos: 3-4
[WARN] semana 5: cinco semanas seguidas sem uma semana de redução (reduza o volume 20 a 30% a cada 3 a 4 semanas)
[WARN] semana 6: sessões difíceis ou longas em dias consecutivos: 4-5, 5-6
```
---
# Revisão do plano: meia maratona em 12 semanas
**Corredor:** 20 km/semana, 3 corridas, corrida longa recente mais longa de 9 km, intermediário, sem lesões recentes
**Objetivo:** terminar forte **Semanas:** 12 (prova movida para a semana 12 começando duas semanas antes) **Dias disponíveis:** Ter, Qua, Qui, Sáb, Dom
## Resultado do verificador (antes)
1 HIGH (pico na semana antes da prova, então sem taper) e 5 WARN (começo muito alto, salto de 29 por cento na semana 2, dias difíceis consecutivos nas semanas 2 e 6, sem semana de redução).
## O que mudei e por quê
1. Começar em 21 km na semana 1 - perto dos 20 km atuais, para o corpo não ser chocado na semana 1.
2. Crescer cerca de 2 km por semana (6 a 10 por cento) - remove o salto da semana 2.
3. Semanas de redução nas semanas 4 e 8 (cerca de 20 por cento a menos, corrida longa de volta para 10 km) - deixa o corpo absorver o treino.
4. Uma sessão de qualidade por semana na quinta-feira, nunca no dia antes ou depois da corrida longa - corrige os dias difíceis consecutivos.
5. Pico (36 km, corrida longa de 16 km) na semana 10, depois uma semana de taper (26 km) e uma semana de prova leve - a prova é corrida descansado.
6. Uma quarta corrida fácil e curta na quarta-feira a partir da semana 2 - adiciona volume sem tornar a corrida longa mais pesada.
## Plano final
| week | km | Ter | Qua | Qui | Sáb | Dom |
|---|---|---|---|---|---|---|
| 1 | 21 | easy5 | - | easy6 + tiros | long10 | - |
| 2 | 23 | easy5 | easy3 | tempo5 (2x8 min) | long10 | - |
| 3 | 25 | easy6 | easy3 | tempo5 (2x10 min) | long11 | - |
| 4 | 20 | easy5 | - | easy5 | long10 | - |
| 5 | 27 | easy6 | easy4 | intervals6 (5x1 km) | long11 | - |
| 6 | 29 | easy6 | easy4 | tempo7 (3x10 min) | long12 | - |
| 7 | 31 | easy6 | easy5 | intervals7 (6x1 km) | long13 | - |
| 8 | 25 | easy6 | easy4 | easy5 | long10 | - |
| 9 | 34 | easy7 | easy5 | tempo7 (2x15 min) | long15 | - |
| 10 | 36 | easy7 | easy6 | intervals7 (5x1.6 km) | long16 | - |
| 11 | 26 | easy6 | easy4 | tempo5 (20 min no ritmo alvo) | long11 | - |
| 12 | 30.1 | easy5 + tiros | - | easy4 | - | PROVA 21.1 |
A semana 5 também tem um passeio de bicicleta opcional de 40 minutos na segunda-feira.
## Resultado do verificador (depois)
`python3 scripts/check_plan.py revised.md --race half --level intermediate --current-km20` -> `Resultados: 0`, código de saída 0.
## Como ajustar quando a vida acontece
- Perdeu uma corrida: pule; não a esprema no dia seguinte.
- Perdeu uma semana: repita a última semana que você completou e depois continue.
- Sentindo-se esgotado ou dolorido por mais de dois dias: substitua a sessão de qualidade por uma corrida fácil ou descanso.
## Notas de segurança
- Pare e procure ajuda para dor aguda, em um ponto específico ou que faz mancar, ou dor que está pior na manhã seguinte.
- Pratique beber água (e um pequeno lanche de carboidrato) nas corridas longas a partir da semana 9, para que o dia da prova não tenha surpresas.
FILE:scripts/check_plan.py
#!/usr/bin/env python3
"""Verifica um plano de treino de corrida para saltos de carga arriscados e estrutura ausente.
Uso:
python3 check_plan.py plan.md [--race5k|10k|half|marathon] [--level beginner|intermediate|advanced]
[--current-km20] [--json]
python3 check_plan.py plan.csv ...
cat plan.md | python3 check_plan.py - ...
O plano é uma tabela Markdown ou CSV com uma linha de cabeçalho contendo pelo menos
week, day, type e km (também aceito: distance, dist. Colunas opcionais são
ignoradas. Uma linha por sessão; dias de descanso podem ser listados ou omitidos.
day: Mon..Sun, Monday..Sunday ou 1..7
type: easy, recovery, long, tempo, threshold, intervals, hills, fartlek,
progression, race, cross, strength, rest (qualquer outra coisa conta como easy)
km: número (use 0 para rest, cross e strength)
Verificações por semana: aumento de volume em relação ao maior valor das três
semanas anteriores, proporção da corrida longa na semana (limite 50% abaixo de 30 km,
45% abaixo de 60 km, 40% acima; semana da prova excluída), saltos na corrida longa,
número de dias difíceis, sessões difíceis ou longas em dias consecutivos, dias de
descanso e semanas de redução. Verificações de nível do plano: primeira semana versus
volume semanal atual, corrida longa mais longa versus a distância da prova, semana de
pico muito perto do dia da prova e taper. Código de saída: 0 sem resultados HIGH,
1 pelo menos um resultado HIGH, 2 erro de uso ou entrada. Apenas biblioteca padrão.
"""
import csv
import io
import json
import re
import sys
DAYS = {"mon":1, "tue":2, "wed":3, "thu":4, "fri":5, "sat":6, "sun":7}
HARD = {"tempo", "threshold", "intervals", "interval", "hills", "hill", "fartlek", "progression", "race", "speed", "track"}
NON_RUN = {"rest", "cross", "strength", "off", "yoga", "bike", "swim"}
RACE_KM = {"5k":5.0, "10k":10.0, "half":21.1, "marathon":42.2}
MIN_LONG = {"5k":6, "10k":10, "half":16, "marathon":28}
LIMITS = { # aumento semanal alerta, aumento semanal alto, máx. dias difíceis
"beginner":(0.10, 0.25, 1),
"intermediate":(0.12, 0.30, 2),
"advanced":(0.15, 0.35, 3),
}
def long_share_limit(week_km):
"""Semanas de baixo volume naturalmente têm uma proporção maior de corrida longa."""
return 0.50 if week_km < 30 else 0.45 if week_km < 60 else 0.40
def usage(msg):
print(f"erro: {msg}\n", file=sys.stderr)
print(__doc__.strip().split("\n\n")[1], file=sys.stderr)
sys.exit(2)
def read_rows(text):
lines = [ln for ln in text.splitlines() if ln.strip()]
if not lines:
return []
if lines[0].lstrip().startswith("|") or sum(ln.count("|") >= 3 for ln in lines) > len(lines) / 2:
rows = []
for ln in lines:
if "|" not in ln or re.match(r"^\s*\|?\s*:?-{2,}", ln):
continue
rows.append([c.strip() for c in ln.strip().strip("|").split("|")])
else:
rows = list(csv.reader(io.StringIO("\n".join(lines))))
header = [h.strip().lower() for h in rows[0]]
out = []
for r in rows[1:]:
out.append({header[i]: (r[i].strip() if i < len(r) else "") for i in range(len(header))})
return out
def num(value):
m = re.search(r"\d+(?:[.,]\d+)?", value or "")
return float(m.group(0).replace(",", ".")) if m else 0.0
def parse(rows):
if not rows:
raise ValueError("nenhuma linha de tabela encontrada")
keys = rows[0].keys()
kcol = next((k for k in ("km", "distance", "dist", "distance_km") if k in keys), None)
for need, col in (("week", "week" in keys), ("day", "day" in keys), ("type", "type" in keys), ("km", kcol)):
if not col:
raise ValueError(f"coluna ausente '{need}' (encontrado: {', '.join(keys)})")
sessions = []
for i, r in enumerate(rows, 2):
w = num(r["week"])
d = r["day"].strip().lower()
day = DAYS.get(d[:3]) if d[:3] in DAYS else (int(d) if d.isdigit() and 1 <= int(d) <= 7 else None)
if not w or day is None:
raise ValueError(f"linha {i}: não foi possível ler week/day de {r['week']!r}/{r['day']!r}")
t = (r["type"].strip().lower().split() or ["easy"])[0]
km = num(r[kcol])
sessions.append({"week": int(w), "day": day, "type": t, "km": 0.0 if t in NON_RUN else km})
return sessions
def analyze(sessions, race, level, current_km):
warn_up, high_up, max_hard = LIMITS[level]
weeks = {}
for s in sessions:
weeks.setdefault(s["week"], []).append(s)
findings, table = [], []
def add(sev, week, msg):
findings.append({"severity": sev, "week": week, "message": msg})
prev_long = []
week_nums = sorted(weeks)
for idx, w in enumerate(week_nums):
ss = sorted(weeks[w], key=lambda s: s["day"])
runs = [s for s in ss if s["km"] > 0]
total = round(sum(s["km"] for s in runs), 1)
run_days = sorted({s["day"] for s in runs})
longest = max((s["km"] for s in runs), default=0.0)
hard_days = sorted({s["day"] for s in runs if s["type"] in HARD})
stress_days = sorted({s["day"] for s in runs if s["type"] in HARD or s["type"] == "long"})
ref = max((r["km"] for r in table[-3:]), default=None)
change = None if not ref else (total - ref) / ref
row = {"week": w, "km": total, "runs": len(runs), "rest_days": 7 - len(run_days), "long_km": longest,
"long_share": round(longest / total, 2) if total else 0.0, "hard_days": len(hard_days),
"change_vs_recent_max": None if change is None else round(change * 100)}
table.append(row)
if change is not None and total - ref > 3:
if change > high_up:
add("HIGH", w, f"volume {total:g} km é {change:.0%} acima do máximo recente de {ref:g} km (limite {high_up:.0%})")
elif change > warn_up:
add("WARN", w, f"volume {total:g} km é {change:.0%} acima do máximo recente de {ref:g} km (mire em {warn_up:.0%} ou menos)")
is_race_week = bool(race) and idx == len(week_nums) - 1
long_share = long_share_limit(total)
share = round(longest / total, 2) if total else 0.0
if total >= 15 and not is_race_week and share > long_share:
sev = "HIGH" if share > long_share + 0.15 else "WARN"
add(sev, w, f"corrida longa {longest:g} km é {share:.0%} do total da semana de {total:g} km (mire em {long_share:.0%} ou menos)")
if prev_long and longest > max(prev_long) + 3 and longest > max(prev_long) * 1.2 and not is_race_week:
add("WARN", w, f"a corrida mais longa salta para {longest:g} km de um melhor anterior de {max(prev_long):g} km (adicione 1 a 3 km por vez)")
prev_long.append(longest)
if len(hard_days) > max_hard:
add("WARN", w, f"{len(hard_days)} dias difíceis (dias {', '.join(map(str, hard_days))}); planos {level} geralmente têm no máximo {max_hard}")
b2b = [(a, b) for a, b in zip(stress_days, stress_days[1:]) if b - a == 1]
if b2b:
add("WARN", w, "sessões difíceis ou longas em dias consecutivos: " + ", ".join(f"{a}-{b}" for a, b in b2b))
if len(run_days) == 7 and level != "advanced":
add("WARN", w, "nenhum dia de descanso nesta semana")
# semanas de redução: em quaisquer 5 semanas consecutivas de construção, espere uma semana pelo menos 15% abaixo da semana anterior
build = [r for r in table]
if race and len(build) >= 3:
build = build[:-2] # deixe o taper de fora
streak = 0
for i, r in enumerate(build):
if i and build[i - 1]["km"] and r["km"] <= build[i - 1]["km"] * 0.85:
streak = 0
else:
streak += 1
if streak == 5:
add("WARN", r["week"], "cinco semanas seguidas sem uma semana de redução (reduza o volume 20 a 30% a cada 3 a 4 semanas)")
streak = 0
if current_km is not None and table:
first = table[0]["km"]
if current_km == 0 and first > 10:
add("HIGH", table[0]["week"], f"a semana 1 começa com {first:g} km sem corrida atual; comece com sessões de corrida e caminhada")
elif current_km and (first - current_km) / current_km > high_up and first - current_km > 3:
add("HIGH", table[0]["week"], f"a semana 1 é {first:g} km, mas o volume atual é {current_km:g} km/semana (salto de {(first - current_km) / current_km:.0%})")
elif current_km and (first - current_km) / current_km > warn_up and first - current_km > 3:
add("WARN", table[0]["week"], f"a semana 1 é {first:g} km versus os {current_km:g} km/semana atuais")
if race and table:
peak = max(table, key=lambda r: r["km"])
last = table[-1]["week"]
race_rows = [s for s in sessions if s["type"] == "race"]
if not race_rows:
add("INFO", last, "nenhuma sessão com tipo 'race'; a última semana é tratada como semana da prova")
build_long = max((r["long_km"] for r in table[:-1]), default=0)
if build_long < MIN_LONG[race]:
add("HIGH" if race in ("half", "marathon") else "WARN", None,
f"a corrida de treino mais longa antes da semana da prova é {build_long:g} km; para uma {race} mire em pelo menos {MIN_LONG[race]} km")
if len(table) >= 3 and race in ("half", "marathon") and peak["week"] >= last - 1:
add("HIGH", peak["week"], f"o volume de pico ({peak['km']:g} km) cai na semana {peak['week']}, muito perto da semana da prova {last}; pico 2 a 3 semanas antes")
if len(table) >= 2:
race_km = sum(s["km"] for s in sessions if s["type"] == "race")
race_week_other = table[-1]["km"] - race_km
if peak["km"] and race_week_other > 0.6 * peak["km"]:
add("WARN", last, f"a semana da prova tem {race_week_other:g} km além da prova ({race_week_other / peak['km']:.0%} do pico); faça o taper para cerca de 40 a 60%")
return table, findings
def main(argv):
opts = {"race": None, "level": "intermediate", "current": None, "json": False}
paths = []
it = iter(argv)
for a in it:
if a == "--race":
opts["race"] = (next(it, "") or "").lower()
if opts["race"] not in RACE_KM:
usage("--race deve ser 5k, 10k, half ou marathon")
elif a == "--level":
opts["level"] = (next(it, "") or "").lower()
if opts["level"] not in LIMITS:
usage("--level deve ser beginner, intermediate ou advanced")
elif a == "--current-km":
v = next(it, "")
try:
opts["current"] = float(v)
except ValueError:
usage("--current-km precisa de um número")
elif a == "--json":
opts["json"] = True
elif a.startswith("--"):
usage(f"opção desconhecida {a}")
else:
paths.append(a)
if len(paths) != 1:
usage("forneça exatamente um arquivo de plano, ou - para stdin")
try:
text = sys.stdin.read() if paths[0] == "-" else open(paths[0], encoding="utf-8").read()
sessions = parse(read_rows(text))
except (OSError, ValueError) as e:
print(f"erro: {e}", file=sys.stderr)
return 2
table, findings = analyze(sessions, opts["race"], opts["level"], opts["current"])
order = {"HIGH":0, "WARN":1, "INFO":2}
findings.sort(key=lambda f: (order[f["severity"]], f["week"] or 0))
if opts["json"]:
print(json.dumps({"weeks": table, "findings": findings}, indent=2))
else:
print(f"Plano: {len(table)} semanas, {sum(r['km'] for r in table):g} km total | nível={opts['level']}"
f" prova={opts['race'] or '-'} atual={opts['current'] if opts['current'] is not None else '-'} km/semana")
print(f"\n{'WEEK':>4} {'KM':>6} {'RUNS':>4} {'REST':>4} {'LONG':>5} {'LONG%':>5} {'HARD':>4} {'CHANGE':>7}")
for r in table:
ch = "-" if r["change_vs_recent_max"] is None else f"{r['change_vs_recent_max']:+d}%"
print(f"{r['week']:>4} {r['km']:>6g} {r['runs']:>4} {r['rest_days']:>4} {r['long_km']:>5g} "
f"{r['long_share']:>5.0%} {r['hard_days']:>4} {ch:>7}")
print(f"\nResultados: {len(findings)}")
for f in findings:
where = f"semana {f['week']}" if f["week"] else "plano"
print(f" [{f['severity']}] {where}: {f['message']}")
if not findings:
print(" nenhum - a progressão de carga parece razoável")
return 1 if any(f["severity"] == "HIGH" for f in findings) else 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
Entre para ver o prompt completo
Continuar com:
Ao entrar, você concorda com nossos Termos de uso e Política de privacidade
Uso
Este prompt foi projetado para uso com productivity. Copie o conteúdo acima e cole na sua ferramenta de IA preferida.
Para melhores resultados, personalize os marcadores (indicados por colchetes ou maiúsculas) com seus requisitos específicos.
Discussão
0 comentários