@TobiOrNotTobi: Dein Programm ist doch etwas entfernt von dem was man für eine GUI braucht. Du hast nicht einmal eine einzige Funktion in Deinem Programm definiert. Mindestens eine hat jedes Programm, nämlich die Funktion in dem das Hauptprogramm steht. Das gehört genau so wenig wie Variablen auf Modulebene.
Auf Funktionen bauen dann Klassen auf, bei denen zusammengehörige Daten und Funktionen die auf diesen Daten operieren in Form einer Klasse mit Methoden zusammengeführt werden.
Klassen und objektorientierte Programmierung (OOP) braucht man dann für jede nicht-triviale GUI. Was dort dann neu dazu kommt, ist eine deutlich andere Ablaufsteuerung. Da kann man dann keine Schleifen mehr schreiben die ewig, oder auch nur lange laufen, denn das blockiert die GUI. Man schreibt bei GUIs keinen Code der am Stück linear abläuft, sondern Funktionen bzw. Methoden die von der GUI-Hauptschleife bei bestimmten Ereignissen aufgerufen werden, für die man diesen Code registriert. Also zum Beispiel gibt man eine Methode an die aufgerufen wird, wenn der Benutzer eine Schaltfläche anklickt, oder wenn er in einem Eingabefeld die Eingabetaste auf der Tastatur drückt. Dann darf diese Methode *kurz* etwas machen, und gibt dann die Kontrolle an die GUI-Hauptschleife zurück. Da man sich Zustand über solche Rückrufe hinweg merken muss, kommt man um OOP nicht herum.
Zum bisherigen Programm: `sys` und `os` werden importiert, aber nicht verwendet.
Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Die Zeichenkette 'leer' ist relativ willkürlich gewählt. Hier würde man eher `None` für Namen vewenden für die man an der Stelle noch keinen endgültigen Wert hat.
Sämtliche `str()`-Aufrufe sind letztendlich überflüssig. Nur an einer einzigen Stelle kann man jetzt schon alle einfach ersatzlos streichen. Und die Stelle wo tatsächlich etwas anderes als eine Zeichenkette übergeben wird, sollte man das gar nicht machen müssen, weil man das Datumsobjekt als ganzes als Zeichenkette formatieren kann.
Das ist auch eine komische Mischung zwischen `datetime` und `time`. Das `time`-Modul braucht man hier nicht, man kann das alles mit dem `datetime`-Modul erledigen.
Zeichenketten und Werte mit `str()` und ``+`` zusammenstückeln ist auch eher BASIC als Python. In Python gibt es dafür Zeichenkettenformatierung mit der `format()`-Methode und ab Python 3.6 f-Zeichenkettenliteralen.
Den Dateinamen würde man komplett mit '.txt'-Endung aus *einem* `datetime.date`-Objekt erstellen, das man in eine Zeichenkette hineinformatiert.
Zwischen Funktion und öffnender Klammer der Argumentliste gehört kein Leerzeichen.
Die ganzen ``if``\s die den Inhalt von `code` prüfen sollten bis auf das erste ``elif``\s sein.
Das ``else`` ist dann falsch und gehört mit der Prüfung der Vollständigkeit kein in den Zweig der bei 'A…' genommen wird.
Auf 'IN' oder 'OUT' kann man kürzer prüfen wenn man eine Liste und den ``in``-Operator verwendet statt zwei Vergleiche zu schreiben.
Tests wie ``code[0] == 'P'`` fallen auf die Nase wenn `code` die leere Zeichenkette ist. Wenn also jemand aus versehen (oder absichtlich) einfach nur die Eingabetaste drückt, bricht das gesamte Programm mit einem `IndexError` ab. Um zu prüfen ob eine Zeichenkette mit einer anderen anfängt, gibt es die `startswith()`-Methode, die auch funktioniert wenn die Zeichenkette leer ist.
Wenn alle Daten vollständig sind wird die gleiche Zeichenkette zweimal zusammengesetzt. Solche Wiederholungen macht man nicht. Die setzt man einmal zusammen, bindet das Ergebnis an einen Namen und benutzt den dann zweimal. Wiederholungen von Code und Daten machen Mehrarbeit sind fehleranfällig wenn man Änderungen vornehmen will/muss, weil man alle Kopien auf die gleiche Art ändern muss.
In dem Zeitstempel kommt ein Semikolon vor – das ist *ein* Zeitstempel, den sollte man nicht auf zwei Felder aufteilen. Das macht eine spätere Weiterverarbeitung nur unnötig schwer.
Bei Textdateien sollte man immer explizit eine Kodierung angeben.
Mit der ``with``-Anweisung stellt man sicher, dass die Datei auch unter allen Umständen wieder geschlossen wird, also insbesondere auch wenn ein Fehler zwischen `open()` und `close()` auftritt.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import datetime
def main():
dateiname = f'{datetime.date.today():%YKW%V}.txt'
print(dateiname)
zeitstempel = None
richtung = None
projekt = None
artikel = None
try:
while True:
code = input('Scan: ')
if code in ['IN', 'OUT']:
richtung = code
elif code.startswith('P'):
projekt = code
elif code.startswith('A'):
if projekt and richtung:
artikel = code
print('Eingabe vollständig.')
zeitstempel = f'{datetime.datetime.now():%d.%m.%Y %H:%M:%S}'
line = f'{zeitstempel};{richtung};{projekt};{artikel}\n'
print(line)
with open(dateiname, 'a', encoding='utf-8') as datei:
datei.write(line)
else:
print(
'\nEingabe unvollständig.\n'
'Erwartet werden in Reihenfolge: IN oder OUT, P xxxx'
' und A xxxx'
)
print('Bereits vorhanden:')
print('zeitstempel:', zeitstempel)
print(' richtung:', richtung)
print(' projekt:', projekt)
print(' artikel:', artikel)
except KeyboardInterrupt:
print('\nExit')
if __name__ == '__main__':
main()