Fehler in eine Übungsrunde verwandeln

PythonBeginner
Jetzt üben

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.