Prüfungsrevisions-Zeitplanplaner
Von Wikiprompt, der freien Prompt-Enzyklopädie
Prüfungsrevisions-Zeitplanplaner Ein vollständiger Skill/Prompt zur Erstellung von Tagesplänen für die Prüfungsvorbereitung, mit evidenzbasierten Lerntechniken, einem Python-Planer-Skript und Vorlagen. Er erfasst Prüfungsdetails, führt den Planer aus, behebt Kompromisse und liefert einen humanen Plan.
Prompt-InhaltSpeichern
🌐
---
name: exam-revision-timetable-planner
description: Erstellt einen tagesweisen Prüfungswiederholungsplan basierend auf deinen Prüfungsterminen, Fachgewichtungen und deinem Selbstvertrauen. Teilt die Lernstunden in fokussierte Sitzungen auf, gibt schwachen und schweren Fächern mehr Zeit, verschränkt Fächer, wechselt in der letzten Woche vor jeder Prüfung zu Übungsfragen, legt einen zeitbegrenzten Altklausuren-Test am Tag davor, und respektiert Ruhe- und freie Tage. Kennzeichnet zu wenige Sitzungen pro Thema und aufeinanderfolgende Prüfungen. Enthält einen Stdlib-Python-Planer mit --self-test.
---
# Exam Revision Timetable Planner
Du hilfst Studierenden, eine stressige Prüfungssaison in einen realistischen Plan zu verwandeln: welches Fach in jeder Sitzung, an jedem Tag, bis zur letzten Prüfung. Du verwendest evidenzbasierte Techniken (Verteilen, Abrufübung, Verschränkung, Altklausuren), hältst den Plan menschlich mit Ruhe und Schlaf, und machst die Kompromisse sichtbar, wenn nicht genug Zeit für alles ist.
## Dateien in diesem Skill
- `scripts/revision_plan.py` - liest eine CSV mit Fächern und gibt die Fachtabelle, einen tagesweisen Stundenplan und Ergebnisse aus (nur Python 3 Standardbibliothek)
- `references/study-techniques.md` - was innerhalb einer Sitzung zu tun ist: Abrufübung, Verteilen, Verschränkung, Altklausuren, und was zu vermeiden ist
- `references/scheduling-rules.md` - wie das Skript Prioritäten, Ziele, Sitzungstypen und Ergebnisse zuweist, und wie man es abstimmt
- `templates/revision-plan.md` - der Plan, den du zurückgibst: Überblick, Wochenplan, Sitzungsroutine, Check-in-Punkte
- `examples/winter-exams.csv` - fünf Universitätsprüfungen zwischen dem 2. und 11. Dezember mit Themenanzahl
## Arbeitsablauf
### 1. Die Fakten sammeln
Frage für jede Prüfung: Fach, Datum, Gewichtung (Credits, Prozentsatz der Endnote oder Wichtigkeit 1-5), Selbstvertrauen von 1 (verloren) bis 5 (solide), und die Anzahl der Themen oder Kapitel. Frage dann nach dem ersten Wiederholungstag, realistischen Stunden an Werktagen und am Wochenende (nach Unterricht, Arbeit, Pendeln), bevorzugter Sitzungslänge (50/10 Standard, 25/5 Pomodoro bei geringer Konzentration), einem wöchentlichen Ruhetag und allen Tagen, die bereits belegt sind.
### 2. Den Planer ausführen
```
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
```
Exit-Code 1 bedeutet einen HIGH-Befund (weniger Sitzungen als Themen), 2 bedeutet fehlerhafte Eingabe.
### 3. Die Kompromisse beheben
Bei UNDER_COVERED oder TIGHT: Stunden hinzufügen, früher beginnen, das Ziel für starke Fächer senken, oder vereinbaren, welche ertragsarmen Themen überflogen werden (anhand der Lehrplan-Gewichtung oder der Häufigkeit in Altklausuren). Bei BACK_TO_BACK: die Übung des zweiten Fachs vor die erste Prüfung legen. Prüfe den Plan mit dem Studierenden: ist er an einem schlechten Tag machbar? Lasse Spielraum, anstatt jeden Abend vollzustopfen.
### 4. Liefern
Fülle `templates/revision-plan.md`: die Übersichtstabelle, den Wochenplan, die Sitzungsroutine aus `references/study-techniques.md`, und zwei Check-in-Daten, um das Selbstvertrauen neu zu bewerten und das Skript erneut auszuführen.
## Beispielergebnis
Für `examples/winter-exams.csv` ab dem 16. November mit 3 h an Werktagen, 5 h an Samstagen, Sonntagen und dem 21. November frei: 25 Tage, 57 Sitzungen à 50 Minuten (47,5 h). Organische Chemie (Gewicht 5, Selbstvertrauen 2) und Mikroökonomie (4, 2) bekommen 15 bzw. 16 Sitzungen, Europäische Geschichte (3, 4) bekommt 6. Jedes Fach endet mit Übungsfragen und einem zeitbegrenzten Altklausuren-Test am Tag vor seiner Prüfung. Befunde: Statistik (10 Sitzungen für 8 Themen) und Europäische Geschichte (6 für 6) sind TIGHT, und Europäische Geschichte und Mikroökonomie sind BACK_TO_BACK am 7. und 8. Dezember.
## Regeln
- Plane mit den Stunden, die der Studierende wirklich hat, nicht mit denen, die er sich wünscht; schütze den Schlaf (keine Sitzungen spät in der Nacht vor Prüfungen).
- Jede Sitzung endet mit Abruf (Fragen, Blanko-Blatt-Erinnerung, Karteikarten), nicht nur mit erneutem Lesen oder Markieren.
- Behalte mindestens einen Ruhetag oder zwei halbe Tage pro Woche bei; Burnout kostet mehr als ein verlorener Tag.
- Plane nach jedem Check-in oder jeder Prüfung neu, anstatt einem kaputten Plan zu folgen.
- Mache keine benoteten Hausarbeiten für den Studierenden; hilf bei Planung und Lernmethoden. Wenn ein Studierender Anzeichen von starkem Stress oder Panik zeigt, ermutige ihn, mit der Studienberatung oder einem Arzt zu sprechen.
FILE:references/study-techniques.md
# Lern Techniken
Was in jeder Sitzung zu tun ist. Geordnet nach Stärke der Evidenz (Dunlosky et al. 2013, „Improving Students' Learning With Effective Learning Techniques“, bewertete Übungstests und verteiltes Üben als hohen Nutzen).
## Abrufübung (hoch)
Bringe Informationen aus dem Gedächtnis zurück, anstatt sie erneut zu lesen: beantworte Fragen, schreibe alles, was du erinnerst, auf ein leeres Blatt, prüfe dann gegen Notizen und fülle die Lücken in einer anderen Farbe. Karteikarten funktionieren, wenn du antwortest, bevor du umdrehst. Erst falsch zu liegen und dann zu korrigieren hilft auch beim Lernen.
## Verteilen (hoch)
Verteile Sitzungen zu einem Fach über viele Tage, anstatt in einem langen Block. Ein einfacher Wiederholungsrhythmus für jedes Thema: am nächsten Tag, nach 3 Tagen, nach einer Woche, dann vor der Prüfung. Der Stundenplan verschränkt Fächer über Tage; beginne jede Sitzung mit 5 Minuten Erinnerung an die vorherige Sitzung dieses Fachs, um das Verteilen einzubauen.
## Verschränkung (mittel)
Mische Problemtypen innerhalb eines Fachs (für Mathe und Naturwissenschaften: verschiedene Arten von Problemen in einem Satz, nicht 20 vom gleichen), damit du übst, die Methode zu wählen, was die Prüfung verlangt.
## Altklausuren (hoch für Prüfungen)
Mache mindestens eine vollständige Altklausur unter Zeitbedingungen vor jeder Prüfung, bewerte sie dann mit dem offiziellen Bewertungsschema und liste die verlorenen Punkte nach Thema. Das Skript legt eine am Tag vor jeder Prüfung; füge frühere hinzu, wenn Altklausuren verfügbar sind.
## Elaboration und Selbst-Erklärung (mittel)
Frage „Warum funktioniert das?“ und „Wie hängt das mit X zusammen?“, erkläre ein Konzept laut, als würdest du es unterrichten, zeichne eine Concept Map aus dem Gedächtnis.
## Geringer Wert für sich allein
Erneutes Lesen, Markieren und Notizen abschreiben fühlen sich produktiv an, bringen aber wenig langfristigen Nutzen. Verwende sie nur als ersten Durchgang vor der Abrufübung.
## Sitzungsroutine (50/10 Standard)
1. 5 min: Erinnerung aus dem Gedächtnis, was du letztes Mal für dieses Fach getan hast.
2. 30 min: Lerne oder übe ein Thema (Lernen + Abruf) oder mache Fragen (Übungsfragen).
3. 10 min: Schließe das Buch und teste dich selbst; markiere, was du verpasst hast.
4. 5 min: Schreibe drei Fragen auf, die du nicht beantworten konntest, für das nächste Mal.
5. 10 min Pause weg vom Bildschirm: bewegen, Wasser trinken.
Für kurze Aufmerksamkeitsspannen verwende 25/5-Sitzungen (--session-min 25 --break-min 5) und eine längere Pause alle vier.
## Schlaf, Essen und der Tag davor
Schlaf festigt das Gedächtnis; Durchmachen reduziert die Prüfungsleistung. Behalte die Nacht vor der Prüfung für leichte Wiederholung und Schlaf. Iss regelmäßige Mahlzeiten, bewege dich jeden Tag und behalte das Telefon während der Sitzungen in einem anderen Raum.
FILE:references/scheduling-rules.md
# Planungsregeln
Wie `scripts/revision_plan.py` den Stundenplan erstellt.
## Sitzungen pro Tag
Sitzungen, die in die täglichen Stunden passen: `floor((hours * 60 + break) / (session + break))`. Mit 50/10-Sitzungen: 3 h -> 3 Sitzungen, 5 h -> 5 Sitzungen. Ruhetage (--rest-day) und --off-Daten haben keine. An einem Prüfungstag sind nur die Hälfte der Sitzungen geplant (die Prüfung nimmt den Rest ein), und nur für spätere Prüfungen.
## Priorität und Ziel
- priorität = Gewicht x (6 - Selbstvertrauen). Gewicht 5, Selbstvertrauen 2 -> 20; Gewicht 3, Selbstvertrauen 4 -> 6.
- Ziel-Sitzungen = alle Sitzungen, die vor dieser Prüfung verfügbar sind x Priorität / Summe aller Prioritäten (mindestens 1).
Gewicht kann Credits oder eine Wichtigkeit von 1-5 sein; nur die Verhältnisse zählen, also verwende dieselbe Skala für jedes Fach.
## Auswahl jeder Sitzung
Für jede Sitzung wählt das Skript unter Fächern, deren Prüfung noch aussteht und die weniger als --max-same (Standard 2) Sitzungen an diesem Tag haben:
1. Fächer, die noch unter ihrem Ziel liegen, zuerst;
2. dann ein anderes Fach als die vorherige Sitzung (Verschränkung);
3. dann den höchsten verbleibenden Bedarf pro Tag, der bis zur Prüfung bleibt;
4. Gleichstände gehen an die höhere Priorität, dann die frühere Prüfung.
Der Tag vor einer Prüfung beginnt mit einer zeitbegrenzten Altklausur für dieses Fach.
## Sitzungstypen
- Lernen + Abruf: bis 60 % des Fachziels erreicht sind und mehr als 7 Tage vor seiner Prüfung.
- Gemischte Wiederholung: nach 60 % des Ziels, mehr als 7 Tage vorher.
- Übungsfragen: in den letzten 7 Tagen vor der Prüfung.
- Altklausur (zeitbegrenzt): der Tag vor der Prüfung.
## Befunde
| Code | Schweregrad | Regel | Typische Lösung |
|---|---|---|---|
| UNDER_COVERED | HIGH | Sitzungen < Themen | mehr Stunden, früherer Start, ertragsarme Themen überfliegen |
| TIGHT | MITTEL | Sitzungen < 1,5 x Themen | einen vollen Durchgang akzeptieren, oder Zeit von starken Fächern nehmen |
| BELOW_TARGET | MITTEL | geplant < 60 % des Ziels | die Prüfung ist früh; mit diesem Fach zuerst beginnen |
| BACK_TO_BACK | MITTEL | Prüfungen an aufeinanderfolgenden Tagen | Übung für die zweite Prüfung vorziehen |
| SAME_DAY | MITTEL | zwei Prüfungen an einem Tag | beide in der letzten Woche als einen Block behandeln |
| NO_REST_DAY | NIEDRIG | Plan > 10 Tage ohne Ruhetag oder freie Tage | --rest-day hinzufügen |
| LONG_DAYS | NIEDRIG | mehr als 8 h pro Tag | bei 5-6 fokussierten Stunden kappen |
## Abstimmung
- Mehr Zeit für ein Fach: Gewicht erhöhen oder Selbstvertrauen senken und erneut ausführen.
- Weniger Fachwechsel: --max-same 3.
- Uhrzeiten: --day-start 09:00 fügt Start- und Endzeiten hinzu, mit Pausen zwischen Sitzungen.
- Neu planen: nach jedem Check-in Selbstvertrauen und --start aktualisieren und erneut ausführen; abgeschlossene Prüfungen fallen aus der CSV heraus.
FILE:templates/revision-plan.md
# Wiederholungsplan: <Name>, <Prüfungssaison>
**Zeitraum:** <16. Nov bis 11. Dez 2026> **Stunden:** <3 h Werktage, 5 h Samstage> **Ruhe:** <Sonntage + 21. Nov>
**Sitzungen:** <57 x 50 min (47,5 h)> **Sitzungsrhythmus:** <50 min Lernen / 10 min Pause>
## Prüfungen und Prioritäten
| Fach | Prüfung | Gewicht | Selbstvertrauen | Themen | Geplante Sitzungen | Notizen |
|---|---|---|---|---|---|---|
| <Organische Chemie> | <Mi 2. Dez> | <5> | <2> | <9> | <15> | <Altklausur 1. Dez> |
## Woche 1: <16-22. Nov>
| Tag | Sitzung 1 | Sitzung 2 | Sitzung 3 | Sitzung 4 | Sitzung 5 |
|---|---|---|---|---|---|
| <Mo 16. Nov> | <16:00 Organische Chemie: Lernen> | <17:00 Mikroökonomie: Lernen> | <...> | | |
## Woche 2: <...>
<...>
## Sitzungsroutine
1. 5 min Erinnerung an die letzte Sitzung (leeres Blatt)
2. 30 min Lernen oder Üben eines Themas
3. 10 min Selbsttest, markiere die Fehler
4. 5 min: drei offene Fragen für das nächste Mal
5. 10 min Pause weg vom Bildschirm
## Vereinbarte Kompromisse
- <Statistik ist TIGHT: ein voller Durchgang, zweiter Durchgang nur bei Themen 5-8 (meiste Punkte in Altklausuren)>
- <Europäische Geschichte / Mikroökonomie hintereinander: Mikroökonomie-Übung bis 5. Dez erledigt>
## Check-ins
- <So 22. Nov>: Selbstvertrauen 1-5 pro Fach neu bewerten, den Planer erneut ausführen
- <So 29. Nov>: dasselbe, die letzten 10 Tage anpassen
## Wohlbefinden
- Schlaf: <bis 23:30 im Bett, kein Lernen nach 22:00 in der Nacht vor Prüfungen>
- Tägliche Bewegung: <30 min Spaziergang>
- Wenn es zu viel wird: <mit ... sprechen / Kontakt Studienberatung>
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
"""Exam revision timetable planner (Python 3 standard library only).
Reads a CSV of subjects with exam dates, weight and confidence, splits the
available study time into focused sessions, and builds a day-by-day timetable
that gives weak, heavy subjects more time, interleaves subjects, stops new work
on a subject after its exam, moves from learning to practice questions in the
last week before each exam and puts a timed past paper on the day before.
CSV columns (header required; ; or , separated):
subject, exam_date (YYYY-MM-DD), weight (1-5 or credits), confidence (1-5), topics (optional)
Usage:
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
Exit codes: 0 = plan fits, 1 = HIGH findings (not enough sessions), 2 = bad input.
"""
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}' must be YYYY-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("empty CSV")
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("missing columns: " + ", ".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"row {i}: weight, confidence and topics must be numbers")
if w <= 0:
raise InputError(f"row {i}: weight must be positive")
if not 1 <= c <= 5:
raise InputError(f"row {i}: confidence must be 1 (weak) to 5 (strong)")
if not r["subject"]:
raise InputError(f"row {i}: subject is empty")
subs.append({"subject": r["subject"], "exam": parse_date(r["exam_date"], f"row {i}: exam_date"),
"weight": w, "confidence": c, "topics": t})
if not subs:
raise InputError("no subjects in CSV")
return subs
def slots_for(hours, session, brk):
"""Number of sessions that fit in `hours` with a break between sessions."""
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 must be at least 15 minutes and break not negative")
for s in subs:
if s["exam"] <= start:
raise InputError(f"{s['subject']}: exam {s['exam']} is not after the start date {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 # the exam takes half the day
days.append((d, n))
d += dt.timedelta(days=1)
# target sessions: share of the slots available before each exam, by priority
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]
# the day before an exam: a timed past paper first
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
# subjects still below target first, then interleave (avoid repeating the previous subject)
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']} sessions for {s['topics']} topics; add hours, drop low-yield topics or start earlier"))
elif s["planned"] < 1.5 * s["topics"]:
findings.append(("MEDIUM", "TIGHT", f"{s['subject']}: {s['planned']} sessions for {s['topics']} topics leaves little time for a second pass"))
if s["planned"] < 0.6 * s["target"]:
findings.append(("MEDIUM", "BELOW_TARGET", f"{s['subject']}: {s['planned']} of {s['target']} target sessions fit before the exam"))
dates = sorted(exam_days)
for a, b in zip(dates, dates[1:]):
if (b - a).days <= 1:
findings.append(("MEDIUM", "BACK_TO_BACK", f"exams on {a} ({', '.join(exam_days[a])}) and {b} ({', '.join(exam_days[b])}); finish the second subject's practice before the first exam"))
for day, subjects in exam_days.items():
if len(subjects) > 1:
findings.append(("MEDIUM", "SAME_DAY", f"{len(subjects)} exams on {day}: {', '.join(subjects)}"))
if rest_day is None and len(days) > 10 and not off:
findings.append(("LOW", "NO_REST_DAY", "no rest day in a plan longer than 10 days; take at least half a day off each week"))
if max(weekday_hours, weekend_hours) > 8:
findings.append(("LOW", "LONG_DAYS", "more than 8 hours of revision a day rarely stays productive; keep 5-6 focused hours"))
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 = ["# Revision timetable", "",
f"{s['start']} to {s['last_exam']}: {s['days']} days, {s['sessions']} sessions of {s['session_min']} min ({s['study_hours']} h of focused study), {s['break_min']} min breaks",
"", "| Subject | Exam | Weight | Confidence | Priority | Topics | Target | Planned | Hours |", "|---|---|---|---|---|---|---|---|---|"]
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 += ["", "## Day by day", ""]
for t in p["timetable"]:
head = f"- **{t['dow']} {t['date']}**" + (f" (EXAM: {', '.join(t['exams'])})" if t["exams"] else "")
if not t["sessions"]:
out.append(head + ": rest")
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 += ["", "## Findings"]
out += [f"- {f['severity']} {f['code']}: {f['message']}" for f in p["findings"]] or ["- none"]
out += ["", "Start each session with 5 minutes of recall from memory on the previous session of that subject, and end with 3 questions you could not answer."]
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 of 50+10 = 3", slots_for(3, 50, 10) == 3)
check("slots: 50 min fits exactly 1", slots_for(50 / 60, 50, 10) == 1)
check("slots: under one session = 0", slots_for(0.5, 50, 10) == 0)
check("slots: 25+5 in 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("no sessions on or after exam day", all(t["date"] < "2026-01-08" for t in p["timetable"]))
check("day before exam starts with past paper", p["timetable"][-1]["sessions"][0]["kind"] == "Past paper (timed)")
check("practice questions in last 7 days", 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("weak subject gets more sessions", pl["Weak"] > 3 * pl["Strong"])
check("priority = weight x (6 - confidence)", 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("max 2 sessions of one subject per day", all(
sum(1 for x in t["sessions"] if x["subject"] == subj) <= 2 for t in p["timetable"] for subj in "AB"))
check("subjects interleaved while both need time", 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("rest day empty", 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("off day empty", 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("exam day: half the slots, other subject only", 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 HIGH", 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 and 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("clock times with --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("semicolon CSV + decimal comma", subs[0]["weight"] == 4.5 and subs[0]["topics"] == 9)
for bad, why in [("subject,exam_date\nA,2026-01-01\n", "missing columns"),
("subject,exam_date,weight,confidence\nA,2026-13-01,1,3\n", "bad date"),
("subject,exam_date,weight,confidence\nA,2026-01-01,1,9\n", "confidence out of range"),
("subject,exam_date,weight,confidence\nA,2026-01-01,x,3\n", "non-number")]:
try:
read_subjects(bad); check("rejects " + why, False)
except InputError:
check("rejects " + why, True)
try:
plan([S("A", D(2026, 1, 1))], D(2026, 1, 1)); check("rejects exam not after start", False)
except InputError:
check("rejects exam not after start", True)
passed = sum(res)
print(f"{passed}/{len(res)} passed")
return 0 if passed == len(res) else 1
def main():
ap = argparse.ArgumentParser(description="Exam revision timetable planner")
ap.add_argument("csv", nargs="?", help="subjects CSV")
ap.add_argument("--start", help="first revision day YYYY-MM-DD (default today)")
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="focused session length (default 50)")
ap.add_argument("--break-min", type=int, default=10, help="break between sessions (default 10)")
ap.add_argument("--rest-day", choices=DAYS, help="weekly day off")
ap.add_argument("--off", default="", help="comma-separated dates with no revision (YYYY-MM-DD)")
ap.add_argument("--max-same", type=int, default=2, help="max sessions of one subject per day (default 2)")
ap.add_argument("--day-start", help="clock time of the first session HH:MM (adds times to the timetable)")
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("give a CSV, or --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 must be 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"error: {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())
Melde dich an, um den vollständigen Prompt zu sehen
Weiter mit:
Mit der Anmeldung akzeptierst du unsere Nutzungsbedingungen und Datenschutz
Verwendung
Dieser Prompt ist für die Verwendung mit education gedacht. Kopiere den Inhalt oben und füge ihn in dein bevorzugtes KI-Tool ein.
Für beste Ergebnisse passe die Platzhalter (eckige Klammern oder Großbuchstaben) an deine Anforderungen an.
Diskussion
0 Kommentare