Einführung
Speichere stabile Antworten und mache ausschließlich Fehler dieser Runde zu einer unabhängigen Übung. Du brauchst die bisherigen Quizkonzepte sowie Python-Funktionen, Listen, Dictionaries, Bedingungen und Schleifen. Diese Einheit stellt die drei früheren Regeln eigenständig bereit und benötigt keine Dateien oder Prozesse einer vorherigen Einheit.
Verwende WebIDE Terminal → New Terminal (bei schmalem Fenster More). Bearbeite nur logic.py; bewahre engine.py, quiz.py und bank.json. Geschätzte Lese- und Übungszeit: 35 Minuten, keine gemessene Anfängerzeit.
Abgegebene Antworten als JSON speichern
In diesem Schritt speicherst du eine echte Runde, ohne Antworten an Bildschirmpositionen zu binden. Die vorbereitete Engine liefert eine Liste mit ausschließlich abgegebenen question_id/option_id-Paaren. Sie übernimmt Rückmeldung und Punktestand; die Aufzeichnung enthält weder eine selbst gemeldete Richtigkeit noch Bildschirmnummern.
Beginne im WebIDE-Terminal:
cd /home/labex/project
json.dump schreibt Python-Listen und Dictionaries als JSON. with open(..., "w", encoding="utf-8") öffnet eine Textdatei zum Schreiben und schließt sie anschließend. UTF-8 macht Text portabel; ensure_ascii=False hält Unicode lesbar und indent=2 erleichtert das Lesen. stream.write("\n") beendet die Datei mit einem Zeilenumbruch. Die Hülle {"answers": answers} kennzeichnet die Liste.
Das vollständige Here-Dokument bewahrt die drei vorbereiteten Regeln und ergänzt die Speicherfunktion. > ersetzt logic.py; das zitierte <<'PY' schreibt wörtlichen Text bis zum abschließenden PY. Die Übungsfunktion folgt im nächsten Schritt.
cat > logic.py <<'PY'
import json
def choose_questions(questions, count, rng):
return rng.sample(questions, min(count, len(questions)))
def move_options(question, rng):
options = question["options"].copy()
rng.shuffle(options)
return options
def read_answer(options, ask, tell):
while True:
text = ask("Answer (number or q): ").strip()
if text.lower() == "q":
return None
for position, option in enumerate(options, start=1):
if text == str(position):
return option["option_id"]
tell("Enter one displayed number, or q to stop.")
def save_answers(path, answers):
with open(path, "w", encoding="utf-8") as stream:
json.dump({"answers": answers}, stream, ensure_ascii=False, indent=2)
stream.write("\n")
PY
--ordered bewahrt die bekannte Fragen-/Optionsreihenfolge; --output benennt eine neue Aufzeichnung. Vorhandene Ausgabepfade werden vor Spielbeginn abgelehnt, um frühere Aufzeichnungen zu schützen. Beantworte zwei Fragen: 1 bei sky (richtig), dann 1 bei tide (falsch).
python3 quiz.py bank.json --ordered --count 2 --output round.json
Score: 1/2 answered
Saved round.json
cat zeigt die tatsächliche Aufzeichnung:
cat round.json
Sie enthält sky/sun und tide/sun. Dieselbe Options-ID hat in beiden Fragen unterschiedliche Bedeutung. Bewahre diese ursprüngliche Runde. Bei versehentlichem Wiederholen ist der Fehler wegen vorhandener Ausgabe erwartet: Verwende für zusätzliche Versuche einen neuen Dateinamen, statt sie zu überschreiben. Bei falsch geschriebenem Quelldateinamen prüfe ls und wiederhole den richtigen Pfad; Quiz error: ... ist keine gespeicherte Runde.
Nur Fehler dieser Runde erneut üben
In diesem Schritt ermittelst du Fehler erneut anhand der echten richtigen ID jeder Frage. Ein Dictionary ordnet beantworteten Frage-IDs die ausgewählten Options-IDs zu. Nimm eine Frage nur auf, wenn sie beantwortet wurde und die Antwort von ihrem eigenen correct_option_id abweicht. Richtige und unbeantwortete Fragen bleiben draußen. Die Liste bewahrt ganze Frageobjekte. In {answer["question_id"]: answer["option_id"] for answer in answers} besucht der Teil nach for jede Antwort; der Schlüssel/Wert-Teil davor baut jeweils einen Dictionary-Eintrag. Das ist eine Dictionary-Comprehension. In [question for question in questions if ...] besucht for jede Frage und if behält passende Objekte: eine List-Comprehension. and verlangt beide Bedingungen: Eine Antwort existiert und ist falsch. So zählt eine unbeantwortete Frage nicht als Fehler. >> hängt an, ohne vorhandene Regeln zu ersetzen:
cat >> logic.py <<'PY'
def wrong_questions(questions, answers):
selected = {answer["question_id"]: answer["option_id"] for answer in answers}
return [question for question in questions
if question["question_id"] in selected
and selected[question["question_id"]] != question["correct_option_id"]]
PY
--practice liest die ursprüngliche Runde; --output schreibt eine getrennte neue Aufzeichnung. Wiederholt werden alle und nur die Fehler dieser Runde, kein angesammelter Verlauf. Führe aus:
python3 quiz.py bank.json --practice round.json --output retry.json
Nur tide erscheint. Wähle die angezeigte Nummer für Moon; ihre Position kann wechseln. Das Ergebnis ist Score: 1/1 answered. Prüfe beide unabhängigen Aufzeichnungen:
cat round.json retry.json
Das Original enthält weiterhin tide/sun, die Wiederholung tide/moon. Die Bank ist unverändert. Erstelle nun eine vollständig richtige Runde. Die Anzahl ist positiv und die Auswahl durch min(count, len(questions)) begrenzt; 100 stellt jede der drei Fragen einmal.
python3 quiz.py bank.json --ordered --count 100 --output perfect.json
Gib 1, 2, 2 für sky, tide und roots ein. Übe anschließend diese Runde:
python3 quiz.py bank.json --practice perfect.json --output empty.json
No mistakes to practice.
Score: 0/0 answered
Saved empty.json
Eine leere Fehlermenge ist gültig. Starte zuletzt eine neue Runde und gib q ein, bevor du eine Antwort abgibst:
python3 quiz.py bank.json --output stopped.json
Der Punktestand ist 0/0; stopped.json enthält eine leere answers-Liste. Die verlassene Frage darf dort nicht als falsch gespeichert sein. Bewahre alle fünf Aufzeichnungen. Falls beim Bearbeiten ein Syntaxfehler entstand, wiederhole den vollständigen Block des Schritts. Da Schritt 1 die Datei ersetzt, führe danach erneut den Anhängeblock aus Schritt 2 aus. Bewahre vorhandene Aufzeichnungen und nutze für weitere Spiele neue Namen.
Zusammenfassung
Du hast tatsächlich abgegebene ID-Paare gespeichert, die ursprüngliche Runde bewahrt und eine unabhängige Fehlerübung erstellt, einschließlich gültiger leerer und abgebrochener Runden.



