lehrkraefte:blc:informatik:glf22:python:woertlitrainer

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
lehrkraefte:blc:informatik:glf22:python:woertlitrainer [2022/12/12 08:36]
Ivo Blöchliger [Frei wählbare Datei]
lehrkraefte:blc:informatik:glf22:python:woertlitrainer [2022/12/16 07:02] (current)
Ivo Blöchliger [Python Snippets]
Line 160: Line 160:
 <hidden Lösungsvorschlag> <hidden Lösungsvorschlag>
 <code pyton voci-mit-dict-von-datei.py> <code pyton voci-mit-dict-von-datei.py>
 +import sys 
 +import os
 +import json
  
 +##################
 +# Daten einlesen #
 +##################
 +
 +# Datei bestimmen (default oder von der Kommandozeile)
 +datei = "voci.json"
 +if len(sys.argv)>1:  # Falls es ein zusätzliches Kommandozeilenargument gibt
 +    datei = sys.argv[1]
 +print(f"Versuche Daten aus der Datei {datei} einzulesen")
 +if not os.path.exists(datei):   # Falls die Datei nicht existiert, abbrechen
 +    print(f"Sorry, die Datei {datei} existiert nicht!")
 +    exit(-1)  # Abbruch mit Fehler
 +
 +# Daten einlesen
 +with open(datei, "r") as f:   # Datei zum Lesen öffnen
 +  voci = json.loads(f.read())       # Inhalt lesen, interpretieren und in die Variable voci speichern.
 + 
 +##########
 +# Lernen #
 +##########
 +
 +# Wiederholen, für jedes paar in der Liste
 +for paar in voci:
 +    ok = False # Benutzer hat noch nicht richtig geantwortet
 +    anzahlfehler = 0
 +    while not ok:
 +        # Wort auf Deutsch anzeigen
 +        print(f"Übersetze: {paar['d']}")
 +        if anzahlfehler>2:
 +            print(f"   Hinweis: {paar['f']}")
 +        # Eingabe vom Benutzer
 +        eingabe = sys.stdin.readline().strip()
 +
 +        if eingabe==paar['f']:  # gleich dem Fremdwort?
 +            ok  = True
 +        else:
 +            anzahlfehler = anzahlfehler + 1
 </code> </code>
 </hidden> </hidden>
Line 196: Line 236:
 for i in range(10):  # 10 mal wiederholen, zum Testen for i in range(10):  # 10 mal wiederholen, zum Testen
     # Vokabular sortieren, wobei ein Eintrag mit score+zufallszahl bewertet wird:     # Vokabular sortieren, wobei ein Eintrag mit score+zufallszahl bewertet wird:
-    voci = sorted(voci, key = lambda eintrag: eintrag['s']+random.random())+    voci.sort(key = lambda eintrag: eintrag['s']+random.random())
     print(f"Erster Eintrag ist jetzt: {voci[0]}")     print(f"Erster Eintrag ist jetzt: {voci[0]}")
 </code> </code>
