Programmierbeispiel DB 2

Das Programm über die Bahnhöfe der DB  noch in Python 3.5:

from tkinter import *

#Klasse Bahnhof
class Bahnhof(object):
    def __init__(self, name, breite, laenge):
        self.name = name
        self.breite = float(breite)
        self.laenge = float(laenge)

    def isHbf(self):
        if self.name.find("Hbf")>-1:
            return True
        return False


#Parsen der csv-Datei und Erzeugen der Bahnhöfe
import csv
alleBahnhoefe = []
reader = csv.reader(open("DB_2016.csv"),delimiter=';')
for row in reader:
    alleBahnhoefe.append(Bahnhof(row[2],row[4],row[5]))

#Bestimmen der max/min Breiten und Längen
maxLaenge = 0
for curBahnhof in alleBahnhoefe:
    if curBahnhof.laenge>maxLaenge:
        maxLaenge=curBahnhof.laenge

minLaenge = 10000000
for curBahnhof in alleBahnhoefe:
    if curBahnhof.laenge<minLaenge:
        minLaenge=curBahnhof.laenge

maxBreite = 0
for curBahnhof in alleBahnhoefe:
    if curBahnhof.breite>maxBreite:
        maxBreite=curBahnhof.breite

minBreite = 10000000
for curBahnhof in alleBahnhoefe:
    if curBahnhof.breite<minBreite:
        minBreite=curBahnhof.breite


#Zeichnen der Punkte
master = Tk()
canvas_width = 600
canvas_height = 600
w = Canvas(master, width=canvas_width,height=canvas_height)
w.pack()

#Normale Bahnhöfe in Blau
for curBahnhof in alleBahnhoefe:
    actLaenge = (canvas_width) / (maxLaenge-minLaenge) * (curBahnhof.laenge-minLaenge);
    actBreite = (canvas_height) / (maxBreite-minBreite) * (curBahnhof.breite-minBreite);
    actX = int(actBreite);
    actY = int(canvas_height-actLaenge);
    w.create_oval(actX,actY, actX+5,actY+5, fill="#000000")

#Hauptbahnhöfe in Rot mit Namen (Ersten beiden Buchstaben)
for curBahnhof in alleBahnhoefe:
    actLaenge = (canvas_width) / (maxLaenge-minLaenge) * (curBahnhof.laenge-minLaenge);
    actBreite = (canvas_height) / (maxBreite-minBreite) * (curBahnhof.breite-minBreite);
    actX = int(actBreite);
    actY = int(canvas_height-actLaenge);
    if curBahnhof.isHbf():
        w.create_oval(actX,actY, actX+5,actY+5, fill="#ff0000")
        w.create_text(actX+5,actY+5,text=curBahnhof.name[:2], fill="#ff0000")

mainloop()

Beteilige dich an der Unterhaltung

2 Kommentare

  1. Ein paar Anmerkungen zu deinem Quelltext:
    (bezieht sich vieles auf PEP8: https://www.python.org/dev/peps/pep-0008/, sollte man mal lesen und sich direkt angewöhnen, wenn man mit Python anfängt)

    Importe sollten immer am Anfang des Files stehen und man sollte *-Importe vermeiden, da man sich so den namespace mit allen Namen des Moduls zumüllt und ggf. bei mehreren Modulen Namen doppelt vorhanden sind. Der letzte Import “gewinnt” dann und man wundert sich, warum es nicht funktioniert.

    Bezeichner von Variablen/Methoden sollten immer mit underscores versehen werden, CamelCase ist nur bei Klassenbezeichnern vorgesehen, also eher is_hbf() statt isHbf()

    Ob man hier eine Klasse braucht mag mal dahingestellt sein, aber isHbf() kann
    man eleganter schreiben:

    def isHbf(self):
    return “Hbf” in self.name

    Der ‘in’-Operator prüft, ob der String “Hbf” in self.name vorhanden ist und gibt im Erfolgsfall True zurück, sonst False. Somit ist das nur eine Zeile und auch leserlicher als die find Methode mit Vergleich auf vorhandenen Index.

    Um eine Datei zu öffnen sollte man immer das with-Statement verwenden, da damit automatisch die Datei wieder geschlossen wird. Bei dir bleibt die Datei geöffnet, was in diesem Fall nicht schlimm ist, aber zu Problemen führen könnte, wenn du später von woanders nochmal auf die Datei lesend oder schreibend zugreifen willst.

    Für das Bestimmen von Maximum und Minimum hat Python max und min. Die jeweiligen Werte kann man mittels generators erhalten:

    z.B.:
    maxLaenge = max(bahnhof.laenge for bahnhof in alleBahnhoefe)

    Ansonsten habe ich noch bei tkinter die Möglichkeit entdeckt Objekte auf Layer zu verschieben (mit lift/lower), so dass die zwei for-Schleifen am Ende zu einer werden können. Die “normalen” Bahnhöfe wandern dann immer direkt in den Hintergrund.

    Den gesamten überarbeiteten Quelltext habe ich nochmal hier gepostet:
    http://pastebin.com/85cYmwaG

    Bitte alles als konstruktive Kritik verstehen, ich freue mich immer, wenn Kollegen Python als Sprache für sich und den Unterricht entdecken/vorziehen.

    1. Ja ja, man merkt, dass ich nur wenig bis gar nicht Python programmiere. Insofern bin ich über das Feedback dankbar. Das ich jetzt hier meine Antworten hinschreibe, soll daher auch nicht als zurück meckern zu verstehen sein, sondern als Verdeutlichung, wie die “Fehler” entstanden sind. Oft fragt man sich ja als Lehrer “Warum macht ein Schüler so etwas?”. In diesem Fall bin ich eher “der junge Padawan”, der allerdings seine Gedanken nachvollziehen kann.

      1. Den Style-Guide kannte ich gar nicht. Danke dafür.

      2.a Die Importe stehe nicht zusammen an einer Stelle, da ich einfach meine Java-Klassen Copy-Paste-mäßig in ein einziges Python-Dokument übertragen habe.
      2.b Und das man nicht alles Pakete per * importiert ist mir klar. Ich berücksichtige so etwas in der Regel aber immer nur, wenn ich das Programm produktiv einsetzen oder weiterreichen will und damit möglichst klein halten will.

      3. Da ich noch längst nicht so den Überblick über viele Funktionen in Python habe, wusste ich auch nicht so genau, was es an Funktionen gibt. Daher danke vor allem für die Verkürzung/Optimierung mancher Funktionen.

      Danke auf alle Fälle für die Anregungen.

Schreibe einen Kommentar

Schreibe einen Kommentar zu Ingo Bartling Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Durch die weitere Nutzung der Seite (Scrollen, Navigieren) stimmen Sie der Verwendung von Cookies zu. Weitere Informationen

Die Cookie-Einstellungen auf dieser Website sind auf "Cookies zulassen" eingestellt, um das beste Surferlebnis zu ermöglichen. Wenn du diese Website ohne Änderung der Cookie-Einstellungen verwendest oder auf "Akzeptieren" klickst, erklärst du sich damit einverstanden.

Schließen