Posts by __blackjack__

    hyle Deine Variante mit dem aktiv in einer laaaanglaufenden Schleife warten, funktioniert nicht wirklich, beziehungsweise ist das eher Zufall und hängt vom Backend und der Implementierung ab. Wenn die Threads für so etwas startet, kann es sein, das die Rückruffunktionen die Verarbeitung von weiteren Ereignissen oder gar der GPIO-Signale blockieren. Für diese Funktionen gilt das gleiche wie für „interrupt service handler“ oder GUI-Rückrufe: kurz was machen, und dann die Kontrolle schnell wieder an den Aufrufer zurück geben.


    Dennis89 ist darüber gestolpert, dass der Code definitiv nicht mit den Mock-Pins aus `gpiozero` funktioniert. Das kann aber beispielsweise auch für Implementierungen gelten, die die Pins in einem Thread ”pollen” oder gar auf Netzwerkkommunikation warten wie bei pigpio und einem entsprechenden Daemon.


    maxis1601 Der Code enthält überflüssigen Unsinn. Mal davon abgesehen von den unnötigen Klammern bei der ``if``-Bedingung ist auch die Bedingung selbst unsinnig, weil die *immer* wahr ist, denn wenn `when_held` nicht ”wahr” wäre, würde das bedeuten da ist keine Funktion zugewiesen worden. Dann wäre die Funktion aber auch nicht aufgerufen worden. Und Funktionen sind im boole'schen Sinne immer ”wahr”.


    Ohne das ``if`` hätte man dann eine ”Endlosschleife” die *immer* *genau* *einmal* durchlaufen und mit einem ``break`` abgebrochen wird. Womit das keine Schleife mehr ist, denn etwas was genau einmal durchlaufen wird, macht als Schleife keinen Sinn.


    `start` wird in der Funktion definiert, aber nicht verwendet. Und `button` wird auch nicht verwendet. Dann bleibt noch die Frage ob man die kleine Zeitverzögerung von 1/10 Sekunde aus der ehemaligen Schleife überhaupt noch braucht‽


    Was die Funktion braucht wäre `client`, denn das sollte als Variable nicht auf Modulebene existieren.


    `zeittest` ist als Name nicht so besonders. Es beschreibt keine Tätigkeit, was so das übliche Namensschema bei Funktionen und Methoden wäre, aber die Funktion hat auch irgendwie nichts mit Zeit und testen zu tun, die verschickt eine Nachricht.


    `Keyboardterrupt` sollte wohl besser `KeyboardInterrupt` heissen.


    Ich denke: 🤷‍♂️


    Die Frage ist bei so etwas auch das „allen Ernstes“, und warum Sender so etwas bringen. Oft will da einer ins Fernsehen, und die Sender/Sendungen wollen was möglichst kontroverses, damit's auf Twitter stürmt. Also beide sind scharf auf Aufmerksamkeit.

    schlizbäda Es gibt ja noch keinen ”Sieger” bei der Methode wie man am besten gendert. Relativ neu, neulich irgendwo gesehen das ï — quasi der Doppelpunkt auf das kleine i gelegt. Stört den Lesefluss weniger, ist ein Buchstabe (man kann dann beispielsweise ein Wort per Doppelklick markieren, wo der Doppelpunkt ”unterbricht”), und Screenreader die den Text vorlesen, kommen damit wohl auch besser/transparenter klar als mit Sonderzeichen mitten im Wort.

    Bezüglich Geany: Ich würde mit einem Texteditor und Java wahnsinnig werden. Java ist IMHO eine Sprache mit der man ohne eine gute IDE nicht programmieren kann, weil man dann zu viel Boilerplate-Code von Hand schreiben muss.

    mindthegap Weitere Anmerkungen: ``global`` bitte gleich wieder vergessen.


    Importe stehen üblicherweise am Anfang des Moduls und nicht irgendwo versteckt mittendrin. Damit man leichter sehen kann was die Abhängigkeiten sind.


    `random` wird importiert, aber nirgends verwendet.


    Sternchen-Importe sind Böse™. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.


    ``as`` beim Importieren ist zum umbenennen gedacht, aber `GPIO` wird gar nicht umbenannt.


    ``sys.argv[0]`` ist nicht wirklich geeignet um den Pfad zum Programm zu ermitteln. Den Pfad zum aktuellen Modul ermittelt man über `__file__`.


    Anstelle der `os.path`-Funktionen verwendet man in neuem Code eher das `pathlib`-Modul.


    `LED_PRO_BLOCK`, `LED_BLOCKS`, `LED_BASERIGHT`, `LED_LEFT`, `LED_RIGHT`, `LED_LOWTIME`, `LED_HIGHTIME`, `LED_LOW`, `LED_HIGH`, `maxRandom`, `distorsion`, `distorsionLow`, `LED_LOWTIMERANGE`, `LED_HIGHTIMERANGE`, `MUSIC_ON` werden definiert, aber nicht wirklich irgendwo verwendet. Und `LED_BASELEFT` wird auch nicht wirklich verwendet, weil da ausschliesslich eine Farbe drin steckt in der Liste.


    Die Funktion `allean()` wird definiert, aber nirgends verwendet. Sollte sie aber vielleicht, denn im Hauptprogramm steht noch mal Code der das gleiche macht. Die Funktion `alleaus()` ist nahezu eine Kopie von `allean()` und hat deshalb einen inhaltlich falschen Docstring. Kopieren und leicht anpassen von Code ist ein Warnzeichen, dass man das anders lösen möchte. Zum Beispiel durch eine Funktion und/oder eine Schleife. In diesem Fall will man einfach die Funktion von `allean()` von `alleaus()` heraus verwenden.


    Da sind ein paar sinnlose ``time.sleep(0.1)`` im Code verteilt‽


    `GPIO.cleanup()` sollte am Ende des Programms aufgerufen werden. Und auch das ``--clear``-Argument sollte am Programmende auf jeden Fall ausgewertet werden, an *einer* Stelle, nicht an zwei verschiedenen. `pygame.quit()` gehört dort auch hin.


    Das ``try``/``except KeyboardInterrupt:`` ist an der falschen Stelle, denn das bricht die ``while``-Schleife nicht ab.


    Man vergleicht nicht mit literalen Wahrheitswerten, denn da kommt nur wieder ein Wahrheitswert bei heraus. Entweder der, den man sowieso schon hatte, dann hätte man gleich den verwenden können. Oder dessen Gegenteil. Dafür gibt es ``not``.


    Da sind drei Tests auf `playSound` mit Code dazwischen. Das lässt sich zu einem Test zusammenfassen.


    `pygame.init()` wird nur aufgerufen wenn `playSound` wahr ist. Das macht keinen Sinn. Und wenn kein Sound ausgewählt ist, dann funktioniert auch das Zurückschalten von Rot nach Grün nicht, weil das am Ende der Soundausgabe passiert.


    Statt `left` und `right` überall im Programm zu testen, kann man eine Liste mit Strips anlegen und die einfach abarbeiten.


    Das zeichnen eines farbigen Kreises steht dreimal fast identisch im Quelltext. Ein Kandidat für eine Funktion.


    Ungetestet:

    mindthegap GUIs sind in der Regel nicht thread-sicher. Das gilt auch für Pygame. In dem `pir_callback()` darf man nichts an der GUI verändern, das kann sonst zu komischen Verhalten bis hin zu harten Abstürzen führen.


    Bei solchen Callbacks aus anderen Threads macht man am besten nicht viel, sondern signalisiert das nur an das Hauptprogramm.`pygame.event.post()` ist thread-sicher, man könnte sich also hier ein eigenes Event in die Hauptschleife schicken, und dann dort entsprechend darauf reagieren.


    Sonstiges: Es gibt zu viel Code auf Modulebene. Da sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.


    Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

    Franjo G: Mal hinten anfangend: Das `input()` am Ende ist sinnlos bis nervig. So etwas machen Konsolenprogramme nicht.


    Das Programm reagiert IMHO nicht so toll wenn man ungültige Werte eingibt, wie negative Werte oder nur 0en.


    Bei der Abfrage von `angle_alpha` steht drei mal fast der gleiche Code. Das kann man alles in eine Bedingung packen und die auch eher so formulieren wie der Kommentar das beschreibt: Zählen wie viele unbekannte Seiten es gibt.


    Bei den Berechnungen und um `str()`-Aufrufe sind teilweise sinnlose Klammern. Die sind unnötig und tragen auch nicht zum besseren Verständnis bei.


    Namen durchnummerieren ist keine gute Idee. Man weiss beim Lesen der Namen `output1()` und `output2()` nicht was diese Funktionen machen. Und die werden auch immer beide direkt nacheinander aufgerufen, das könnte man also auch in *eine* Funktion stecken. Oder einfach ”inline” schreiben. Das erste `print()` kann man auch nur *einmal* in das Hauptprogramm nach der letzten Benutzereingabe schreiben.


    Von den ganzen ``if``\s bei den Berechnungen + Ausgaben sollte ja nur *eine* Bedingung zutreffen, das heisst man würde hier besser mit ``elif`` arbeiten, damit nicht unnötig die ganzen Bedingungen nach dem Treffer auch noch geprüft werden. Und man kann in einem abschliessenden ``else`` dann auch eine Fehlermeldung ausgeben.


    Man muss nicht jedes Zwischenergebnis an einen (schlechten) Namen binden.


    Ungetestet:

    dte Die Bedingung kann man mit ``in`` etwas kürzer formulieren und ohne das man `event.type` zweimal hinschreiben muss.


    Statt `round()` möchte man wohl eher `int()` verwenden, denn `round()` impliziert, dass auch aufgerundet werden kann und je nach Koordinate dann vielleicht auch 1280 oder 720 heraus kommen könnte, wo die Werte aber nur von 0 bis 1279 beziehungsweise von 0 bis 719 gehen sollten.


    Die Klammern um die `event,.*`-Teilausdrücke sind unnötig.


    Python
        if event.type in [FINGERDOWN, FINGERUP]:
            x = int(event.x * 1280)
            y = int(event.y * 720)

    Die Zeile 12 macht keinen Sinn. Da wird ein `Image`-Objekt erstellt das nie irgendwo verwendet wird. Der Hinweis darauf ist Unsinn. Natürlich erstellt auch das laden eines Bildes aus einer Datei den Puffer in den das Bild geladen wird, in der Grösse, die das Bild braucht/belegt.


    Die Bilddatei hat aber beispielsweise schon mal nicht die Pixelabmessungen 648×480 und ist auch keine S/W-Bitmap, sondern ein RGBA-Bild:

    Python
    In [260]: from PIL import Image                                                  
    
    In [261]: image = Image.open("Downloads/ScreenshotVISWeahter.bmp")               
    
    In [262]: image.size                                                             
    Out[262]: (600, 448)
    
    In [263]: image.mode                                                             
    Out[263]: 'RGBA'

    Ich vermute mal stark, dass das wichtig ist, die richtige Menge an Daten im richtigen Format an das Display zu füttern.

    rasray Es geht nicht darum was er hat, oder nicht, sondern was er ist. Ist schon ein Unterschied ob man sagt, der Herr X hat ein Arschloch, oder der Herr X ist ein Arschloch.


    fred0815 Nee der Olaf hat nicht einen speziellen Menschen mit Brechmittel foltern lassen, der hat das generell für mutmassliche Drogendealer als mögliches Mittel eingeführt.

    Naja, in diesem Fall ja nicht wirklich. Da wird eher der Grote gemerkt haben, dass man sowas nicht einfach so machen kann, ohne dass sich das herum spricht. Möchte nicht wissen in wie vielen Tweets er seit dem erst recht als „Pimmel“ bezeichnet wurde.

    bug-reporter Das sich der Dienst von Hand starten lässt, heisst nicht, dass es keine Fehler in der Service-Datei gibt. Wenn Du von Hand startest, ist ja das System komplett gestartet. Wenn der Rechner startet, kann es beispielsweise sein, das irgendein Systemteil den Dein Dienst benötigt, noch nicht gestartet ist. Dann wäre das ein Fehler in der Service-Datei, dass da eine Abhängigkeit nicht angegeben ist.


    Falls Du selbst kein ``sys.exit(1)`` oder ``sys.exit("Fehlertext")`` im Quelltext stehen hast, dann gibt es beim Ausführen eine Ausnahme, denn das Programm endet ja offenbar mit einem Exit-Status 1. Normal wäre 0 wenn alles problemlos gelaufen wäre.


    Falls die Standard- und Fehlerausgabe noch nicht in ein Log umgeleitet werden, würde ich das mal machen und schauen was das Programm da ausgibt, wenn es abbricht.

    helmuth99: Anmerkungen zum Quelltext: Bitte Quelltext nicht als Bild posten sondern als Text. Es gibt da die Schaltfläche mit der Beschriftung „</>“ um Code einzufügen, so dass nicht nur die Einrückung erhalten bleibt, sondern man kann da sogar auswählen welche Programmiersprache das ist, um eine farbige Auszeichnung wie in einem Editor/einer IDE zu bekommen.


    ``as`` beim Importieren ist zum Umbenennen, `GPIO` wird aber gar nicht umbenannt.


    Beim `Adafruit_ADS1x15` ist das umbenennen in `ADA` nicht so wirklich toll, weil alle Module von der Firma Adafruit mit `Adafruit_` anfangen, und da `ADA` nur solange wirklich als Abkürzung funktioniert, solange man nur ein Modul von denen im Quelltext verwendet. Die Abkürzung ist auch eher kryptisch. Es wäre hier besser einfach konkret den Datentyp aus dem Modul zu importieren, statt das Modul abzukürzen.


    Das importierte `board`-Modul wird nicht verwendet.


    Wenn man etwas mit dem GPIO-Modul macht, sollte man am Programmende den Aufruf von `GPIO.cleanup()` sicherstellen.


    `b` ist ein kryptischer und damit schlechter Name für `True`. Er ist auch überflüssig, weil der sowieso nur an einer Stelle verwendet wird, und da hätte man dann auch einfach `True` direkt hinschreiben können.


    ``while`` ist keine Funktion und sollte auch nicht so geschrieben werden, als wäre es eine. Da gehört ein Leerzeichen hinter das Schlüsselwort und die Klammern sind überflüssig.


    Man nummeriert keine Namen. Dann will man entweder bessere Namen, oder gar keine Einzelnamen, sondern eine Datenstruktur. Oft eine Liste. So auch in diesem Fall.


    `gain` hat 1 als Defaultwert, das braucht man also nicht extra angeben. Dann wird der Code einfacher, denn man kann dann die `read_adc()`-Methode mit `map()` und einem `range()`-Objekt verwenden.


    Das zusammenstückeln von Zeichenketten und Werten mittels ``+`` und `str()` ist eher BASIC als Python. Dafür gibt es die `format()`-Methode auf Zeichenketten und f-Zeichenkettenliterale. Und wenn man die Werte in einer Liste hat, braucht man das auch nicht für jeden Wert einzeln hinschreiben, weil man die Liste abarbeiten kann.


    Ungetestet:

    nurazur Das etwas ”funktioniert” heisst bei C erst einmal gar nichts wenn der Standard zu etwas sagt, dass es undefiniert ist. Das ist ja gerade das perfide daran, dass man Code schreiben kann der ”funktioniert”, weil der Compiler etwas macht was man erwartet, an einer Stelle wo er im Grunde machen kann was er will.


    Das `u` ist nötig weil ein Überlauf bei ``<<`` bei `int` undefiniertes Verhalten ist, während bei `unsignet int` die Bits einfach rausgeschoben werden/verloren gehen. Und ähnliches gilt dann auch für das abziehen von 1 falls beim ``<<`` eine 0 heraus kommt, was wie gesagt nicht garantiert ist.