if mit String aus .txt (plz help)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
CIMA-PYTHON
User
Beiträge: 4
Registriert: Donnerstag 30. Mai 2019, 12:14

Liebe Forum Mitglieder und alle die das lesen.Ich habe eine Frage zum Thema Strings aus einer Text Datei vergleichen.
Mein Beispiel ist ein Vokabeltrainer in den man seine Vokabeln einträgt und diese dann aus der Text Datei abgefragt werden(ich möchte keine Liste verwenden, da diese nicht gespeichert wird nachdem man das Script wieder schließ/abbricht). Doch die if abfrage funktioniert nicht. Ich würde mich sehr über Hilfe freuen, denn ich sitze schon sehr lang an diesem Problem.
Datei de.txt/de_voc:
Hallo
Apfel
Buch
(oder ['Hallo\n', 'Apfel\n', 'Buch\n'])
Datei en.txt/en_voc:
hello
apple
book
(oder ['hello\n', 'apple\n', 'book\n'])

Code: Alles auswählen

#python 3
import random

def eingabe():
    while True:
        voc_de = open("de.txt", "a")
        de = input("Deutsch:")
        if de == "stop":
            return
        voc_de.write(str(de))
        voc_de.write("\n") # für eine neue Zeile
        voc_de.close()
        voc_en = open("en.txt", "a")
        en = input("Englisch:")
        if en == "stop":
            return
        voc_en.write(str(en))
        voc_en.write("\n")
        voc_en.close()

def abfrage():
    while True:
        de_voc = open("de.txt", "r").readlines() #evtl. read/readline
        en_voc = open("en.txt", "r").readlines() #evtl. read/readline
        z = random.randint(0, len(de_voc)-1)
        ab = de_voc[z]
        print("Übersetze:", ab) #die Abfrage von ab/de_voc[z]
        ub = input("Übersetzung:") #der user Input
        if str(ub) == en_voc[z]: # mein Problem,die if Bedingung funktioniert nicht (nur wenn die komplette Datei abgefragt wird(ohne z )und ich dann halt auch ['hello', .....]angebe)
            print("Richtig")
        else:
            print("Falsch")
while True:
    befehl = input("befehle(eingabe/abfrage):")
    if befehl == "eingabe":
        eingabe()
    elif befehl == "abfrage":
        abfrage()
    else:
        print("error")
Ich hoffe ich habe mich richtig ausgedrückt und der Code ist nachvollziehbar und verständlich
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@CIMA-PYTHON: Das Problem sind die Zeilenendezeichen. Du siehst ja selbst in der Ausgabe der eingelesenen Liste(n), dass da an jedem Wort am Ende ein '\n' steht. Und 'apple' == 'apple\n' ist nun mal `False`. Du musst beim Einlesen diese Zeilenenden mit der `strip()`-Methode entfernen.

Diese beiden ”parallelen” Dateien sind aber auch nicht gut. Das ist zu fehleranfällig. Zusammengehörende Daten sollte man auch zusammen speichern. Zum Beispiel in einer Datei mit dem `csv`-Modul je eine Spalte für Deutsch und Englisch.

Bei der Eingabe der Worte öffnest Du die Datei für Deutsch schon vor der Eingabe, das heisst wenn der Benutzer 'stop' eingibt, dann wird die Datei nicht wieder geschlossen. Wenn es geht, solltest Du Dateien immer mit der ``with``-Anweisung öffnen, damit Du einen garantieren Punkt im Programmablauf hast, an dem die Datei geschlossen wird.

Textdateien sollte man immer mit einer expliziten Kodierungsangabe öffnen. UTF-8 bietet sich an wenn man die Wahl selbst treffen kann, weil dort jedes Unicodezeichen kodiert und gespeichert werden kann und in der Datei für die meisten der bei uns gebräuchlichen Zeichen trotzdem nur ein Byte belegt wird.

'stop' ist eine ungünstige Eingabe für den Abbruch, denn das ist ein Wort das man vielleicht auch ganz gerne in der Übersetzung haben möchte. Man sollte als Abbruchkriterium also etwas wählen das kein Wort ist. Eine Leereingabe würde sich anbieten. Wenn der Benutzer einfach die Eingabetaste drückt ohne ein Wort einzugeben ist das doch ein ganz gutes Zeichen das er nichts mehr eingeben möchte.

`input()` liefert bereits eine Zeichenkette – keiner der `str()`-Aufrufe in dem Programm macht Sinn.

`de_voc`, `voc_de`, `ab`, `ub`, `z`, und so weiter sind wirklich schlechte Namen. Ein Name sollte dem Leser deutlich vermitteln was der Wert dahinter im Kontext des Programms bedeutet. Man sollte da nicht raten müssen. Also keine kryptischen Abkürzungen. ISO-Länderkürzel sind noch okay, weil das gängige, standardisierte Abkürzungen sind, aber `voc`? Das ist ein Sounddateiformat das in den 90ern mal populär war. Wenn Du `vocabulary_file` meinst, dann schreib auch genau das.

Die Dateien werden bei der `abfrage()` in jedem Schleifendurchlauf aufs neue eingelesen, statt *einmal* *vor* der Schleife. Zudem werden die Dateien geöffnet, aber nicht wieder geschlossen.

Statt `randint()` könnte man `randrange()` verwenden und sich da das -1 sparen. Aber eigentlich möchte man die Daten in *einer* Liste haben und daraus mit `random.choice()` auswählen. Beziehungsweise die Daten nach dem einlesen mit `random.shuffle()` mischen und dann mit einer ``for``-Schleife über die Daten gehen, damit auch jede Vokabel dran kommt.

Spätestens beim einlesen sollte man die Daten in *einer* Liste zusammenführen. Wenn Du auf zwei Dateien bestehst, was wie gesagt nicht wirklich gut ist, dann bietet sich die `zip()`-Funktion an.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
CIMA-PYTHON
User
Beiträge: 4
Registriert: Donnerstag 30. Mai 2019, 12:14

Vielen Dank für die schnelle Antwort. Ich versuche es morgen zu testen(keine Zeit, Schule) Schönen Tag dir noch und hoffentlich bekomme ich es richtig hin :)
Antworten