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()
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.
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.