Cronograma de Revisão para Exames
De Wikiprompt, a enciclopédia livre de prompts
Cronograma de Revisão para Exames Uma habilidade/prompt completo para criar cronogramas de revisão para provas dia a dia, com técnicas de estudo baseadas em evidências, um script de planejador em Python e modelos. Ele coleta os detalhes das provas, executa o planejador, ajusta as compensações e entrega um plano humanizado.
Conteúdo do PromptSalvar
🌐
---
name: planejador-de-cronograma-de-revisao-para-provas
description: Cria um cronograma de revisão para provas dia a dia a partir das suas datas de prova, pesos das disciplinas e confiança. Divide as horas de estudo em sessões focadas, dá mais tempo para disciplinas fracas e pesadas, intercala disciplinas, muda para questões práticas na última semana antes de cada prova, coloca uma prova anterior cronometrada no dia anterior e respeita dias de descanso e folga. Sinaliza poucas sessões por tópico e provas em dias consecutivos. Inclui um planejador em Python da biblioteca padrão com --self-test.
---
# Planejador de Cronograma de Revisão para Provas
Você ajuda estudantes a transformar uma temporada de provas estressante em um plano realista: qual disciplina estudar em cada sessão, todos os dias, até a última prova. Você usa técnicas baseadas em evidências (espaçamento, prática de recuperação, intercalação, provas anteriores), mantém o plano humano com descanso e sono, e torna visíveis os trade-offs quando não há tempo suficiente para tudo.
## Arquivos nesta skill
- `scripts/revision_plan.py` - lê um CSV de disciplinas e imprime a tabela de disciplinas, um cronograma dia a dia e descobertas (apenas biblioteca padrão Python 3)
- `references/study-techniques.md` - o que fazer dentro de uma sessão: prática de recuperação, espaçamento, intercalação, provas anteriores e o que evitar
- `references/scheduling-rules.md` - como o script atribui prioridades, metas, tipos de sessão e descobertas, e como ajustá-lo
- `templates/revision-plan.md` - o plano a ser entregue: visão geral, cronograma semanal, rotina de sessão, pontos de verificação
- `examples/winter-exams.csv` - cinco provas universitárias entre 2 e 11 de dezembro com contagens de tópicos
## Fluxo de trabalho
### 1. Reúna os fatos
Pergunte para cada prova: disciplina, data, quanto vale (créditos, porcentagem da nota final ou importância 1-5), confiança de 1 (perdido) a 5 (sólido) e o número de tópicos ou capítulos. Depois pergunte o primeiro dia de revisão, horas realistas em dias de semana e fins de semana (após aulas, trabalho, deslocamento), duração preferida da sessão (50/10 padrão, Pomodoro 25/5 para foco baixo), um dia de descanso semanal e quaisquer dias que já estejam ocupados.
### 2. Execute o planejador
```
python3 scripts/revision_plan.py examples/winter-exams.csv --start 2026-11-16 --weekday-hours 3 --weekend-hours 5 --rest-day Sun --off 2026-11-21 --day-start 16:00
python3 scripts/revision_plan.py my-exams.csv --start 2026-05-04 --session-min 25 --break-min 5 --json
python3 scripts/revision_plan.py --self-test
```
Código de saída 1 significa uma descoberta ALTA (menos sessões que tópicos), 2 significa entrada inválida.
### 3. Corrija os trade-offs
Para UNDER_COVERED ou TIGHT: adicione horas, comece mais cedo, reduza a meta para disciplinas fortes ou concorde quais tópicos de baixo rendimento serão apenas revisados superficialmente (use a ponderação do programa ou a frequência em provas anteriores). Para BACK_TO_BACK: mova a prática da segunda disciplina para antes da primeira prova. Verifique o plano com o estudante: é viável em um dia ruim? Deixe folga em vez de estudar até tarde todas as noites.
### 4. Entregue
Preencha `templates/revision-plan.md`: a tabela de visão geral, o cronograma por semana, a rotina de sessão de `references/study-techniques.md` e duas datas de verificação para reavaliar a confiança e executar o script novamente.
## Exemplo de resultado
Para `examples/winter-exams.csv` a partir de 16 de novembro com 3 h em dias de semana, 5 h aos sábados, domingos e 21 de novembro de folga: 25 dias, 57 sessões de 50 minutos (47,5 h). Química Orgânica (peso 5, confiança 2) e Microeconomia (4, 2) recebem 15 e 16 sessões, História Europeia (3, 4) recebe 6. Cada disciplina termina com questões práticas e uma prova anterior cronometrada no dia anterior à sua prova. Descobertas: Estatística (10 sessões para 8 tópicos) e História Europeia (6 para 6) estão APERTADAS, e História Europeia e Microeconomia estão EM DIAS CONSECUTIVOS em 7 e 8 de dezembro.
## Regras
- Planeje com as horas que o estudante realmente tem, não as horas que ele gostaria de ter; proteja o sono (sem sessões tarde da noite antes das provas).
- Toda sessão termina com recuperação (questões, recordação em página em branco, flashcards), não apenas releitura ou marcação de texto.
- Mantenha pelo menos um dia de descanso ou dois meios dias por semana; burnout custa mais do que um dia perdido.
- Replaneje após cada verificação ou prova em vez de seguir um plano quebrado.
- Não faça trabalhos avaliados para o estudante; ajude com planejamento e métodos de estudo. Se um estudante mostrar sinais de estresse sério ou pânico, incentive-o a conversar com o apoio ao estudante ou um médico.
FILE:references/study-techniques.md
# Técnicas de Estudo
O que fazer dentro de cada sessão. Ordenadas pela força da evidência (Dunlosky et al. 2013, "Improving Students' Learning With Effective Learning Techniques", classificaram teste prático e prática distribuída como alta utilidade).
## Prática de recuperação (alta)
Traga informações de volta da memória em vez de relê-las: responda perguntas, escreva tudo o que lembra em uma página em branco, depois verifique com as anotações e preencha as lacunas em outra cor. Flashcards funcionam se você responder antes de virar. Errar primeiro e depois corrigir também ajuda no aprendizado.
## Espaçamento (alta)
Distribua sessões de uma disciplina ao longo de vários dias em vez de um longo bloco. Um ritmo simples de revisão para cada tópico: no dia seguinte, após 3 dias, após uma semana, depois antes da prova. O cronograma intercala disciplinas entre dias; comece cada sessão com 5 minutos de recordação da sessão anterior daquela disciplina para incorporar o espaçamento.
## Intercalação (moderada)
Misture tipos de problemas dentro de uma disciplina (para matemática e ciências: diferentes tipos de problemas em um conjunto, não 20 do mesmo tipo) para praticar a escolha do método, que a prova exige.
## Provas anteriores (alta para provas)
Faça pelo menos uma prova completa em condições cronometradas antes de cada prova, depois corrija com o gabarito oficial e liste os pontos perdidos por tópico. O script coloca uma no dia anterior a cada prova; adicione outras mais cedo se houver provas disponíveis.
## Elaboração e autoexplicação (moderada)
Pergunte "por que isso funciona?" e "como isso se conecta com X?", explique um conceito em voz alta como se estivesse ensinando, desenhe um mapa conceitual de memória.
## Baixo valor por si só
Reler, marcar texto e copiar anotações parecem produtivos, mas dão pouco ganho de longo prazo. Use-os apenas como primeira passada antes da recuperação.
## Rotina de sessão (50/10 padrão)
1. 5 min: recorde da memória o que você fez da última vez nesta disciplina.
2. 30 min: aprenda ou pratique um tópico (Aprender + recordar) ou faça questões (Questões práticas).
3. 10 min: feche o livro e teste-se; marque o que errou.
4. 5 min: escreva três perguntas que você não conseguiu responder para a próxima vez.
5. 10 min de pausa longe da tela: mova-se, beba água.
Para atenção curta use sessões 25/5 (`--session-min 25 --break-min 5`) e uma pausa mais longa a cada quatro.
## Sono, comida e o dia anterior
O sono consolida a memória; virar a noite reduz o desempenho na prova. Mantenha a noite anterior à prova para revisão leve e sono. Faça refeições regulares, mova-se todos os dias e mantenha o celular em outro cômodo durante as sessões.
FILE:references/scheduling-rules.md
# Regras de Agendamento
Como `scripts/revision_plan.py` constrói o cronograma.
## Sessões por dia
Sessões que cabem nas horas diárias: `floor((hours * 60 + break) / (session + break))`. Com sessões 50/10: 3 h -> 3 sessões, 5 h -> 5 sessões. Dias de descanso (`--rest-day`) e datas `--off` não têm nenhuma. Em um dia de prova, apenas metade das sessões é planejada (a prova ocupa o resto), e apenas para provas posteriores.
## Prioridade e meta
- prioridade = peso x (6 - confiança). Peso 5, confiança 2 -> 20; peso 3, confiança 4 -> 6.
- sessões meta = todas as sessões disponíveis antes daquela prova x prioridade / soma de todas as prioridades (pelo menos 1).
O peso pode ser créditos ou uma pontuação de importância 1-5; apenas as proporções importam, então use a mesma escala para todas as disciplinas.
## Escolhendo cada sessão
Para cada sessão, o script escolhe entre disciplinas cuja prova ainda está por vir e que têm menos de `--max-same` (padrão 2) sessões naquele dia:
1. disciplinas ainda abaixo da meta primeiro;
2. depois uma disciplina diferente da sessão anterior (intercalação);
3. depois a maior necessidade restante por dia restante até a prova;
4. empates vão para a maior prioridade, depois a prova mais cedo.
O dia anterior a uma prova começa com uma prova anterior cronometrada para aquela disciplina.
## Tipos de sessão
- Aprender + recordar: até 60 % da meta da disciplina ser concluída e mais de 7 dias antes da sua prova.
- Revisão mista: após 60 % da meta, mais de 7 dias antes.
- Questões práticas: nos últimos 7 dias antes da prova.
- Prova anterior (cronometrada): o dia anterior à prova.
## Descobertas
| Código | Gravidade | Regra | Correção típica |
|---|---|---|---|
| UNDER_COVERED | ALTA | sessões < tópicos | mais horas, começar mais cedo, revisar superficialmente tópicos de baixo rendimento |
| TIGHT | MÉDIA | sessões < 1,5 x tópicos | aceitar uma única passada, ou tirar tempo de disciplinas fortes |
| BELOW_TARGET | MÉDIA | planejado < 60 % da meta | a prova é cedo; comece essa disciplina primeiro |
| BACK_TO_BACK | MÉDIA | provas em dias consecutivos | antecipar a prática para a segunda prova |
| SAME_DAY | MÉDIA | duas provas no mesmo dia | tratar ambas como um bloco na última semana |
| NO_REST_DAY | BAIXA | plano > 10 dias sem dia de descanso ou folgas | adicionar `--rest-day` |
| LONG_DAYS | BAIXA | mais de 8 h por dia | limitar a 5-6 horas focadas |
## Ajustes
- Mais tempo para uma disciplina: aumente seu peso ou diminua sua confiança e execute novamente.
- Menos mudanças de disciplina: `--max-same 3`.
- Horários de relógio: `--day-start 09:00` adiciona horários de início e fim, com pausas entre sessões.
- Replanejar: após cada verificação, atualize a confiança e `--start`, e execute novamente; provas concluídas saem do CSV.
FILE:templates/revision-plan.md
# Plano de revisão: <nome>, <temporada de provas>
**Período:** <16 nov a 11 dez 2026> **Horas:** <3 h dias de semana, 5 h sábados> **Descanso:** <domingos + 21 nov>
**Sessões:** <57 x 50 min (47,5 h)> **Ritmo de sessão:** <50 min estudo / 10 min pausa>
## Provas e prioridades
| Disciplina | Prova | Peso | Confiança | Tópicos | Sessões planejadas | Notas |
|---|---|---|---|---|---|---|
| <Química Orgânica> | <Qua 2 dez> | <5> | <2> | <9> | <15> | <prova anterior 1 dez> |
## Semana 1: <16-22 nov>
| Dia | Sessão 1 | Sessão 2 | Sessão 3 | Sessão 4 | Sessão 5 |
|---|---|---|---|---|---|
| <Seg 16 nov> | <16:00 Química Orgânica: Aprender> | <17:00 Microeconomia: Aprender> | <...> | | |
## Semana 2: <...>
<...>
## Rotina de sessão
1. 5 min recordação da última sessão (página em branco)
2. 30 min aprender ou praticar um tópico
3. 10 min autoteste, marque os erros
4. 5 min: três perguntas em aberto para a próxima vez
5. 10 min pausa longe da tela
## Trade-offs acordados
- <Estatística está APERTADA: uma passada completa, segunda passada apenas nos tópicos 5-8 (mais pontos em provas anteriores)>
- <História Europeia / Microeconomia em dias consecutivos: prática de Microeconomia concluída até 5 dez>
## Verificações
- <Dom 22 nov>: reavalie a confiança 1-5 por disciplina, execute o planejador novamente
- <Dom 29 nov>: o mesmo, ajuste os últimos 10 dias
## Bem-estar
- Sono: <na cama até 23:30, sem estudo após 22:00 na noite anterior às provas>
- Movimento diário: <caminhada de 30 min>
- Se ficar demais: <converse com ... / contato do apoio ao estudante>
FILE:examples/winter-exams.csv
subject,exam_date,weight,confidence,topics
Organic Chemistry,2026-12-02,5,2,9
Statistics,2026-12-04,4,3,8
European History,2026-12-07,3,4,6
Microeconomics,2026-12-08,4,2,7
Academic English,2026-12-11,2,4,4
FILE:scripts/revision_plan.py
#!/usr/bin/env python3
"""Planejador de cronograma de revisão para provas (apenas biblioteca padrão Python 3).
Lê um CSV de disciplinas com datas de prova, peso e confiança, divide o
tempo de estudo disponível em sessões focadas e constrói um cronograma dia a dia
que dá mais tempo a disciplinas fracas e pesadas, intercala disciplinas, para
novo trabalho em uma disciplina após sua prova, muda de aprendizado para questões
práticas na última semana antes de cada prova e coloca uma prova anterior
cronometrada no dia anterior.
Colunas do CSV (cabeçalho obrigatório; separado por ; ou ,):
subject, exam_date (AAAA-MM-DD), weight (1-5 ou créditos), confidence (1-5), topics (opcional)
Uso:
python3 revision_plan.py exams.csv --start 2026-11-16 --weekday-hours 3 --weekend-hours 5
python3 revision_plan.py exams.csv --start 2026-11-16 --rest-day Sun --off 2026-11-28,2026-11-29 --day-start 16:00
python3 revision_plan.py --self-test
Códigos de saída: 0 = plano cabe, 1 = descobertas ALTAS (sessões insuficientes), 2 = entrada inválida.
"""
import argparse, csv, datetime as dt, io, json, sys
DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
SEV = {"HIGH": 0, "MEDIUM": 1, "LOW": 2}
class InputError(Exception):
pass
def parse_date(s, what):
try:
return dt.date.fromisoformat(s.strip())
except ValueError:
raise InputError(f"{what} '{s}' deve ser AAAA-MM-DD")
def read_subjects(text):
sample = text[:2000]
delim = ";" if sample.count(";") > sample.count(",") else ","
rd = csv.DictReader(io.StringIO(text), delimiter=delim)
if not rd.fieldnames:
raise InputError("CSV vazio")
fields = [f.strip().lower() for f in rd.fieldnames]
missing = [c for c in ("subject", "exam_date", "weight", "confidence") if c not in fields]
if missing:
raise InputError("colunas ausentes: " + ", ".join(missing))
subs = []
for i, raw in enumerate(rd, start=2):
r = {k.strip().lower(): (v or "").strip() for k, v in raw.items() if k}
if not any(r.values()):
continue
try:
w = float(r["weight"].replace(",", "."))
c = int(r["confidence"])
t = int(r["topics"]) if r.get("topics") else None
except ValueError:
raise InputError(f"linha {i}: weight, confidence e topics devem ser números")
if w <= 0:
raise InputError(f"linha {i}: weight deve ser positivo")
if not 1 <= c <= 5:
raise InputError(f"linha {i}: confidence deve ser 1 (fraco) a 5 (forte)")
if not r["subject"]:
raise InputError(f"linha {i}: subject está vazio")
subs.append({"subject": r["subject"], "exam": parse_date(r["exam_date"], f"linha {i}: exam_date"),
"weight": w, "confidence": c, "topics": t})
if not subs:
raise InputError("nenhuma disciplina no CSV")
return subs
def slots_for(hours, session, brk):
"""Número de sessões que cabem em `hours` com uma pausa entre sessões."""
mins = hours * 60
if mins < session:
return 0
return int((mins + brk) // (session + brk))
def plan(subs, start, weekday_hours=3.0, weekend_hours=5.0, session=50, brk=10, rest_day=None,
off=(), max_same=2, day_start=None):
if session < 15 or brk < 0:
raise InputError("session deve ser pelo menos 15 minutos e break não negativo")
for s in subs:
if s["exam"] <= start:
raise InputError(f"{s['subject']}: prova {s['exam']} não é após a data de início {start}")
last = max(s["exam"] for s in subs)
exam_days = {}
for s in subs:
exam_days.setdefault(s["exam"], []).append(s["subject"])
for s in subs:
s["priority"] = s["weight"] * (6 - s["confidence"])
days = []
d = start
while d < last:
if d in off or (rest_day is not None and d.weekday() == rest_day):
n = 0
else:
n = slots_for(weekend_hours if d.weekday() >= 5 else weekday_hours, session, brk)
if d in exam_days:
n //= 2 # a prova ocupa metade do dia
days.append((d, n))
d += dt.timedelta(days=1)
# sessões meta: parcela das vagas disponíveis antes de cada prova, por prioridade
total_p = sum(s["priority"] for s in subs)
for s in subs:
before = sum(n for day, n in days if day < s["exam"])
s["target"] = max(1, round(before * s["priority"] / total_p))
s["planned"] = 0
timetable = []
for day, n in days:
today, used = [], {}
live = [s for s in subs if s["exam"] > day]
# o dia anterior a uma prova: uma prova anterior cronometrada primeiro
for s in live:
if (s["exam"] - day).days == 1 and len(today) < n:
today.append((s["subject"], "Past paper (timed)")); used[s["subject"]] = 1; s["planned"] += 1
while len(today) < n:
cands = [s for s in live if used.get(s["subject"], 0) < max_same]
if not cands:
break
prev = today[-1][0] if today else None
def score(s):
days_left = max(1, (s["exam"] - day).days)
need = (s["target"] - s["planned"]) / days_left
# disciplinas ainda abaixo da meta primeiro, depois intercalar (evitar repetir a disciplina anterior)
return (s["planned"] < s["target"], s["subject"] != prev, need, s["priority"], -s["exam"].toordinal())
s = max(cands, key=score)
left = (s["exam"] - day).days
kind = "Practice questions" if left <= 7 else ("Learn + recall" if s["planned"] < s["target"] * 0.6 else "Mixed review")
today.append((s["subject"], kind)); used[s["subject"]] = used.get(s["subject"], 0) + 1; s["planned"] += 1
timed = []
t = day_start
for subj, kind in today:
if t is not None:
end = t + session
timed.append({"subject": subj, "kind": kind, "time": f"{t // 60:02d}:{t % 60:02d}-{end // 60:02d}:{end % 60:02d}"})
t = end + brk
else:
timed.append({"subject": subj, "kind": kind})
timetable.append({"date": day.isoformat(), "dow": DAYS[day.weekday()], "exams": exam_days.get(day, []), "sessions": timed})
findings = []
for s in subs:
if s["topics"]:
if s["planned"] < s["topics"]:
findings.append(("HIGH", "UNDER_COVERED", f"{s['subject']}: {s['planned']} sessões para {s['topics']} tópicos; adicione horas, remova tópicos de baixo rendimento ou comece mais cedo"))
elif s["planned"] < 1.5 * s["topics"]:
findings.append(("MEDIUM", "TIGHT", f"{s['subject']}: {s['planned']} sessões para {s['topics']} tópicos deixa pouco tempo para uma segunda passada"))
if s["planned"] < 0.6 * s["target"]:
findings.append(("MEDIUM", "BELOW_TARGET", f"{s['subject']}: {s['planned']} de {s['target']} sessões meta cabem antes da prova"))
dates = sorted(exam_days)
for a, b in zip(dates, dates[1:]):
if (b - a).days <= 1:
findings.append(("MEDIUM", "BACK_TO_BACK", f"provas em {a} ({', '.join(exam_days[a])}) e {b} ({', '.join(exam_days[b])}); termine a prática da segunda disciplina antes da primeira prova"))
for day, subjects in exam_days.items():
if len(subjects) > 1:
findings.append(("MEDIUM", "SAME_DAY", f"{len(subjects)} provas em {day}: {', '.join(subjects)}"))
if rest_day is None and len(days) > 10 and not off:
findings.append(("LOW", "NO_REST_DAY", "nenhum dia de descanso em um plano com mais de 10 dias; tire pelo menos meio dia de folga por semana"))
if max(weekday_hours, weekend_hours) > 8:
findings.append(("LOW", "LONG_DAYS", "mais de 8 horas de revisão por dia raramente permanece produtivo; mantenha 5-6 horas focadas"))
findings.sort(key=lambda f: SEV[f[0]])
total_sessions = sum(len(t["sessions"]) for t in timetable)
return {
"subjects": [{"subject": s["subject"], "exam": s["exam"].isoformat(), "weight": s["weight"], "confidence": s["confidence"],
"priority": s["priority"], "topics": s["topics"], "target": s["target"], "planned": s["planned"],
"hours": round(s["planned"] * session / 60, 1)} for s in sorted(subs, key=lambda x: x["exam"])],
"summary": {"start": start.isoformat(), "last_exam": last.isoformat(), "days": len(days), "sessions": total_sessions,
"study_hours": round(total_sessions * session / 60, 1), "session_min": session, "break_min": brk},
"timetable": timetable,
"findings": [{"severity": a, "code": b, "message": c} for a, b, c in findings],
}
def to_markdown(p):
s = p["summary"]
out = ["# Cronograma de revisão", "",
f"{s['start']} a {s['last_exam']}: {s['days']} dias, {s['sessions']} sessões de {s['session_min']} min ({s['study_hours']} h de estudo focado), {s['break_min']} min de pausas",
"", "| Disciplina | Prova | Peso | Confiança | Prioridade | Tópicos | Meta | Planejado | Horas |", "|---|---|---|---|---|---|---|---|---|"]
for x in p["subjects"]:
out.append(f"| {x['subject']} | {x['exam']} | {x['weight']:g} | {x['confidence']} | {x['priority']:g} | {x['topics'] or '-'} | {x['target']} | {x['planned']} | {x['hours']} |")
out += ["", "## Dia a dia", ""]
for t in p["timetable"]:
head = f"- **{t['dow']} {t['date']}**" + (f" (PROVA: {', '.join(t['exams'])})" if t["exams"] else "")
if not t["sessions"]:
out.append(head + ": descanso")
continue
parts = [(f"{x['time']} " if "time" in x else "") + f"{x['subject']} ({x['kind']})" for x in t["sessions"]]
out.append(head + ": " + "; ".join(parts))
out += ["", "## Descobertas"]
out += [f"- {f['severity']} {f['code']}: {f['message']}" for f in p["findings"]] or ["- nenhuma"]
out += ["", "Comece cada sessão com 5 minutos de recordação da memória sobre a sessão anterior daquela disciplina e termine com 3 perguntas que você não conseguiu responder."]
return "\n".join(out)
def self_test():
res = []
def check(name, cond):
res.append(cond)
print(("PASS " if cond else "FAIL ") + name)
D = dt.date
S = lambda name, exam, w=1, c=3, t=None: {"subject": name, "exam": exam, "weight": w, "confidence": c, "topics": t}
check("slots: 3 h de 50+10 = 3", slots_for(3, 50, 10) == 3)
check("slots: 50 min cabe exatamente 1", slots_for(50 / 60, 50, 10) == 1)
check("slots: abaixo de uma sessão = 0", slots_for(0.5, 50, 10) == 0)
check("slots: 25+5 em 2 h = 4", slots_for(2, 25, 5) == 4)
p = plan([S("A", D(2026, 1, 8))], D(2026, 1, 5), weekday_hours=2, weekend_hours=2, session=50, brk=10)
check("nenhuma sessão no dia da prova ou depois", all(t["date"] < "2026-01-08" for t in p["timetable"]))
check("dia anterior à prova começa com prova anterior", p["timetable"][-1]["sessions"][0]["kind"] == "Past paper (timed)")
check("questões práticas nos últimos 7 dias", all(x["kind"] != "Learn + recall" for t in p["timetable"] for x in t["sessions"]))
subs = [S("Weak", D(2026, 3, 1), w=3, c=1), S("Strong", D(2026, 3, 1), w=3, c=5)]
p = plan(subs, D(2026, 2, 1), weekday_hours=3, weekend_hours=3, max_same=3)
pl = {x["subject"]: x["planned"] for x in p["subjects"]}
check("disciplina fraca recebe mais sessões", pl["Weak"] > 3 * pl["Strong"])
check("prioridade = peso x (6 - confiança)", p["subjects"][0]["priority"] in (15, 3))
p = plan([S("A", D(2026, 3, 1)), S("B", D(2026, 3, 1))], D(2026, 2, 1), weekday_hours=3, weekend_hours=3)
check("máx. 2 sessões de uma disciplina por dia", all(
sum(1 for x in t["sessions"] if x["subject"] == subj) <= 2 for t in p["timetable"] for subj in "AB"))
check("disciplinas intercaladas enquanto ambas precisam de tempo", all(t["sessions"][i]["subject"] != t["sessions"][i + 1]["subject"]
for t in p["timetable"][:10] for i in range(len(t["sessions"]) - 1)))
p = plan([S("A", D(2026, 2, 16))], D(2026, 2, 2), rest_day=6)
check("dia de descanso vazio", all(not t["sessions"] for t in p["timetable"] if t["dow"] == "Sun"))
p = plan([S("A", D(2026, 2, 6))], D(2026, 2, 2), off={D(2026, 2, 3)})
check("dia de folga vazio", not [t for t in p["timetable"] if t["date"] == "2026-02-03"][0]["sessions"])
p = plan([S("A", D(2026, 2, 5)), S("B", D(2026, 2, 9))], D(2026, 2, 2), weekday_hours=4)
day5 = [t for t in p["timetable"] if t["date"] == "2026-02-05"][0]
check("dia de prova: metade das vagas, apenas outra disciplina", len(day5["sessions"]) == 2 and all(x["subject"] == "B" for x in day5["sessions"]))
p = plan([S("A", D(2026, 2, 5), t=20)], D(2026, 2, 2))
check("UNDER_COVERED ALTA", p["findings"][0]["code"] == "UNDER_COVERED")
p = plan([S("A", D(2026, 2, 20), t=11)], D(2026, 2, 2), weekday_hours=1, weekend_hours=1, rest_day=6)
check("TIGHT", any(f["code"] == "TIGHT" for f in p["findings"]))
p = plan([S("A", D(2026, 2, 9)), S("B", D(2026, 2, 10)), S("C", D(2026, 2, 10))], D(2026, 2, 2))
codes = [f["code"] for f in p["findings"]]
check("BACK_TO_BACK e SAME_DAY", "BACK_TO_BACK" in codes and "SAME_DAY" in codes)
check("NO_REST_DAY", "NO_REST_DAY" in [f["code"] for f in plan([S("A", D(2026, 3, 1))], D(2026, 2, 1))["findings"]])
check("LONG_DAYS", "LONG_DAYS" in [f["code"] for f in plan([S("A", D(2026, 2, 5))], D(2026, 2, 2), weekend_hours=10)["findings"]])
p = plan([S("A", D(2026, 2, 5))], D(2026, 2, 2), day_start=9 * 60)
check("horários de relógio com --day-start", p["timetable"][0]["sessions"][1]["time"] == "10:00-10:50")
subs = read_subjects("subject;exam_date;weight;confidence;topics\nMaths;2026-12-03;4,5;2;9\n")
check("CSV com ponto e vírgula + vírgula decimal", subs[0]["weight"] == 4.5 and subs[0]["topics"] == 9)
for bad, why in [("subject,exam_date\nA,2026-01-01\n", "colunas ausentes"),
("subject,exam_date,weight,confidence\nA,2026-13-01,1,3\n", "data inválida"),
("subject,exam_date,weight,confidence\nA,2026-01-01,1,9\n", "confiança fora do intervalo"),
("subject,exam_date,weight,confidence\nA,2026-01-01,x,3\n", "não numérico")]:
try:
read_subjects(bad); check("rejeita " + why, False)
except InputError:
check("rejeita " + why, True)
try:
plan([S("A", D(2026, 1, 1))], D(2026, 1, 1)); check("rejeita prova não após início", False)
except InputError:
check("rejeita prova não após início", True)
passed = sum(res)
print(f"{passed}/{len(res)} passaram")
return 0 if passed == len(res) else 1
def main():
ap = argparse.ArgumentParser(description="Planejador de cronograma de revisão para provas")
ap.add_argument("csv", nargs="?", help="CSV de disciplinas")
ap.add_argument("--start", help="primeiro dia de revisão AAAA-MM-DD (padrão hoje)")
ap.add_argument("--weekday-hours", type=float, default=3.0)
ap.add_argument("--weekend-hours", type=float, default=5.0)
ap.add_argument("--session-min", type=int, default=50, help="duração da sessão focada (padrão 50)")
ap.add_argument("--break-min", type=int, default=10, help="pausa entre sessões (padrão 10)")
ap.add_argument("--rest-day", choices=DAYS, help="dia de folga semanal")
ap.add_argument("--off", default="", help="datas separadas por vírgula sem revisão (AAAA-MM-DD)")
ap.add_argument("--max-same", type=int, default=2, help="máx. de sessões de uma disciplina por dia (padrão 2)")
ap.add_argument("--day-start", help="horário de relógio da primeira sessão HH:MM (adiciona horários ao cronograma)")
ap.add_argument("--json", action="store_true")
ap.add_argument("--self-test", action="store_true")
a = ap.parse_args()
if a.self_test:
return self_test()
if not a.csv:
ap.error("forneça um CSV, ou --self-test")
try:
with open(a.csv, encoding="utf-8-sig") as fh:
subs = read_subjects(fh.read())
start = parse_date(a.start, "--start") if a.start else dt.date.today()
off = {parse_date(x, "--off") for x in a.off.split(",") if x.strip()}
ds = None
if a.day_start:
try:
h, m = map(int, a.day_start.split(":")); assert 0 <= h < 24 and 0 <= m < 60
except Exception:
raise InputError("--day-start deve ser HH:MM")
ds = h * 60 + m
p = plan(subs, start, a.weekday_hours, a.weekend_hours, a.session_min, a.break_min,
DAYS.index(a.rest_day) if a.rest_day else None, off, a.max_same, ds)
except (OSError, InputError) as e:
print(f"erro: {e}", file=sys.stderr)
return 2
print(json.dumps(p, indent=2) if a.json else to_markdown(p))
return 1 if any(f["severity"] == "HIGH" for f in p["findings"]) else 0
if __name__ == "__main__":
sys.exit(main())
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 education. 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