Seite 1 von 2
richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Montag 20. März 2023, 22:17
von Kalysto
Hallo Zusammen,
Ich habe eine Allgemeine Frage zum Aufbau von Programm Code..
Ich bin nun bei ca. 28.770 Zeilen Code welches für mein Programm ist und unter Pythonista läuft, das ganze wird nun recht unübersichtlich.. daher wollte ich nun schauen das ich vllt. mehrere Dateien erstellen würde welche immer ein "Hauptprogramm" seinerseits enthält.
Hierbei sind auch Codes doppelt da ich damals für jede Seite eine Eigene Nav. Bar erstellt hatte das wollte ich dann bei dem Überarbeiten anpassen und in eine "Allgemeine" Datei packen worin Code steht der von anderen Funktionen auch genutzt werden sollte.
Zur Zeit habe ich eine Klasse main welche gestartet wird und danach werden die entsprechenden Unterprogramme über Funktionen aufgerufen.
zum etwas verdeutlichen (besseren verstehen):
Code: Alles auswählen
class main(SafeAreaView):
def __init__(self):
####
EINSTELLUNGEN für Variablen etc.
####
self.StartPage()
self.StartPage() ist somit meine Startseite worüber ich alle anderen Seiten aufrufen kann und entsprechend wieder zurück komme.
Meine Frage ist nun wie ich am besten vorgehen soll und ob man das überhaupt macht und machen sollte ??
das ganze würde dann auch für Konfigurationsdateien gelten worin Farben, Texte etc. enthalten sein können sollte ?
Meine Vorstellung würde so für meine main.py aussehen:
Code: Alles auswählen
class main(SafeAreaView):
def __init__(self):
####
EINSTELLUNGEN für Variablen etc.
####
self.StartPage()
def StartPage(self):
# Nur als Sichtbeispiel
Button.Action = self.subPage1
Button.Action = self.subPage2
Button.Action = self.subPage3
def subPage1(self, sender):
# import aus Datei subPage1
self.subPage1()
def subPage2(self, sender):
# import aus Datei subPage2
self.subPage2()
def subPage3(self, sender):
# import aus Datei subPage3
self.subPage3()
bin für Vorschläge offen wie ich das angehen kann und könnte
mfg.
Kalysto
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Montag 20. März 2023, 22:39
von Sirius3
Wenn man ein Programm hat, das 28770 Zeilen hat, dann ist da sicher was falsch. Aus Deinen Ausführungen werde ich aber nicht schlau.
Das Code-Fragment, den Du zeigst, hält sich an keine Namenskonvention, hat keinerlei Inhalt und besteht nur aus durchnummierierten generischen Wörtern, was ihn nochmals schwieriger zu verstehen macht.
Kannst Du ein Minimalbeispiel posten, das tatsächliche Funktionalität hat und den typischen Aufbau des Programms zeigt.
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Montag 20. März 2023, 23:17
von darktrym
Und wie sind die Zeilen denn auf geteilt, wie lang sind die Methoden, wie viel Kommentare stecken drin und auf wie vielen Dateien sind die verteilt.
28K für ein Python Skript klingt tatsächlich recht viel, als ob man gegen DRY verstößt.
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Dienstag 21. März 2023, 09:19
von Kebap
> Hierbei sind auch Codes doppelt da ich damals für jede Seite eine Eigene Nav. Bar erstellt hatte das wollte ich dann bei dem Überarbeiten anpassen und in eine "Allgemeine" Datei packen worin Code steht der von anderen Funktionen auch genutzt werden sollte.
Das bestätigt wohl DRY Verstöße. Gut, wenn du das reparieren willst. Dazu braucht man aber nicht gleichzeitig mehrere Dateien. Mehrere Funktionen könnten schon ausreichen. Nicht zu viel gleichzeitig ändern.
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Dienstag 21. März 2023, 21:33
von Kalysto
Sirius3 hat geschrieben: ↑Montag 20. März 2023, 22:39
Wenn man ein Programm hat, das 28770 Zeilen hat, dann ist da sicher was falsch. Aus Deinen Ausführungen werde ich aber nicht schlau.
Das Code-Fragment, den Du zeigst, hält sich an keine Namenskonvention, hat keinerlei Inhalt und besteht nur aus durchnummierierten generischen Wörtern, was ihn nochmals schwieriger zu verstehen macht.
Kannst Du ein Minimalbeispiel posten, das tatsächliche Funktionalität hat und den typischen Aufbau des Programms zeigt.
Hier habe ich nun einmal den verkürzten Auszug der
__init__:
Code: Alles auswählen
def __init__(self):
# Angabe des Gerätes für debugLog
UIDevice = ObjCClass('UIDevice')
device = UIDevice.currentDevice()
self.DEVICE_VERSION = str(device.systemVersion())
self.DEVICE_TYPE = str(device.localizedModel())
self.DEVICE_OS = str(device.systemName())
self.DEVICE_ID = str(device.identifierForVendor())
# Pfadangabe für die Log Ausgaben...
self.loggingPath = os.path.join(os.path.dirname(sys.argv[0]), 'Protokollierungen')
# Angabe ob Abfragen erstellt werden sollten
self.TABLE_SCHEMA__QUERY = None
# Auswahl der Datenbank
self.selectDatabase()
# Benötigt für die Close Funktion
self.safeModeMateriallist__APPCLOSE = False
self.safeModeCustomerSetting__APPCLOSE = False
self.safeModeDatanormEntry__APPCLOSE = False
self.safeModeManufacturer__APPCLOSE = False
self.safeModeMateriallistCSV__APPCLOSE = False
# Bildschirmgröße
self.WIDTH, self.HEIGHT = self.get_screen_size()
self.DEVICE = self.DEVICE_TYPE
# Unzulässige Zeichen in Kunden und Projektnamen
self.forbiddenChars_all = set('<>:"/\|?*!')
# Unzulässige Zeichen in Projektnamen (als Satz Ende)
self.forbiddenChars_firstLastChar = set('.')
# Hauptbildschirm Ansicht des Inhaltes
self.main_content = ui.View(frame=self.bounds, flex='WH')
self.add_subview(self.main_content)
# Darstellung und Anischt (Begrenzung) der Buttons
#self.button_area = style(ui.View(name='button_area', bg_color='')) #TODO ## style für Die Umrandung schauen was ich da machen werde ##
self.button_area = ui.View(name='button_area')
dock(self.button_area).bottom(self.main_content, At.TIGHT)
# Ist für die Höhenanpassung der Button Darstellung
at(self.button_area).height = at(self.button_area).fit_height
# Angaben der Klassen Ansicht
self.name = 'Barcode Scanner'
self.background_color = getColor('MAIN')
self.present('fullscreen', hide_title_bar=True) if self.DEVICE == 'iPad' else self.present('fullscreen', hide_title_bar=True, orientations=['portrait'])
# Anzeige des Contents
self.content_area = ui.View(name='content_area')
dock(self.content_area).top(self.main_content, At.TIGHT)
at(self.content_area).bottom = at(self.button_area).top - At.TIGHT
self.StartPage()
StartPage:
Code: Alles auswählen
def StartPage(self):
# Button für die Öffnung der sidebar der Kundenprofile
self.checkCloseButton = size_to_fit(getButton_area(ui.Button(name='checkCloseButton'), 'checkCloseButton', self.DEVICE, 1))
self.checkCloseButton.action = self.checkCloseButton__ACTION_Button
self.checkCloseButton.width = self.checkCloseButton.height
dock(self.checkCloseButton).top_right(self.main_content)
# Button für die Öffnung der sidebar der Kundenprofile
self.sidebarRegistrationButton = size_to_fit(getButton_area(ui.Button(name='sidebarRegistrationButton'), 'sidebarRegistrationButton', self.DEVICE, 1))
self.sidebarRegistrationButton.enabled = False
self.sidebarRegistrationButton.action = self.userSidebar_openClose
self.sidebarRegistrationButton.width = self.sidebarRegistrationButton.height
dock(self.sidebarRegistrationButton).bottom_left(self.button_area)
# Anzeige sowie Darstellung der Sidebar (Benutzer)
self.sidebarUserView = style(ui.View(name='sidebarUserView', width=sidebarSetWidth('sidebarUserView', self.DEVICE, self.WIDTH)))
self.add_subview(self.sidebarUserView)
at(self.sidebarUserView).top = at(self.main_content).top
at(self.sidebarUserView).bottom = at(self.main_content).bottom
at(self.sidebarUserView).right = at(self.main_content).left
# User Sidebar Schließen
self.userSidebarCloseButton = size_to_fit(getButton_area(ui.Button(name='userSidebarCloseButton'), 'sidebarCloseButton', self.DEVICE, 1))
self.userSidebarCloseButton.action = self.userSidebar_openClose
dock(self.userSidebarCloseButton).bottom_center(self.sidebarUserView)
# Ist für die Höhenanpassung der Button Darstellung
at(self.button_area).height = at(self.button_area).fit_height
self.regUserLabel = size_to_fit(getLabel_area(ui.Label(name='regUserLabel'), 'regUserLabel', self.DEVICE))
dock(self.regUserLabel).top_left(self.main_content, -At.TIGHT)
at(self.regUserLabel).top = at(self.checkCloseButton).bottom
self.showSetting = Action(
set_menuOptions('Action', 'showSetting', self.DEVICE), self.settingBarcodeScannerAPPSwitcher__ACTION_Action,
image=SymbolImage('gear'),
)
self.hideSetting = Action(
set_menuOptions('Action', 'hideSetting', self.DEVICE), self.settingBarcodeScannerAPPSwitcher__ACTION_Action,
image=SymbolImage('gear'),
)
self.hideSetting.selected = True
set_menu(self.sidebarRegistrationButton, [
self.showSetting,
self.hideSetting,
], long_press=True)
self.registration = getView_area('StartPage', get_area('StartPage', self.DEVICE))
fill_with(
self.registration
).from_top(self.content_area)
welcomeLabel = size_to_fit(getLabel_area(ui.Label(name='welcomeLabel'), 'welcomeLabel', self.DEVICE))
dock(welcomeLabel).top_center(self.registration)
at(welcomeLabel).top = at(self.regUserLabel).bottom
welcomeTextView = getTextView_area(ui.TextView(name='welcomeTextView'), 'welcomeTextView', self.DEVICE)
welcomeTextView.width = (self.registration.width - (At.gap * 2))
welcomeTextView.size_to_fit()
dock(welcomeTextView).center(self.registration)
serverStatusInfoLabel = size_to_fit(getLabel_area(ui.Label(name='serverStatusInfoLabel'), 'serverStatusInfoLabel', self.DEVICE))
dock(serverStatusInfoLabel).top_left(self.registration, At.TIGHT)
at(serverStatusInfoLabel).top = at(welcomeTextView).bottom
serverStatusLabel = getLabel_area(ui.Label(name='serverStatusLabel'), 'serverStatusLabel', self.DEVICE)
attach(serverStatusLabel).right_of(serverStatusInfoLabel)
serverUpdateStatusInfoLabel = size_to_fit(getLabel_area(ui.Label(name='serverUpdateStatusInfoLabel'), 'serverUpdateStatusInfoLabel', self.DEVICE))
dock(serverUpdateStatusInfoLabel).top_left(self.registration, At.TIGHT)
at(serverUpdateStatusInfoLabel).top = at(serverStatusInfoLabel).bottom
self.serverUpdateStatusLabel = getLabel_area(ui.Label(name='serverUpdateStatusLabel'), 'serverUpdateStatusLabel', self.DEVICE)
attach(self.serverUpdateStatusLabel).right_of(serverUpdateStatusInfoLabel)
appVersionsInfoLabel = size_to_fit(getLabel_area(ui.Label(name='appVersionsInfoLabel'), 'appVersionsInfoLabel', self.DEVICE))
dock(appVersionsInfoLabel).top_left(self.registration, At.TIGHT)
at(appVersionsInfoLabel).top = at(serverUpdateStatusInfoLabel).bottom
self.appVersionsLabel = getLabel_areaContent(ui.Label(name='appVersionsLabel'), f'{appVersion} - {appBuild}', 'appVersionsLabel', self.DEVICE)
attach(self.appVersionsLabel).right_of(appVersionsInfoLabel)
serverVersionsInfoLabel = size_to_fit(getLabel_area(ui.Label(name='serverVersionsInfoLabel'), 'serverVersionsInfoLabel', self.DEVICE))
dock(serverVersionsInfoLabel).top_left(self.registration, At.TIGHT)
at(serverVersionsInfoLabel).top = at(appVersionsInfoLabel).bottom
self.serverVersionsLabel = getLabel_area(ui.Label(name='serverVersionsLabel'), 'serverVersionsLabel', self.DEVICE)
attach(self.serverVersionsLabel).right_of(serverVersionsInfoLabel)
selectedDatabaseInfoLabel = size_to_fit(getLabel_area(ui.Label(name='selectedDatabaseInfoLabel'), 'selectedDatabaseInfoLabel', self.DEVICE))
dock(selectedDatabaseInfoLabel).top_left(self.registration, At.TIGHT)
at(selectedDatabaseInfoLabel).top = at(serverVersionsInfoLabel).bottom
selectedDatabaseLabel = getLabel_areaContent(ui.Label(name='selectedDatabaseLabel'), self.TABLE_SCHEMA, 'selectedDatabaseLabel', self.DEVICE)
attach(selectedDatabaseLabel).right_of(selectedDatabaseInfoLabel)
self.appVersionsLabel.x = self.serverVersionsLabel.x
serverStatusLabel.x = self.serverVersionsLabel.x
selectedDatabaseLabel.x = self.serverVersionsLabel.x
self.serverUpdateStatusLabel.x = self.serverVersionsLabel.x
# Angaben der Konfigurationsdateien
self.configurationsFile__DEFAULT = 'config.default'
self.configurationsFile__USER = 'config.user'
self.configurationsFile__FOLDER = 'Konfigurationsdatei'
# Angaben des Barcode Scanner Ordners
self.mainDirApplication = '03_Barcode_Application'
self.subDirApplication = '2021_08_14 -- outVersion'
# Deaktiviert das 2 Finger swipen (Schließen Funktion)
disable_swipe_to_close(self.superview)
# Sperrung des Ruhemoduses des iPhones
on_main_thread(console.set_idle_timer_disabled)(True)
Das ganze Projekt hatte ich vor 2 Jahren begonnen und ist natürlich immer wieder gewachsen sodass weitere Seiten dazugekommen sind etc.
Ich bin jetzt nicht der Top Programmierer das war und ist mein erstes Großes Projekt welches immer noch angepasst etc. wird...
meine Frage ist eben wie man das besser gestalten kann bzw. ob man gewissen Code in mehrere Dateien auslagern kann und Darf....
Das Code doppelt ist weis ich jetzt schon ohne nachschauen zu müssen weil ich eben für jede Seite eine eigene Nav. bar erstellt habe welches man natürlich über eine Erledigen könnte... bevor ich das nun aber angehen wollte wollte ich eben wissen worauf ich noch achten sollte was man anpassen Müsste und sollte.
wie gesagt das ganze läuft auf MacOS und IOS über Pythonista.
danke schon einmal für die Hilfen
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Dienstag 21. März 2023, 21:35
von Kalysto
darktrym hat geschrieben: ↑Montag 20. März 2023, 23:17
Und wie sind die Zeilen denn auf geteilt, wie lang sind die Methoden, wie viel Kommentare stecken drin und auf wie vielen Dateien sind die verteilt.
28K für ein Python Skript klingt tatsächlich recht viel, als ob man gegen DRY verstößt.
Kommentare sind vorhanden klar und auch ein Log "System"
Dateien habe ich nur 2 Stk. die "App" an sich und eine Konfigurationsdatei mit Farben und etliche Einstellungen der Button's etc...
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Dienstag 21. März 2023, 22:15
von __blackjack__
@Kalysto: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Methoden werden üblicherweise, genau wie Funktionen, nach den Tätigkeiten benannt die sie durchführen, damit man weis was sie tun und um sie leicht von eher passiven Werten unterscheiden zu können. `StartPage` ist keine Tätigkeit und zudem noch so geschrieben als wäre es eine Klasse.
Was liefern denn die Methoden auf dem `device` das man das in Zeichenketten umwandeln muss?
`os.path` & Co sind durch das `pathlib`-Modul abgelöst.
Warum gibt es `DEVICE` und `DEVICE_TYPE` wenn die den gleichen Wert haben?
Das sieht extrem danach aus als wäre das ein Programm das aus Funktionen besteht, die auf globale Variablen zugreifen, nur dass das alles einfach in einer Klasse verschoben wurde. Eine Gott-Klasse die *viel* zu viel weiss und kann.
Attribute werden in der `__init__()` angelegt, nicht in anderen Methoden. Und in der `__init__()` wird hier schon zu viel angelegt wovon sehr wahrscheinlich nicht einmal alles in der Klasse stehen muss.
In der letzten Zeile von dem ``# Angaben der Klassen Ansicht``-Block wird ein bedingter Ausdruck missbraucht um das in eine Zeile zu quetschen, denn mit dem *Ergebnis* von dem Ausdruck wird nichts gemacht.
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Mittwoch 22. März 2023, 19:24
von Kalysto
__blackjack__ hat geschrieben: ↑Dienstag 21. März 2023, 22:15
@Kalysto: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Methoden werden üblicherweise, genau wie Funktionen, nach den Tätigkeiten benannt die sie durchführen, damit man weis was sie tun und um sie leicht von eher passiven Werten unterscheiden zu können. `StartPage` ist keine Tätigkeit und zudem noch so geschrieben als wäre es eine Klasse.
Okay, das kann ich anpassen wenn ich die Datei ändere, Danke.
__blackjack__ hat geschrieben: ↑Dienstag 21. März 2023, 22:15
Was liefern denn die Methoden auf dem `device` das man das in Zeichenketten umwandeln muss?
Das weis ch heute leider nicht mehr und müsste es Prüfen. Du möchtest darauf hinaus das man den `str()` part nicht benötigt ?
__blackjack__ hat geschrieben: ↑Dienstag 21. März 2023, 22:15
`os.path` & Co sind durch das `pathlib`-Modul abgelöst.
Okay, das wusste ich nicht mit & Co. meinst du noch etwas ?
__blackjack__ hat geschrieben: ↑Dienstag 21. März 2023, 22:15
Warum gibt es `DEVICE` und `DEVICE_TYPE` wenn die den gleichen Wert haben?
Ist eine sehr gute Frage .
__blackjack__ hat geschrieben: ↑Dienstag 21. März 2023, 22:15
Das sieht extrem danach aus als wäre das ein Programm das aus Funktionen besteht, die auf globale Variablen zugreifen, nur dass das alles einfach in einer Klasse verschoben wurde. Eine Gott-Klasse die *viel* zu viel weiss und kann.
Einfach gesagt ja, denn ich betätige ein Button und das entsprechende wird eben ausgeführt: neue Seite geladen sql Einträge getätigt etc.
Ist das nun aber schlimm alles in eine Klasse zu packen ? denn sonst könnte ich ja nicht auf alle Daten zurückgreifen ?
__blackjack__ hat geschrieben: ↑Dienstag 21. März 2023, 22:15
Attribute werden in der `__init__()` angelegt, nicht in anderen Methoden. Und in der `__init__()` wird hier schon zu viel angelegt wovon sehr wahrscheinlich nicht einmal alles in der Klasse stehen muss.
Die Werte brauche ich schon, das steht außer frage...
sollte ich diese Definitionen nicht in der `__init__` erstellen ? dafür ist diese doch aber ?
und was genau meinst du mit Attribute.
__blackjack__ hat geschrieben: ↑Dienstag 21. März 2023, 22:15
In der letzten Zeile von dem ``# Angaben der Klassen Ansicht``-Block wird ein bedingter Ausdruck missbraucht um das in eine Zeile zu quetschen, denn mit dem *Ergebnis* von dem Ausdruck wird nichts gemacht.
Meinst du diese ?
Code: Alles auswählen
self.present('fullscreen', hide_title_bar=True) if self.DEVICE == 'iPad' else self.present('fullscreen', hide_title_bar=True, orientations=['portrait'])
sollte man das eher so schreiben ?
Code: Alles auswählen
if self.DEVICE == 'iPad'
self.present('fullscreen', hide_title_bar=True)
else
self.present('fullscreen', hide_title_bar=True, orientations=['portrait'])
Danke für deine Antwort und Tipps!
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Mittwoch 22. März 2023, 20:08
von __blackjack__
@Kalysto: Ja, ich wollte darauf hinaus ob man die `str()`-Aufrufe überhaupt benötigt.
Mit `os.path` & Co ist alles gemeint was man mit dem `pathlib`-Modul erledigen kann.
Ja es ist schlimm alles in eine Klasse zu packen. Das ist ja 0 Struktur. Dann kann man das auch ohne Klasse machen mit ganz viel ``global``. Das macht dann letztlich keinen Unterschied. Eine Klasse sollte ein ”Ding” modellieren mit einer übersichtlichen Anzahl von Attributen und Methoden und nicht *alles* mit Unmengen an Attributen, die zudem noch nicht mal alle in einer dafür vorgesehenen Methode erstellt werden, sondern über alle Methoden verteilt sind, so dass man gar nicht so leicht sagen kann welche Attribute es insgesamt gibt, und noch weniger *wann* die anfangen zu existieren, also was vorher alles passiert/aufgerufen werden muss. Das kann doch kein Mensch sinnvoll nachvollziehen.
Attribute sind das wo man (üblicherweise) mit dem Punktoperator zugreift. Also `some_object.this_is_the_attribute`. Konkret zum anlegen: ``self.name = ...`` darf nicht ausserhalb einer `__init__()` das erste mal passieren, denn das würde ja bedeuten, dass das Attribut nach der `__init__()` noch nicht existiert. Was bedeutet, dass das Objekt nicht komplett initialisiert ist, was aber die Aufgabe der `__init__()`-Methode ist.
Eine übliche Trennung/Strukturierung ist es die Programmlogik von der GUI zu trennen. Also Funktionen und Klassen zu schreiben mit denen die Aufgaben erledigt werden können, die aber nichts von der GUI wissen. Und dann Code für die GUI, der auf der Programmlogik aufsetzt.
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Freitag 24. März 2023, 20:07
von Kalysto
__blackjack__ hat geschrieben: ↑Mittwoch 22. März 2023, 20:08
@Kalysto: Ja, ich wollte darauf hinaus ob man die `str()`-Aufrufe überhaupt benötigt.
Mit `os.path` & Co ist alles gemeint was man mit dem `pathlib`-Modul erledigen kann.
Okay, das werde ich kontrollieren und anpassen.
__blackjack__ hat geschrieben: ↑Mittwoch 22. März 2023, 20:08
Ja es ist schlimm alles in eine Klasse zu packen. Das ist ja 0 Struktur. Dann kann man das auch ohne Klasse machen mit ganz viel ``global``. Das macht dann letztlich keinen Unterschied. Eine Klasse sollte ein ”Ding” modellieren mit einer übersichtlichen Anzahl von Attributen und Methoden und nicht *alles* mit Unmengen an Attributen, die zudem noch nicht mal alle in einer dafür vorgesehenen Methode erstellt werden, sondern über alle Methoden verteilt sind, so dass man gar nicht so leicht sagen kann welche Attribute es insgesamt gibt, und noch weniger *wann* die anfangen zu existieren, also was vorher alles passiert/aufgerufen werden muss. Das kann doch kein Mensch sinnvoll nachvollziehen.
hmm, okay nun weis ich aber nicht genau wie ich das umsetzten kann da ich ja gewisse attribute also self.name etc. auch in anderen Funktionen benötige und wenn ich nun für jede "Seite" eine Klasse erstellen würde wie würde ich so dann meine Attribute auch in andere Klassen "mit nehmen" können ?
__blackjack__ hat geschrieben: ↑Mittwoch 22. März 2023, 20:08
Attribute sind das wo man (üblicherweise) mit dem Punktoperator zugreift. Also `some_object.this_is_the_attribute`. Konkret zum anlegen: ``self.name = ...`` darf nicht ausserhalb einer `__init__()` das erste mal passieren, denn das würde ja bedeuten, dass das Attribut nach der `__init__()` noch nicht existiert. Was bedeutet, dass das Objekt nicht komplett initialisiert ist, was aber die Aufgabe der `__init__()`-Methode ist.
Heißt das nun das ich alle Attribute self.xyz welche ich benötige in der __init__() erstellen muss ?
__blackjack__ hat geschrieben: ↑Mittwoch 22. März 2023, 20:08
Eine übliche Trennung/Strukturierung ist es die Programmlogik von der GUI zu trennen. Also Funktionen und Klassen zu schreiben mit denen die Aufgaben erledigt werden können, die aber nichts von der GUI wissen. Und dann Code für die GUI, der auf der Programmlogik aufsetzt.
Also müsste ich meine Darstellung (Visuell) von meinen SQL Einträgen / Abfragen Trennen ?
Wäre das somit eine eigene Datei ?
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Freitag 24. März 2023, 21:14
von Dennis89
Kalysto hat geschrieben: ↑Freitag 24. März 2023, 20:07
hmm, okay nun weis ich aber nicht genau wie ich das umsetzten kann da ich ja gewisse attribute also self.name etc. auch in anderen Funktionen benötige und wenn ich nun für jede "Seite" eine Klasse erstellen würde wie würde ich so dann meine Attribute auch in andere Klassen "mit nehmen" können ?
Hier mal ein Beispielcode, der macht eigentlich nichts, aber man sieht wie man zwischen Seiten navigieren kann:
Code: Alles auswählen
import tkinter as tk
from functools import partial
class CalculationApp(tk.Frame):
def __init__(self, master, calculator):
tk.Frame.__init__(self, master)
self.calculator = calculator
self.frames = {}
home_page = Home(self)
home_page.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W))
entry_page = Entry(self, calculator)
entry_page.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W))
result_page = Result(self)
result_page.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W))
self.frames['Home'] = home_page
self.frames['Entry'] = entry_page
self.frames['Result'] = result_page
self.show_page("Home")
def show_page(self, page_name):
self.frames[page_name].tkraise()
def get_page(self, page_name):
return self.frames[page_name]
class Home(tk.Frame):
def __init__(self, controller):
tk.Frame.__init__(self)
self.controller = controller
headline = tk.Label(self, text="Hier gehts zur Berechnung")
headline.grid(row=0, column=1)
go_to_entry_page = tk.Button(
self, text=">>", command=partial(self.controller.show_page, "Entry")
)
go_to_entry_page.grid(row=1, column=3)
class Entry(tk.Frame):
def __init__(self, controller, calculator):
tk.Frame.__init__(self)
self.controller = controller
self.calculator = calculator
values_for_calculation = [10, 30]
description = tk.Label(self, text="Bitte Werte auswählen")
description.grid(row=0, column=1)
self.selected_button = tk.StringVar()
for row_index, value in enumerate(values_for_calculation, 1):
radio_button = tk.Radiobutton(
self, text=value, value=value, variable=self.selected_button
)
radio_button.grid(row=row_index, column=0)
tk.Button(
self, text="Berechne", command=self.start_calculation
).grid(row=3, column=3)
tk.Button(self, text="<<", command=partial(self.controller.show_page, "Home")).grid(
row=3, column=0
)
def start_calculation(self):
self.calculator.calculate(int(self.selected_button.get()))
self.controller.get_page('Result').show_result.config(text=self.calculator.result)
self.controller.show_page('Result')
class Result(tk.Frame):
def __init__(self, controller):
tk.Frame.__init__(self)
self.controller = controller
self.show_result = tk.Label(self, text='')
self.show_result.grid(row=0, column=1)
button = tk.Button(
self, text="Startseite", command=partial(controller.show_page, "Home")
)
button.grid(row=1, column=1)
class Calculator:
def __init__(self):
self.result = None
self.database = [2, 3, 5, 6]
def calculate(self, user_choice):
self.result = sum(number * user_choice for number in self.database)
def main():
calculator = Calculator()
root = tk.Tk()
root.title("Berechnungsprogramm")
app = CalculationApp(root, calculator)
app.mainloop()
if __name__ == "__main__":
main()
Kalysto hat geschrieben: ↑Freitag 24. März 2023, 20:07
Heißt das nun das ich alle Attribute self.xyz welche ich benötige in der __init__() erstellen muss ?
Ja
Kalysto hat geschrieben: ↑Freitag 24. März 2023, 20:07
Also müsste ich meine Darstellung (Visuell) von meinen SQL Einträgen / Abfragen Trennen ?
Wäre das somit eine eigene Datei ?
Trenne ja, eine eigene Datei muss es nicht sein. Du kannst das auch in einer Datei voneinader trennen. Du musst dir dabei "nur" überlegen, ob die Logik funktionieren würde, wenn es kein GUI gibt und du das ganze zum Beispiel über das Terminal steuern willst.
Grüße
Dennis
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Freitag 24. März 2023, 21:52
von Kalysto
Dennis89 hat geschrieben: ↑Freitag 24. März 2023, 21:14
Kalysto hat geschrieben: ↑Freitag 24. März 2023, 20:07
Heißt das nun das ich alle Attribute self.xyz welche ich benötige in der __init__() erstellen muss ?
Ja
auch wenn ich erst später diese definieren werde ?
muss man dann leere Attribute erstellen ?
kann man dann z.b. mit:
auf attribute zurückgreifen ?
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Samstag 25. März 2023, 11:57
von __blackjack__
@Kalysto: Man könnte jede Seite mit einer eigenen Klasse modellieren. Und das was die Seite(n) benötigen ebenfalls in einer (oder mehreren) Klassen, wo das oder die Objekte beim erstellen der Seite übergeben werden, damit der GUI-Code auf den entsprechenden Teil der Programmlogik zugreifen kann.
Die Trennung von Programmlogik und GUI muss nicht zwingend auch@Kalysto: Man könnte jede Seite mit einer eigenen Klasse modellieren. Und das was die Seite(n) benötigen ebenfalls in einer (oder mehreren) Klassen, wo das oder die Objekte beim erstellen der Seite übergeben werden, damit der GUI-Code auf den entsprechenden Teil der Programmlogik zugreifen kann.
Die Trennung von Programmlogik und GUI muss nicht zwingend auch eine Trennung in Module bedeuten. Kann es aber. Und natürlich kann man sowohl Programmlogik als auch GUI auf mehrere Module verteilen. Das lässt sich so pauschal nicht sagen was da sinnvoll ist. Spontan würde ich ja sagen 28K Zeilen sind zu viel für ein Modul, andererseits wissen wir nicht wie viel mal davon durch Schleifen, Funktionen, und Klassen einsparen kann.
Leere Attribute ja, wenn man das machen muss, es ist aber ein „code smell“ wenn man das dauernd und/oder viele Attribute hat die in der `__init__()` nicht mit sinnvollen Werten belegt werden können. Nach der `__init__()` sollte ein Objekt normalerweise komplett und in einem gebrauchsfertigen Zustand sein. eine Trennung in Module bedeuten. Kann es aber. Und natürlich kann man sowohl Programmlogik als auch GUI auf mehrere Module verteilen. Das lässt sich so pauschal nicht sagen was da sinnvoll ist. Spontan würde ich ja sagen 28K Zeilen sind zu viel für ein Modul, andererseits wissen wir nicht wie viel mal davon durch Schleifen, Funktionen, und Klassen einsparen kann.
Leere Attribute ja, wenn man das machen muss, es ist aber ein „code smell“ wenn man das dauernd und/oder viele Attribute hat die in der `__init__()` nicht mit sinnvollen Werten belegt werden können. Nach der `__init__()` sollte ein Objekt normalerweise komplett und in einem gebrauchsfertigen Zustand sein.
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Samstag 25. März 2023, 20:35
von Kalysto
__blackjack__ hat geschrieben: ↑Samstag 25. März 2023, 11:57
@Kalysto: Man könnte jede Seite mit einer eigenen Klasse modellieren. Und das was die Seite(n) benötigen ebenfalls in einer (oder mehreren) Klassen, wo das oder die Objekte beim erstellen der Seite übergeben werden, damit der GUI-Code auf den entsprechenden Teil der Programmlogik zugreifen kann.
Die Trennung von Programmlogik und GUI muss nicht zwingend auch@Kalysto: Man könnte jede Seite mit einer eigenen Klasse modellieren. Und das was die Seite(n) benötigen ebenfalls in einer (oder mehreren) Klassen, wo das oder die Objekte beim erstellen der Seite übergeben werden, damit der GUI-Code auf den entsprechenden Teil der Programmlogik zugreifen kann.
Die Trennung von Programmlogik und GUI muss nicht zwingend auch eine Trennung in Module bedeuten. Kann es aber. Und natürlich kann man sowohl Programmlogik als auch GUI auf mehrere Module verteilen. Das lässt sich so pauschal nicht sagen was da sinnvoll ist. Spontan würde ich ja sagen 28K Zeilen sind zu viel für ein Modul, andererseits wissen wir nicht wie viel mal davon durch Schleifen, Funktionen, und Klassen einsparen kann.
Leere Attribute ja, wenn man das machen muss, es ist aber ein „code smell“ wenn man das dauernd und/oder viele Attribute hat die in der `__init__()` nicht mit sinnvollen Werten belegt werden können. Nach der `__init__()` sollte ein Objekt normalerweise komplett und in einem gebrauchsfertigen Zustand sein. eine Trennung in Module bedeuten. Kann es aber. Und natürlich kann man sowohl Programmlogik als auch GUI auf mehrere Module verteilen. Das lässt sich so pauschal nicht sagen was da sinnvoll ist. Spontan würde ich ja sagen 28K Zeilen sind zu viel für ein Modul, andererseits wissen wir nicht wie viel mal davon durch Schleifen, Funktionen, und Klassen einsparen kann.
Leere Attribute ja, wenn man das machen muss, es ist aber ein „code smell“ wenn man das dauernd und/oder viele Attribute hat die in der `__init__()` nicht mit sinnvollen Werten belegt werden können. Nach der `__init__()` sollte ein Objekt normalerweise komplett und in einem gebrauchsfertigen Zustand sein.
Sry, ich glaube das ist was schief gelaufen, kann das nicht so richtig deuten und lesen die Texte sind verschoben...
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Samstag 25. März 2023, 21:04
von __blackjack__
Naja da ist der Text mitten im Text noch einmal eingefügt. Das lässt sich leicht rekonstruieren — einfach den Mittelteil entfernen:
@Kalysto: Man könnte jede Seite mit einer eigenen Klasse modellieren. Und das was die Seite(n) benötigen ebenfalls in einer (oder mehreren) Klassen, wo das oder die Objekte beim erstellen der Seite übergeben werden, damit der GUI-Code auf den entsprechenden Teil der Programmlogik zugreifen kann.
Die Trennung von Programmlogik und GUI muss nicht zwingend auch eine Trennung in Module bedeuten. Kann es aber. Und natürlich kann man sowohl Programmlogik als auch GUI auf mehrere Module verteilen. Das lässt sich so pauschal nicht sagen was da sinnvoll ist. Spontan würde ich ja sagen 28K Zeilen sind zu viel für ein Modul, andererseits wissen wir nicht wie viel mal davon durch Schleifen, Funktionen, und Klassen einsparen kann.
Leere Attribute ja, wenn man das machen muss, es ist aber ein „code smell“ wenn man das dauernd und/oder viele Attribute hat die in der `__init__()` nicht mit sinnvollen Werten belegt werden können. Nach der `__init__()` sollte ein Objekt normalerweise komplett und in einem gebrauchsfertigen Zustand sein.
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Sonntag 26. März 2023, 21:28
von Kalysto
@__blackjack__: Ich werde das so machen das ich je Seite ein eigens Modul erstellen werde mit den entsprechenden Funktionen.
Ich habe hier einmal ein Test gemacht und ist es korrekt das die jeweilige Datei auch die Importe benötigt wie z.b. sys wenn dies verwendet wird und nicht über die "main" "versorgt" werden würde ?
des Weiteren ist der Aufruf so korrekt in dem "kleinen" Beispiel wie unten dargestellt:
main.py
Code: Alles auswählen
import Startseite
class main():
def __init__(self):
# hier steht nun ein wenig code
Startseite.Startseite.start_der_funktion(self)
Startseite.py
Code: Alles auswählen
# und hier nochmal alle Importe welche diese Datei benötigt ?
class Startseite():
def __init__(self):
# hier steht nun ein wenig code
def start_der_funktion(self):
# Hier ist nun der Code
# welcher in der Main ausgeführt werden sollte
...
...
..
.
Wäre das vom Prinzip her so korrekt mit dem Aufruf ?
`Startseite.Startseite.start_der_funktion(self)`
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Dienstag 28. März 2023, 22:04
von Dennis89
Hallo,
'main' ist üblicherweise die Funktion, aus der das Programm gesteuert wird. Dass ist also die Funktion die zum Programmstart aufgerufen wird, darin kannst du dann eine Insatz von 'Startseite' anlagen.
Code: Alles auswählen
from Startseite import Startseite
def main():
startseite = Startseite()
startseite.start_der_funktion()
if _name__ == '__main__':
main()
Klassen sind nicht dazu da, dass da Code drin steht und das vielleicht optisch aufgeräumt aussieht. Ich würde an deiner Stelle erst mal die unterschiedlichen Seiten vergessen und einen Code schreiben der eine Seite darstellt und eine einfache Aufgabe hat. Dann, wenn der Code ordentlich ist und die GUI von der Logik getrennt ist, dann würde ich mich an die zweite Seite wagen und so den Code von Anfang an ordentlich (und mit Nachfragen an die Profis hier) aufbauen. Achja und lass mal alles in einer Datei, das ist für ne Anfang übersichtlicher (so ging es mir zumindest).
Grüße
Dennis
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Sonntag 9. April 2023, 19:23
von Kalysto
Dennis89 hat geschrieben: ↑Dienstag 28. März 2023, 22:04
Hallo,
'main' ist üblicherweise die Funktion, aus der das Programm gesteuert wird. Dass ist also die Funktion die zum Programmstart aufgerufen wird, darin kannst du dann eine Insatz von 'Startseite' anlagen.
Code: Alles auswählen
from Startseite import Startseite
def main():
startseite = Startseite()
startseite.start_der_funktion()
if _name__ == '__main__':
main()
Klassen sind nicht dazu da, dass da Code drin steht und das vielleicht optisch aufgeräumt aussieht. Ich würde an deiner Stelle erst mal die unterschiedlichen Seiten vergessen und einen Code schreiben der eine Seite darstellt und eine einfache Aufgabe hat. Dann, wenn der Code ordentlich ist und die GUI von der Logik getrennt ist, dann würde ich mich an die zweite Seite wagen und so den Code von Anfang an ordentlich (und mit Nachfragen an die Profis hier) aufbauen. Achja und lass mal alles in einer Datei, das ist für ne Anfang übersichtlicher (so ging es mir zumindest).
Grüße
Dennis
Ich werde morgen einmal die Zeit haben und den Code mal erstellen wie ich es machen würde und Poste ihn dann einmal
Danke dir für deine Hilfe.
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Montag 10. April 2023, 17:28
von Kalysto
@Dennis89
Wenn ich das nun machen würde wie in deinem Beispiel:
Code: Alles auswählen
from Startseite import Startseite
def main():
startseite = Startseite()
startseite.start_der_funktion()
if _name__ == '__main__':
main()
wie kann ich nun das "self" von main an das "self" von start_der_funktion übergeben ?
Ich brauche die Möglichkeit das ich hier auf Variablen zurückgreifen müsste als Konkretes Beispiel:
Code: Alles auswählen
from Startseite import Startseite
class main(SafeAreaView):
def __init__(self):
self.device = 'iPhone' # 'iPad', 'Mac' etc...
startseite = Startseite()
startseite.Anmeldung()
if _name__ == '__main__':
main()
Startseite.py:
Code: Alles auswählen
class Startseite():
def Anmeldung():
# Hier müsste ich nun mit dem self.device weiter arbeiten können.. (und ja das self.device muss in der main stehen da ich das öfter verwenden muss)
wie kann man das Problem lösen ? habe schon versucht das irgend wie zu übergeben aber leider alles ohne erfolg.
des Weiteren ist es Korrekt das ich in meiner Startseite.py alle import's angeben muss und diese nicht von der main.py übergeben werden ?
Re: richtiges strukturieren von Programm Code / Konfigurations Datei
Verfasst: Montag 10. April 2023, 21:32
von Dennis89
Hallo,
ich weis nicht ob ich dich richtig verstehe. Das was 'Startseite' bekommen soll wird in der '__init__' entgegen genommen. Wieso fehlt die im letzten Post?
Vielleicht wäre es hilfreicher wenn du etwas mehr Code zeigst, damit man das Prolem besser versteht und das man versteht was du vor hast.
Grüße
Dennis