Haupstadt wird nicht angezeigt

Fragen zu Tkinter.
Antworten
Lukas100%!
User
Beiträge: 2
Registriert: Freitag 15. Februar 2019, 23:49

Hallo an alle :) ,

ich versuche ein simples Programm zu schreiben, welches Fragen beantwortet. Genauer gesagt soll es mir die Hauptstädte verschiedener Länder anzeigen.
Leider zeigt es mir beim eintragen des Landes gar nichts an. Ich bitte um Hilfe und freue mich sehr über eure Antworten.

from tkinter import Tk, simpledialog, messagebox

def datei_lesen():
with open('hauptstadt.txt') as file:
for line in file:
line = line.rstrip('\n')
land, stadt = line.split('/')
die_welt[_land] = stadt
datei_lesen()

def datei_schreiben(land_name, stadt_name):
with open('hauptstadt.txt', 'a') as file:
file.write('\n' + land_name + '/' + stadt_name)

print('Frag den Experten - Hauptstädte der Welt')
root = Tk()
root.withdraw()
die_welt = {}

while True:
abfrage_land = simpledialog.askstring('Land, 'Gib den Namen eines Landes ein:')

if abfrage_land in die_welt:
ergebnis = die_welt[abfrage_land]
messagebox.showinfo('Antwort',
'Die Hauptstadt von ' + abfrage_land + ' ist ' + ergebnis + '!')
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Lukas100%!: Der Code läuft nicht, weil der gar nicht am Compiler vorbei kommt.

Wenn man den Syntaxfehler behebt, dann ist der Code weiterhin so voller Fehler, das Du am besten noch mal von vorne anfängst und das Programm Stück für Stück entwickelst, statt es komplett runter zu schreiben, bevor Du es das erste mal ausführst. Also jede Funktion(alität) einzeln, nach und nach implementieren, und jedes mal testen ob das bisher geschriebene tut was es soll. Und dann erst mit dem nächsten Schritt weitermachen.

Die `datei_lesen()`-Funktion würde mit einem `NameError` abbrechen, wenn man sie denn aufrufen würde. Wäre der nicht, würde der völlig unsinnige rekursive Aufruf dem ganzen das Genick brechen. Da wäre dann die interessante Frage was eher zum Abbruch führt: das Rekursionslimit, oder weil dem Betriebssystem die Dateihandles für den Prozess ausgehen. Eine sinnvolle Funktion müsste die eingelesenen Daten dann auch an den Aufrufer zurück geben.

`datei_schreiben()` wird nirgends aufgerufen. Zudem ist es ungewöhnlich bis falsch das Zeilenende-Zeichen als *erstes* zu schreiben, und die Zeile dann nicht damit abzuschliessen. Das zuammenstückeln der Einzelteile mit ``+`` ist auch eher BASIC als Python. Python kennt dafür Zeichenkettenformatierung mit der `format()`-Methode oder ab Python 3.6 auch f-Zeichenkettenliterale.

`die_welt` auf Modulebene wird nie mit irgendwelchen Werten gefüllt, das heisst da kann man dann auch keine Eingabe vom Benutzer drin finden.

Bis zu dem Test/Zugriff kommt der Code aber auch gar nicht, weil Du den Benutzer in einer Endlosschleife nach der Eingabe fragst, aber die Eingabe erst *nach* der Endlosschleife verwendest. Beziehungsweise eben nicht, weil der Programmablauf da ja niemals hin kommt.

Das Hauptprogramm sollte auch nicht auf Modulebene stehen. Dort gehört nur Code hin der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Lukas100%!: Weitere Anmerkungen: Eingerückt wird mit vier Leerzeichen pro Ebene.

Der Dateiname sollte nicht zweimal im Quelltext stehen. Wenn man Code und/oder Daten wiederholt, besteht die Gefahr das man bei späteren Änderungen nicht alle Kopien ändert, oder nicht alle gleich verändert.

Man sollte bei Textdateien immer die Kodierung explizit angeben, damit das Programm auf allen Systemen und Einstellungen gleich arbeitet. Am besten nimmt man UTF-8 als Kodierung weil damit alle Zeichen kodiert werden können, die der Benutzer eingeben kann.

Wenn man eine Funktion `datei_lesen()` hat und dann noch eine `datei_schreiben()` erwartet der Leser das die komplementär sind, also das `datei_schreiben()` das Gegenteil von `datei_lesen()` ist. `datei_lesen()` liest aber die gesamte Datei, während `datei_schreiben()` eine vorhandene Datei nur um einen Eintrag *erweitert*.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
from tkinter import messagebox, simpledialog, Tk

HAUPTSTADT_DATEINAME = 'hauptstadt.txt'
DELIMITER = '/'


def lese_datei(dateiname):
    with open(dateiname, encoding='utf-8') as file:
        return dict(line.rstrip('\n').split(DELIMITER) for line in file)


def erweitere_datei(dateiname, land_name, stadt_name):
    if any(DELIMITER in name for name in [land_name, stadt_name]):
        raise ValueError(
            f'delimiter ({DELIMITER!r}) must not be part of a name'
        )
    with open(dateiname, 'a', encoding='utf-8') as file:
        file.write(f'{land_name}{DELIMITER}{stadt_name}\n')


def main():
    print('Frag den Experten - Hauptstädte der Welt')
    die_welt = lese_datei(HAUPTSTADT_DATEINAME)

    root = Tk()
    root.withdraw()

    land = simpledialog.askstring('Land', 'Gib den Namen eines Landes ein:')
    if land:
        try:
            hauptstadt = die_welt[land]
        except KeyError:
            messagebox.showerror(
                'Fehler', f'Das Land {land} konnte nicht gefunden werden.'
            )
        else:
            messagebox.showinfo(
                'Antwort', f'Die Hauptstadt von {land} ist {hauptstadt}!'
            )


if __name__ == '__main__':
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Lukas100%!
User
Beiträge: 2
Registriert: Freitag 15. Februar 2019, 23:49

_blackjack_: Vielen Dank für deine schnelle, sehr ausführliche Antwort, hat mich sehr gefreut!
Blöderweise zeigt es bei mir mit deinem geschriebenen Code auch nichts an... Die Hauptstädte von Ländern anzeigen ist eines von mehren Projekten in dem Buch, welches ich gerade lese. Es geht darum, ein simples Expertensystem zu programmieren.
datei_schreiben()` wird nirgends aufgerufen. Zudem ist es ungewöhnlich bis falsch das Zeilenende-Zeichen als *erstes* zu schreiben, und die Zeile dann nicht damit abzuschliessen. Das zuammenstückeln der Einzelteile mit ``+`` ist auch eher BASIC als Python.
Deiner Aussage nach ist die Herangehensweise des Buches etwas ungewöhnlich, bzw. nicht optimal und vor allem nicht wirklich Python basierend?
Gibt es Bücher über Python oder programmieren an sich, auch andere Sprachen, welche du mir empfehlen könntest?
Nochmal vielen Dank für deine ausführliche Antwort und ich wünsche dir noch einen schönen Tag.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Lukas100%!: Sofern etwas eingegeben wurde sollte aber entweder der eine oder der andere Dialog angezeigt werden. Und die Ausgabe des `print()`-Aufrufs sollte auf jeden Fall auf der Standardausgabe erfolgen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten