Problem mit Wörterbuch

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
J4RVIS
User
Beiträge: 4
Registriert: Samstag 26. April 2014, 15:25

Code: Alles auswählen

# -*- coding: utf-8 -*-
fobj = open("vokabeln.txt", "r")
fobj.close()

woerter = {}

fobj = open("vokabeln.txt", "r") 
for line in fobj:
    line = line.strip()
    zuordnung = line.split("-")
    woerter[zuordnung[0]] = zuordnung[1] #0 = Französisches Wort; 1 = Deutsches Wort
fobj.close()

while True: 
    wort = raw_input("Geben Sie ein Wort ein: ") 
    if wort in woerter: 
        print "Das deutsche Wort lautet:", woerter[wort] 

    else:
        woerter = {}
        
        fobj = open("vokabeln.txt", "r") 
        for line in fobj:
            line = line.strip()
            zuordnung = line.split("-")
            woerter[zuordnung[1]] = zuordnung[0] #1 = Französisches Wort; 0 = Deutsches Wort
            fobj.close()
   
        if wort in woerter: 
            print "Das französische Wort lautet:", woerter[wort]
        else:
                print "Das Wort ist unbekannt."
Der Spaß stellt ein einfaches Wörterbuch dar. Oder sollte er zumindest :D In einer txt sind die Übersetztungen in folgender Form gespeichert.

Code: Alles auswählen

un site-eine Website
Die Übersetztung von Französisch in Deutsch funktioniert tadellos, aber sobald ich es andersherumversuche bekomm ich die Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "vokabelabfrage.py", line 32, in <module>
    for line in fobj:
ValueError: I/O operation on closed file
Ich benutze das erste mal line.split() also kann es gut sein das da etwas falsch ist. Ein großen Dankeschön an alle, die sich die Mühe gemacht haben und bis hierhin gelesen haben.

LG J4RVIS
Zuletzt geändert von J4RVIS am Samstag 26. April 2014, 15:50, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Die Fehlermeldung sagt es doch deutlich: Du versuchst aus einer Datei zu lesen, die bereits geschlossen ist! Schau Dir mal Zeile 36 genauer an ;-)

Zum Code gibt es noch einiges zu sagen... mal sehen, vielleicht setze ich mich mal dran.

Kleiner Tipp noch: Poste doch ein wenig aufgeräumteren Code hier. Auskommentierter Coder gehört da nicht rein - außer, er hat eine Bedeutung bezüglich des Problems. Das ist hier von Zeile 5 bis 8 aber eher nicht der Fall ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
J4RVIS
User
Beiträge: 4
Registriert: Samstag 26. April 2014, 15:25

Danke für die schnelle Antwort :) Bin natürlich mal wieder blind wie nix :D Ich hab einfach ca. 200x überlesen dass ich es schon geschlossen habe. Dachte schon mit der Fehlerausgabe läuft was schief. Klingt so als wäre so ziemlich alles unsauber oder falsch xD
LG
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hier mal einige Anmerkungen zum Code...

- Generelles: Vermische nicht Tabs und Leerzeichen für das Einrücken. Benutze immer vier Leerzeichen, das ist auch in PEP8 vorgesehen.

- Wieso öffnest Du in Zeile 2 eine Datei, um sie in Zeile 3 wieder zu schließen? Komplett sinnlos ;-)

- Dateien solltest Du immer mit ``with`` öffnen. Das schließt die Datei automatisch wieder; auch in einem Fehlerfall:

Code: Alles auswählen

with open(...) as fobj:
    # hier kannst Du Operationen auf fobj vornehmen
    # fobj.close() brauchst Du nicht mehr aufrufen!
- Das Parsen Deiner Vokabeldateien sieht ziemlich identisch aus. Das ist ein typischer Fall von Copy- und Paste-Programmierung und verstößt gegen DRY. Du solltest das Parsen in eine Funktion auslagern und diese dann an den beiden Stellen aufrufen.

