Ja stimmt, im Grunde genommen unterscheidet sich bei der 1. und 2. Nur das PhotoImage. Das kann ich aber ja auch einfach in der main Methode übergeben. Dann müsste auch noch übergeben werden um welche Sitzreihe es sich handelt, damit die Ausgabe in der Programmlogik angepasst wird. Also da kann ich eine Klasse löschen. Die 3. Klasse lasse ich erst mal so oder schreibe das PhotoImage in die main methode.__blackjack__ hat geschrieben: ↑Montag 30. Juli 2018, 10:38 @Marvin75854: Wo Unterscheiden sich die `HDPA_Sitzreihe_*`\en denn? Zumindst von dem was man sehen kann ist die `__init__()` mindestens bei den ersten beiden ja gleich. So viel Code zu kopieren würde ich im Grunde sogar als Fehler ansehen und nicht mehr einfach nur als unschön.
Ja. Also, wenn ich bei mir das .get() der übergebenen Werte lösche, funktioniert das Testen. Also liegt es wohl daran. Ich habe mir nochmal eure Beispiele angeguckt und der einzige Unterschied ist, dass die get() Methode schon in der GUI Klasse verwendet wird und in der Programmlogik dann nur noch das hx. Ich glaube jetzt verstehe ich das. Mit dem .get() in der Programmlogik wurde das Entry Feld aus der GUI geholt. So wie es jetzt ist, wird das Feld aus der GUI schon vorher geholt und in der Programmlogik nur noch der Wert verwendet?__blackjack__ hat geschrieben: ↑Montag 30. Juli 2018, 10:38 Du Übergibst beim erstellen des `HDPA_Berechnung`-Exemplars `hx`, `hz`, und `dy` als `Entry`-Objekte. Das sind Eingabeelemente aus der GUI, davon sollte die Berechnung nichts wissen müssen. Stell Dir mal vor Du möchtest das in einer interaktiven Python-Shell mal testen. Das würde man eigentlich gerne so machen können:Geht aber nicht weil die ersten drei Argumente GUI-Eingabeelemente sind. Das heisst statt hier Wert übergeben zu können die man für die reine Berechnung benötigt, muss man erst `Entry`-Elemente erstellen (für die man vorher ein `Tk`-Objekt benötigt) und die Werte dort rein stecken. Anders kann man das nicht testen oder wiederverwenden. Man kann kein anderes GUI-Toolkit verwenden und auch keine Webanwendung daraus machen, obwohl die Art wie die Werte eingegeben wurden, mit der Berechnung eigentlich gar nichts zu tun hat.Code: Alles auswählen
>>> from Programmlogik import HDPA_Berechnung >>> hb = HDPA_Berechnung(42, 23, 47.11, 'test.inc', 1, 1) >>> hb.hdpa_berechnen() >>> hb.links_unten_x 86
Code: Alles auswählen
>>> import Tkinter as tk >>> from Programmlogik import HDPA_Berechnung >>> root = tk.Tk() >>> hx = tk.Entry(root) >>> hx.set('42') >>> hz = tk.Entry(root) >>> hz.set('23') >>> dy = tk.Entry(root) >>> dy.set('47.11') >>> hb = HDPA_Berechnung(hx, hz, dy, 'test.inc', 1, 1) >>> hb.hdpa_berechnen() >>> hb.links_unten_x 86 >>> root.destroy()
Ja in meinem Beispiel ist das noch nicht mehrfahr aufgerufen, weil ich die Funktion bei Sitzreihe 2 noch nicht eingefügt habe. Da soll eben die selbe Berechnung mit anderen Punkten durchgeführt und die Ergebnisse im selben Format ausgegeben werden. Das heißt ich rufe die Funktion z.b. zwei mal auf und geben jeweil das Ergebnis zurück. Mit dem Code den du gezeigt hast. Und dann kann ich die Daten in eine Datei schreiben. Dafür schreibe ich am Besten noch eine extra Funktion?__blackjack__ hat geschrieben: ↑Montag 30. Juli 2018, 10:38 Wenn Du die `HDPA_Ausgabe()` mehrfach aufrufst, machst Du in dem Code aber nicht, *und* es macht auch dann immer noch keinen Sinn die Datei tatsächlich dreimal zu öffnen und zu schliessen. Die könnte man einmal öffnen und dann nicht den Dateinamen übergeben, sondern das offene Dateiobjekt. Ich persönlich würde den Datenfluss dann vielleicht auch umkehren: Nicht den Dateinamen oder das Dateiobjekt an die `HDPA_Ausgabe()` übergeben, sondern die Zeilen/Daten von `HDPA_Ausgabe()` zurückgeben lassen, damit der Aufrufer dann damit machen kann was er möchte. Beispielsweise die Daten in eine Datei schreiben.
Ich habe dann aber immer noch das Problem, dass in diese Datei zum späteren Zeitpunkt noch mehr geschrieben werden soll. Ich will also nur einen Button auf der GUI haben. Wenn ich jetzt alle Elemente auf der GUI in eine Klasse schreibe, dann könnte ich das Problem lösen, aber das will ich ja eigentlich vermeiden. Sonst könnte ich es ja genauso gut global lassen.
Ja ich verstehe immer noch nicht den Unterschied zwischen Funktionen und Methoden. Also einer Funktion kann man Argumente direkt übergeben und eine Methode bekommt ihre Argumente innerhalb einer Klasse von der __init__ .__blackjack__ hat geschrieben: ↑Montag 30. Juli 2018, 10:38 Bei `HDPA_Berechnung()` bekommt die Funktion die Argumente in der Tat über die `__init__()`. Was keinen Sinn macht, denn man könnte ihr die Argumente auch direkt übergeben. Also der *Funktion*, denn eine Methode ist das ja nicht wirklich.
Ja den Absatz verstehe ich überhaupt nicht. Ja so werde ich das jetzt mal machen.__blackjack__ hat geschrieben: ↑Montag 30. Juli 2018, 10:38 Genau, `links_unten_x` & Co sind die Attribute die nicht in der `__init__()` definiert werden. Klar musst Du die Ergebnisse irgendwie benennen, aber die gehören halt nicht als Attribute auf die Klasse, genau so wenig wie die Argumente als Attribute auf diese Klasse gehören. Eventuell kann es Sinn machen Argumente für die Funktion und das Ergebnis der Funktion jeweils in einem eigenen Datentyp zusammen zu fassen, aber alle drei Sachen — Argumente, Funktion, und Ergebnisse — gehören einfach so nicht in einer Klasse.
Ich denke Du fängst bei der Programmlogik am falschen Ende an Daten in Klassen zusammenzufassen. Schreib das lieber erst einmal als Funktionen und schau dann was sich an ”Kleinteilen” zusammenfassen lässt, statt von ”oben” anzufangen und gleich erst mal die komplette Berechnung und Ausgabe in eine Klasse zu stecken.
Ok ich kann den Code nicht so richtig nachvollziehen was in dem Code passiert, werde mal ein bisschen rumprobieren.__blackjack__ hat geschrieben: ↑Montag 30. Juli 2018, 10:38 Die Berechnungsklasse mal als Funktionen, mit einem `collections.namedtuple()` um das Ergebnis der `hdpa_berechnen()`-Funktion zu einem Objekt zusammenfassen zu können:Hier sieht man IMHO ganz gut das es Sinn machen könnte eine Klasse für 3D-Punkte einzuführen.Code: Alles auswählen
from collections import namedtuple HDPAResult = namedtuple( 'HDPAResult', 'links_unten_x links_unten_z' ' rechts_unten_x rechts_unten_z' ' links_oben_x links_oben_z' ' rechts_oben_x rechts_oben_z' ' delta_y' ) def hdpa_berechnen(hx, dy, hz, ddy): return HDPAResult( hx + 126 - 82, hz + 594 - 58, hx + 147 + 82, hz + 594 - 52, hx + 126 - 82, hz + 693 + 82, hx + 147 + 82, hz + 693 + 82, dy + ddy, ) def hdpa_ausgabe(hx, ddy, hz, sitzreihe, i_start, hdpa_result, out_file): out_file.write( '$H-Punkt: ({0}, {1}, {2})\n' '$HDPA-Feld fuer die {3}. Sitzreihe:\n'.format(hx, ddy, hz, sitzreihe) ) node_values = [ (hdpa_result.links_unten_x, hdpa_result.links_unten_z), (hdpa_result.rechts_unten_x, hdpa_result.rechts_unten_z), (hdpa_result.links_oben_x, hdpa_result.links_oben_z), (hdpa_result.rechts_oben_x, hdpa_result.rechts_oben_z), ] for i, (x, z) in enumerate(node_values, i_start): out_file.write( 'NODE / 1000000{0}{1:16.6f}{2:16.6f}{3:16.6f}\n'.format( i, x, hdpa_result.delta_y, z ) ) out_file.write( 'SHELL / 1000000{0} 11000000{1} \n' 'PART / 1000000{0}SHELL 1 \n' 'NAMEDefault HDPA_Feld_{0}.Sitzreihe\n' ' \n' ' \n' ' 1. 3 \n\n' 'END_PART\n'.format( sitzreihe, '1000000'.join(str(i_start + j) for j in [0, 1, 3, 2]), ) )