Line 208: Line 248:
   * Wenn das Programm beendet wird, sollen die Daten wieder geschrieben werden, damit die Scores erhalten bleiben.   * Wenn das Programm beendet wird, sollen die Daten wieder geschrieben werden, damit die Scores erhalten bleiben.
   * Erstellen Sie eine JSON-Datei mit dem aktuellen Französisch-Vokubular (gerne auch kollaborativ, so dass jeder z.B. 10 Wörter einträgt und dann die Dateien vereinigt werden).   * Erstellen Sie eine JSON-Datei mit dem aktuellen Französisch-Vokubular (gerne auch kollaborativ, so dass jeder z.B. 10 Wörter einträgt und dann die Dateien vereinigt werden).
 +
 +<hidden Lösungsvorschlag>
 +<code python voci-v1.py>
 +import sys 
 +import os
 +import json
 +import random
 +
 +##################
 +# Daten einlesen #
 +##################
 +
 +# Datei bestimmen (default oder von der Kommandozeile)
 +datei = "voci.json"
 +if len(sys.argv)>1:  # Falls es ein zusätzliches Kommandozeilenargument gibt
 +    datei = sys.argv[1]
 +print(f"Versuche Daten aus der Datei {datei} einzulesen")
 +if not os.path.exists(datei):   # Falls die Datei nicht existiert, abbrechen
 +    print(f"Sorry, die Datei {datei} existiert nicht!")
 +    exit(-1)  # Abbruch mit Fehler
 +
 +# Daten einlesen
 +with open(datei, "r") as f:   # Datei zum Lesen (read) öffnen
 +  voci = json.loads(f.read())       # Inhalt lesen, interpretieren und in die Variable voci speichern.
 +
 +# Scores hinzufügen, falls nötig
 +for paar in voci:
 +  if not "s" in paar:  # Gibt es den Schlüssel s bereits? Falls nein, hinzufügen.
 +    paar["s"] = 0
 +
 +##########
 +# Lernen #
 +##########
 +
 +# Wiederholen, bis der Benutzer abbricht
 +programmEnde = False
 +print("Hinweis: Durch Eingabe von 'x' kann das Programm beendet werden.")
 +while not programmEnde:  # Endlos-Schleife
 +    # Wörter Sortieren:
 +    voci = sorted(voci, key = lambda eintrag: eintrag['s']+random.random())
 +    # Aktuelles paar ist das erste in der Liste
 +    paar = voci[0]
 +    # Abfrage vorbereiten
 +    ok = False # Benutzer hat noch nicht richtig geantwortet
 +    anzahlfehler = 0
 +    while not ok:  # Wiederholen, bis der Benutzer richtig geantwortet hat.
 +        # Wort auf Deutsch anzeigen
 +        print(f"Übersetze: {paar['d']}     (score {paar['s']})")
 +        if anzahlfehler>2:
 +            print(f"   Hinweis: {paar['f']}")
 +        # Eingabe vom Benutzer
 +        eingabe = sys.stdin.readline().strip()
 +        if eingabe=="x":
 +            programmEnde = True
 +            break     # innere while-Schlaufe verlassen
 +
 +        if eingabe==paar['f']:  # gleich dem Fremdwort?
 +            ok  = True
 +            if anzahlfehler==0:
 +                paar['s']+=2
 +            elif anzahlfehler==1:
 +                paar['s']+=1
 +            else:
 +                paar['s'] -= 1
 +                if (paar['s']<0):
 +                    paar['s']=0
 +        else:
 +            anzahlfehler = anzahlfehler + 1
 +
 +# Daten speichern:
 +with open(datei, "w") as f:   # Datei zum Schreiben (write) öffnen
 +  f.write(json.dumps(voci, indent=2))    # Daten in Datei schreiben
 +  f.write("\n")
 +</code>
 +</hidden>
 </WRAP> </WRAP>
  
 +====== Besserer Programmierstil ======
 +Im Moment ist das Programm ein schon ziemlich unübersichtlicher Klumpen. Um das Programm übersichtlicher zu gestalten, werden wir einzelne Programmteile in Funktionen auslagern, damit das Programm am Schluss in 3 Zeilen passt:
 +
 +<code python>
 +voci, datei = daten_einlesen()
 +abfragen(voci)
 +daten_speichern(voci, datei)
 +</code>
 +
 +Dazu gibt es einen [[https://fginfo.ksbg.ch/~ivo/videos/informatik/22-23/09-woertli-trainer-refactoring.mp4|Screencast]], oder als [[https://bldsg-my.sharepoint.com/:v:/g/personal/ivo_bloechliger_ksbg_ch/EcT9M_iPJspIrRz0shkQa54BrZ2OdumLJKvhopAFmU3Bnw?e=bpmcYw|SharePoint-Stream]] (neu auch für jeden Internauten, zumindest für 18 Monate)
 +
 +<hidden Lösungsvorschlag>
 +<code python voci-refactored.py>
 +import sys 
 +import os
 +import json
 +import random
 +
 +##################
 +# Daten einlesen #
 +##################
 +
 +def dateinamen_bestimmen():
 +    datei = "voci.json"
 +    if len(sys.argv)>1:  # Falls es ein zusätzliches Kommandozeilenargument gibt
 +        datei = sys.argv[1]
 +    print(f"Versuche Daten aus der Datei {datei} einzulesen")
 +    if not os.path.exists(datei):   # Falls die Datei nicht existiert, abbrechen
 +        print(f"Sorry, die Datei {datei} existiert nicht!")
 +        exit(-1)  # Abbruch mit Fehler
 +    return datei
 +
 +
 +def scores_hinzufuegen(voci):
 +    for paar in voci:
 +        if not "s" in paar:  # Gibt es den Schlüssel s bereits? Falls nein, hinzufügen.
 +            paar["s"] = 0
 +
 +
 +def daten_einlesen():
 +    # Datei bestimmen (default oder von der Kommandozeile)
 +    dateinamen = dateinamen_bestimmen()
 +    # Daten einlesen
 +    with open(dateinamen, "r") as f:   # Datei zum Lesen (read) öffnen
 +        voci = json.loads(f.read())       # Inhalt lesen, interpretieren und in die Variable voci speichern.
 +    # Scores hinzufügen, falls nötig
 +    scores_hinzufuegen(voci)
 +    return voci, dateinamen
 +
 +
 +##########
 +# Lernen #
 +##########
 +
 +def hole_eingabe(paar, anzahlfehler):
 +    # Wort auf Deutsch anzeigen
 +    print(f"Übersetze: {paar['d']}     (score {paar['s']})")
 +    if anzahlfehler>2:
 +        print(f"   Hinweis: {paar['f']}")
 +    # Eingabe vom Benutzer
 +    return sys.stdin.readline().strip()
 +
 +
 +def wort_korrekt(eingabe, paar, anzahlfehler):
 +    if eingabe != paar['f']:
 +        return False   # Funktion sofort beenden
 +    # Eingabe ist korrekt
 +    if anzahlfehler>1:
 +        paar['s'] -= 1
 +        if (paar['s']<0):
 +            paar['s']=0
 +        return True
 +    paar['s'] += 2 - anzahlfehler
 +    return True
 +
 +
 +def wort_abfragen(paar):
 +    anzahlfehler = 0
 +    while True:  # Endlos Schleife
 +        eingabe = hole_eingabe(paar, anzahlfehler)
 +        if eingabe=="x":
 +            return True   # Programmabbruch
 +        if wort_korrekt(eingabe, paar, anzahlfehler):
 +            return False  # Wort korrekt, aber Programm nicht beenden
 +        anzahlfehler = anzahlfehler + 1
 +
 +
 +def wort_bestimmen(voci):
 +    voci.sort(key = lambda eintrag: eintrag['s']+random.random())
 +    # Aktuelles paar ist das erste in der Liste
 +    return voci[0]
 +
 +
 +def abfragen(voci):
 +    while True: # Endlosschleife
 +        paar = wort_bestimmen(voci)
 +        programmAbbruch = wort_abfragen(paar)
 +        if programmAbbruch:
 +            return
 +
 +
 +def daten_speichern(voci, dateinamen):
 +    with open(dateinamen, "w") as f:   # Datei zum Schreiben (write) öffnen
 +        f.write(json.dumps(voci, indent=2))    # Daten in Datei schreiben
 +        f.write("\n")
 +
 +
 +voci, dateiname = daten_einlesen()
 +abfragen(voci)
 +daten_speichern(voci, dateiname)
 +</code>
 +</hidden>
  
  • lehrkraefte/blc/informatik/glf22/python/woertlitrainer.1670830599.txt.gz
  • Last modified: 2022/12/12 08:36
  • by Ivo Blöchliger