__blackjack__ hat geschrieben: Dienstag 31. März 2020, 00:13
. Besonders lustig wird so etwas wenn die globale Variable mal nicht den Wert hat, den man da eigentlich erwartet hätte.
Okay, das ist ein Argument, das ich verstehe, ist mir auch schon passiert. Wobei ich hier in meinem Code die Gefahr nicht als besonders hoch einschätze, dass das passiert.
Re Datenbank: Wenn die zweite Datei nicht da ist dann ist die erste Datei eben noch nicht in der Datenbank, denn solange die Transaktion nicht durch ein commit abgeschlossen ist, sind die Änderungen für Lesezugriffe noch nicht sichtbar und können wieder zurückgerollt werden. Das ist die Funktion von Transaktionen, dass man mehrere Änderungen machen kann, die entweder in ihrer Gesamtheit in der Datenbank landen oder gar nicht. Das auf Dateiebene selbst zu programmieren ist umständlich bis unmöglich wenn es portabel sein soll.
Das merke ich...
Das mit dem commit wäre ein Vorteil. Mal sehen, vielleicht komme ich mit der Datenbank klar. Mal probieren.
Du packst das auswefen des Sticks immer an komische/falsche Stellen. Die Funktion die das Anstecken des Sticks erkennen soll, sollte das Anstecken des Sticks erkennen und den Namen liefern. Und nichts anderes.
Das mag vielleicht daran liegen, dass ich den Code leider nicht zeilenweise verfolgen kann wie ich das gerne täte. Das hab ich bei IDLE zumindest noch nicht entdeckt.
Ich schreib mir dann immer die print() rein und lasse mir was ausgeben um zu verfolgen, was gemacht wird, oder halt auch nicht. Bei einigen Sachen wurde mir da an Stellen wo ich das eigentlich nach meinem Verständnis unbedingt was geben musste, bekam ich nichts. Gar nichts. (Zum Beispiel beim Versuch die Datei zu schreiben, wo du ja sagst, da krieg ich die Überprüfung quasi mitgeliefert. Wenn der Code aber gar nicht zu der Zeile geht? Wenn er ginge, müsste er dann ja auch über die print-Zeile.)
Also hab ich mir gedacht, lege ich die Überprüfung dahin wo sie mir Sinn macht, nämlich genau dann, wenn der Stick erkannt wird. Sind dann nicht beide Dateien da, kann er gleich wieder aufhören, Stick raus, weiter lauern was passiert.
Funktionsnamen sollten die Tätigkeit beschreiben die sie durchführen. `usb_ansteckerkenner()` und `auswerfer()` sind aber keine Tätigkeiten sondern eher Namen für ”Dinge”, also eher passivere Objekte. `warten_auf_usb_stick()` und `auswerfen()` wären passender.
Verstehe ich, wenn das jemand nachvollziehen will.
Python hat einen eigenen Datentyp für Wahrheitswerte (`bool`) mit den Werten `True` und `False`, dafür sollte man nicht die Zahlen 1 und 0 missbrauchen.
Das wollte ich eigentlich machen und hab das auch stehen gehabt, dann kam da eine merkwürdige Fehlermeldung dass False nicht definiert ist. Wenns halt nicht wollte, dann hab ich das so probiert um mal ein Ergebnis zu haben. die Zahlenwerte werden ja direkt in der Dokumentation (oder vielleicht hab ich das auch wo anders gelesen) erwähnt.
`gehts_weiter` ist überflüssig. Man muss nicht jedes Ergebnis an einen Namen binden.
Auch ne Angewohnheit die ich von VBA hab. Da pumpe ich alles mögliche in Variablen um zu sehen, was für Werte die annehmen, was vor allem hinter den einzelnen Objekten noch alles drinsteht. In dem Editor kann man da nämlich ganz bequem ins Objektmodell kriechen und ablesen was für Eigenschaften man manipulieren oder lesen kann. Allein schon den Wert angezeigt zu bekommen ist mir oft einiges wert zum Verständnis. (drum zig Zeilen mit print)
Das `usb_ansteckerkenner()` nicht der geeignete Ort ist um den Stick auszuwerfen sieht man auch daran das die Funktion ja den Namen zurück gibt. Wenn Du den Stick auswirfst, dann tut sie das aber nicht, sondern gibt implizit `None` zurück, was der Code an der Aufrufstelle dann versucht als Namen für den Stick zu verwenden, was natürlich zu einer weiteren Ausnahme führen wird. Was zu einem erneuten Versuch den bereits ausgeworfenen Stick erneut auszuwerfen, was wieder zu einer Ausnahme führt. Die dann das Programm beendet. Das ist alles sehr verwirrend strukturiert.
Wobei ich gerade sehe das `copy()` im Falle einer nicht gefundenen Datei gar keine Ausnahme auslöst, der Aufrufer also gar keine Möglichkeit hat darauf zu reagieren wenn das der Fall ist. Die Ausnahmebehandlung dort ist keine sinnvolle Ausnahmebehandlung. Einen Fehler einfach ausgeben und dann so weiter machen als sei alles in Ordnung ist sehr selten ein sinnvoller Umgang mit Ausnahmen. Und wenn man eine Ausnahme nicht sinnvoll behandeln kann, sollte man sie an der Stelle einfach gar nicht behandeln.
Das implizite `None` sollte keine Funktion zurückgeben, die mindestens eine ``return``-Anweisung enthält. Falls so eine Funktion auch `None` als Rückgabewert haben kann, dann sollte das explizit mit einem ``return None`` passieren, damit der Leser das deutlich sieht, und weiss das es Absicht ist und kein Versehen weil ein Ablaufpfad in der Funktion übersehen wurde.
Das gibt nicht None sondern "nope" zurück und ist auch ein Überbleibsel meiner print-debuggingversuche.
Die Funktion könnte dann so aussehen:
Ein nacktes ``except:`` ohne konkrete Ausnahmen ist selten bis nie eine gute Idee, weil es nur wenige Möglichkeiten gibt *alle* Ausnahmen, auch solche mit denen man gar nicht rechnet, sinnvoll zu behandeln. Eigentlich nur die Ausnahme zu protokollieren und dann erneut mit einem nackten ``raise`` wieder auszulösen. Letzteres kann man nur weg lassen wenn man sicher ist, dass danach kein Code mehr ausgeführt wird der zu Folgefehlern führt.
Das verstehe ich jetzt leider nicht. Muss ich erst noch mal google, was du mit raise meinst.
Bei Deinem Code erfolgt das Auswerfen des Sticks übrigends *nicht* wenn alle kopiert werden konnte. Soll das so? Ich hätte ja jetzt eher gedacht das es egal ist alles kopiert werden konnte oder nicht, das am Ende der Stick ausgeworfen werden soll‽
Ja, die Frage ist berechtigt. Aber so weit habe ich in der Tat noch nicht gedacht.
Der Code muss das tatsächlich noch machen und auch dann den Code mit den Schaltflächen neu starten, denn der muss ja die neuen Daten für die Beschriftung einlesen.
Danke für den Hinweis!
Warum bekommt `copy()` den Namen des Sticks? Der wird doch da gar nicht verwendet‽
Vergessen rauszunehmen. Ich hatte zuerst dort den Rauswerfer-Code platziert, was aber wegen der Folgefehler natürlich in noch mehr Fehler rannte.
Funktioniert und hat mir gleich die Augen aufgemacht für einen weiteren Fehler.
Bin nämlich bisher immer davon ausgegangen, dass die CSV-Datei aus Access in der Kodierung bei utf-8 ist. Jetzt hatte ich eine, die hat natürlich Westlich ISO..., also das was Microsoft standardmäßig rausgibt.
Das wird vermutlich so bleiben, denn inzwischen steht soweit fest, dass die Abfrage der DB wo alle Daten der Stellen die ggf. ausgedruckt werden sollen drin sind, mit einem kleinen Excel-Makro passieren soll.
Das Ding gibt aber mit Sicherheit ein csv aus das nicht Unicode ist.
Da muss ich also dann auch noch ran...
Danke für die Unterstützung!
Die Erklärungen helfen mir zu verstehen, was ich alles übersehe.