Ein Latein-Quiz als hervoragende Gelegenheit, die Leichtigkeit der Programmierung mit Python zu demonstrieren

Auch wer mit Latein nicht allzu viel am Hut hat, sollte sich das folgende Beispiel anschauen bzw. umsetzen, da man natürlich nicht nur Zitate auf Latein abfragen kann, sondern beliebige andere Themen. In erster Linie ist es aber (Vorsicht Eigenlob) ein gelunges Beispiel, dass die Leichtigkeit der Python-Programmierung und den flexiblen Umgang mit Arrays veranschaulicht.

Es kommen keine Hashtables vor, keine Klassen, keine Regexes, keine exotischen Module, sondern nur die „Basics“.

Ausgangspunkt ist eine Textdatei mit einer Reihe von Zeilen. Jede Zeile enthält ein Zitat auf Latein, einen Doppelpunkt und die deutsche Übersetzung:

Abyssus abyssum invocat:Ein Fehler zieht den anderen nach sich.
Ad absurdum:Etwas als unsinnig nachweisen.
Alea iacta est:Der Würfel ist gefallen (Zitat von Caesar)

Die Anzahl der Zeilen spielt keine Rolle. WIchtig ist lediglich, dass pro Zeile nur ein Doppelpunkt vorkommen darf.

Auf dieser Textdatei soll ein Quiz gemacht werden. Das bedeutet, dass z.B. 10 Fragen ausgewählt werden. Jede Frage besteht aus einem lateinischen Zitat und vier (willkürlich) Antworten, von denen jeweils eine richtig ist. Also der klassische Multiplechoice-Test.

Die Programmierherausforderung besteht darin, dass z.B. zehn Zitate ausgewählt und pro Zitat z.B. vier Antworten und die Information, welche der vier Antworten richtig ist. Eine kleine Schwierigkeitssteigerung besteht darin, dass keine der vier Antworten doppelt vorkommen und die richtige Antwort natürlich dabei sein muss. Diese darf aber nicht immer die erste Antwort sein, sondern xmuss ebenfalls zufällig über die vier Antworten verteilt werden.

Wie das folgende Listing zeigt, ist die Umsetzung gar nicht sooo schwer, wenn man bereits etwas „pythonisch“ denkt und von der Flexiblität beim Umgang mit Arrays bzw. Listen und den sehr praktischen List Comprehensions Gebrauch macht.

Da ich wie sooft nicht die Zeit habe, die Schritte einzeln vorzustellen, paste ich zunächst das gesamte Listing in den Blog-Eintrag. Das meiste sollte selbsterklärend sein. Falls es Fragen geben sollte, stehe ich natürlich zur Verfügung und helfe mit Erklärungen aus.

Wie immer gibt es Raum für Verbesserungen. So müsste es eine Option geben, um die „Richtung“ der Übersetzung festlegen zu können. Die Anzahl der Fragen müsste variabel und wie bei jedem guten Quiz müsste es eine Option geben, die bewirkt, dass alle falsch beantworten Fragen solange wiederholt werden bis es keine falschen Antworten mehr gab.

Noch netter wäre es natürlich, wenn das Programm keine Konsolenanwendung, sondern eine App wäre. Dann wäre es aber sehr viel einfacher, sie anstatt mit Python mit ein wenig JavaScript als reine Browser-App umzusetzen. Falls doch Python ins Spiel kommen soll, könnten die Fragen über eine Flask-Webapp zur Verfügung gestellt werden. Aber dann wäre es wieder richtige Programmierung und genau darum soll es mit dem kleinen Beispiel nicht gehen.

# Ein Latein-Merkquiz
import os
import random

basePfad = os.path.dirname(__file__)
txtPfad = os.path.join(basePfad, "LateinZitate.txt")

zitate = []
with open(txtPfad, encoding="UTF-8") as fh:
    for zitat in fh:
        if zitat[-1] == "\n":
            zitat = zitat[:-1]
        zitate.append(zitat.split(":"))

anzahl = 10
fragen = []

for i in range(1, anzahl+1):
    while True:
        z = random.randint(0, len(zitate)-1)
        frage = zitate[z][0]
        if len([f for f in fragen if f[0] == frage]) == 0:
            antworten = ["","","",""]
            aIndex = random.randint(0, 3)
            antworten[aIndex] = zitate[z][1]
            # Drei weitere Antworten suchen, die nicht gleich der Frage sind
            for j in [k for k in range(0,4) if k != aIndex]:
                while True:
                    z1 = random.randint(0, len(zitate)-1)
                    antwort = zitate[z1][1]
                    if not antwort in antworten:
                        break
                antworten[j] = antwort
            fragen.append((frage, antworten, aIndex))
            break
print(f"Das Quiz ist mit {anzahl} Fragen bereit.")

print(fragen)

anzahlRichtig = 0
anzahlFalsch = 0

for i in range(1, anzahl):
    print("Was bedeutet %s?" % fragen[i][0])
    for j, antwort in enumerate(fragen[i][1]):
        print(chr(j+65) + ". " + antwort)
    a = input("A,B,C oder D oder Q für Abbruch?")
    if a == "Q":
        break
    antwort = fragen[i][2]
    if ord(a)-65 == antwort:
        print("Die Antwort war richtig!")
        anzahlRichtig += 1
    else:
        print("Leider falsch!")
        print("Richtig wäre %s" % fragen[i][1][antwort])
        anzahlFalsch += 1

print(f"Richtige Antworten: {anzahlRichtig} Falsche Antworten: {anzahlFalsch} - Deine Quote: {(anzahlRichtig/anzahl):.0%}")