- Du solltest Deinen Code insgesamt besser strukturieren - ich kann ohne genaueres Hinsehen nicht verstehen, *was* Dein Programm eigentlich macht. Schreibe kleinere Funktionen, die einen aussagekräftigen Namen haben und verraten, was sie tun. (Ja, das ist schwierig; für einen Anfänger sowieso aber unbedingt notwendig!)

- Habe keinen Code auf Modulebene. Wenn Du Dein Modul von einem anderen Modul importierst, wird sofort Code ausgeführt. Verwende folgenden Trick, um das zu vermeiden, gleichzeitig das zu erlauben, dass Du das Programm wie gewohnt starten kannst:

Code: Alles auswählen

def main():
    # hier Dein Code

if __name__ == "__main__":
    main()
- Kleiner Tipp: Du musst das Parsen natürlich nicht von neuem erfinden. Nutze eine Bibliothek von Python, um Dir die Datenstrukturen (also in Deinem Falle Wörterbücher) in eine Datei zu schreiben und daraus wieder zu lesen. Du könntest z.B. JSON nutzen und dafür das ``json`` Modul. Das geht extrem einfach:

Code: Alles auswählen

import json

words = {"if": "wenn", "while": "solange"}

data_as_str = json.dumps(words)
print(data_as_str)
> '{"if": "wenn", "while": "solange"}'

words_reloaded = json.loads(data_as_str)
print(words_reloaded)
> {'if': 'wenn', 'while': 'solange'}
- Kommentiere nicht so viel aus, sondern lösche alten, nicht mehr gebrauchten Code. Nutze ein Versionskontrollsystem wie Git oder Mercurial, um ggf. alten Code wiederherzustellen. Für kleinere Scripte kannst Du auch einfach gist.github.com nutzen. Das kann zu einem Snippet Versionen vorhalten. Bessr wäre es aber, wirklich ein VCS zu nutzen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
J4RVIS
User
Beiträge: 4
Registriert: Samstag 26. April 2014, 15:25

Erstmal dickes Dankeschön an dich! Du hast mir sehr geholfen. Ich überarbeite jetzt erstmal alles und bearbeite dann diesen Beitrag. Ich werde auch alles an python3 anpassen. Mehr als print und raw_input gibt es ja nich zu ändern. Ich hab den code auf nem raspberry pi verfasst xD hab dort noch kein git. Kommt aber alles noch. Danke nochmal :)
LG
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@ J4RVIS: interessant wird es, wenn Du mehrere Wörter hintereinander eingibst, also zwei Deutsche Wörter und dann genau liest, was die Ausgabe ist, oder nach einem deutschen ein französisches.
J4RVIS
User
Beiträge: 4
Registriert: Samstag 26. April 2014, 15:25

Noch gibts nur die Standartmeldung :( Ich lass mir da noch was einfallen :DD Ursprünglich wollte ich mich eigentlich selbst Vokabeln abfragen. Hab dann aber die Sache mit dem Wörterbuch wesentlich spannender gefunden :D

Bin jetzt auf folgendes Problem gestoßen. Ich will das parsen der Wörter in eine Funktion packen. Wie man dem code entnehmen kann ändert sich aber beim 2ten mal die Zuordnung. Ist es trotzdem möglich eine Funktion zu nutzen. Vielleicht über diverse Parameter?

LG
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

J4RVIS hat geschrieben: Bin jetzt auf folgendes Problem gestoßen. Ich will das parsen der Wörter in eine Funktion packen. Wie man dem code entnehmen kann ändert sich aber beim 2ten mal die Zuordnung. Ist es trotzdem möglich eine Funktion zu nutzen. Vielleicht über diverse Parameter?
Mache drei Funktionen! Eine für das reine Parsen. Diese gibt eben nur eine Liste aus Tupeln zurück. Dann jeweils eine für die "Richtung", in denen aus der Liste von Tupeln ein Dictionary erstellt wird.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@J4RVIS: Das '-' als Trennzeichen erscheint mir ungünstig, es gibt doch zusammengesetzte Worte mit Bindestrichen. Wie unterscheidet man denn dort dann zwischen dem Bindestrich und dem Trenner für die beiden Sprachen?
Antworten