Posts by Dennis89

    Hallo,


    wieso ist in den Funktionen, die den Stand ändern sollen, nochmal ein 'event_detected'?


    Bevor du das Ganze grafisch darstellst, würde ich mich erst einmal um die Logik kümmern.

    Vergiss bitte gleich von Anfang an, das es globale Variablen gibt, Dieser Zustand macht ein Programm sehr unübersichtlich, schlecht wartbar und die Fehlersuche wird auch schwieriger. Wenn du dir Werte merken willst, brauchst du eine Klasse. Schau mal ob folgender Code deine Tore zählt:

    Ist ungetestet, ich hoffe es läuft fehlerfrei durch.

    Das ist wichtig um auch sicher zu gehen, dass dein Aufbau funktioniert.


    Wenn du dir dann sicher bist, dann kannst du dich um die Grafik kümmern.


    Grüße

    Dennis

    Hallo,

    SyntaxError: invalid syntax

    Das sollte so aussehen:

    Code
    [dennis@dennis ~]$ source test/bin/activate
    (test) [dennis@dennis ~]$ python
    Python 3.11.3 (main, May 24 2023, 00:00:00) [GCC 12.3.1 20230508 (Red Hat 12.3.1-1)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import ssl
    >>> 

    Nur eben mit 'python3' falls 'python' bei dir auf Python2 zeigt.


    Grüße

    Dennis


    Edit: Etwas zu langsam :sleepy:

    Du nutzt aus 'bosma' immer nur den ersten Wert aus der zurückgegebenen Liste, wieso gibst du die anderen dann zurück?

    Und man muss beim Vergleiche mit einem Wahrheitswert nicht extra noch mal den Wahrheitswert hinschreiben. 'if eintrag == True' ist das gleiche wie 'if eintrag'.


    So hier mal der erste ungetestete Zwischenstand:


    Das sind jetzt keine großen Änderungen, aber doch grundlegende Themen.


    Grüße

    Dennis

    Hallo,


    'time' wird importiert aber nicht genutzt.

    Auf Modulebene (der Code ohne Einrückungen) darf kein ausführbarer Code stehen. Hier werden nur Klassen, Funktionen und Konstanten definiert. Es gibt eine Ausnahme, das ist eine 'if'-Abfrage als Einstiegspunkt in die 'main'-Funktion. Darin sollte dein Programm starten und von dort werden weitere Funktionen aufgerufen, Argumente übergeben und wieder entgegen genommen.


    Gewöhne dir gleich an sprechende Namen zu verwenden und keine Abkürzungen. Das ist in der Mathematik manchmal etwas schwer, aber es ist auch sehr schwer Code zu lesen, der nur aus Namen mit einem Buchstaben besteht.


    Wenn du mit Dateien arbeitest solltest du immer den absoluten Pfad verwenden. Ein Pfad ist aber kein einfacher String. Den ein Pfad hat andere Eigenschaften als ein String. Erstellen kannst du den Pfad mit 'pathlib.Path'.


    Wenn du eine Datei öffnest, solltest du immer das encoding angeben. Es ist nicht garantiert, das automatisch das richtige genommen wird.


    Bei 'range' musst du den 'step' nicht angeben, wenn der 1 sein soll, das ist der default-Wert.


    Wieso belegst du 'h_ober' mit -1 und addierst bei der Benutzung 1 dazu? Dann kannst du doch gleich 'h_ober = 0' schreiben?

    'h_unter', 'h_ober', 'exponenten_unter' und 'exponenten_ober' sollten Konstanten sein.


    An 'plotten' wird 'obergrenze' übergeben, aber nicht benutzt.

    Strings formatiert man aktuell eigentlich mit 'f'-Strings.

    Wenn die 'obergrenze' 0 ist dann kann sie nicht auch größer 2 sein. Das dritte 'if' in 'intervall_prüfen' sollte ein 'elif' sein. Das heißt, wenn das vorherige True war, dann wird 'elif' gar nicht mehr geprüft. Komischer finde ich aber, das egal ob die Obergrenze 0 oder >2 ist, die Rechnung gleich ist. Zu was dann die Unterscheidung?

    Den Sinn hinter 'ausgabe' verstehe ich nicht. Wann setzt man das True? Vielleicht wäre ein sprechenderer Name hier auch hilfreicher.

    'B' ist auch so ein Name, aber nicht nur das er nichts aussagt, an der Stelle wollte ich noch sagen, das man Namen klein_mit_unterstrich schreibt. Ausnahmen sind Konstanten GANZ_GROSS und Klassen in PascalCase-Schreibweise.

    In 'jacobisymbol' kannst du diesen Ausdruck:

    Code
        if a == 2:
            if n % 8 == 1 or n % 8 == 7:
                return 1
            else:
                return -1

    kannst du etwas zusammen rücken:

    Code
        if a == 2:
            return 1 if n % 8 in [1, 7] else -1

    Dann kannst du die 'if' an manchen Stellen wieder durch 'elif' ersetzen.

    'while' braucht keine Klammern.


    In 'bosma' kannst du

    Code
                if pow(int(D), exp, n) == n - 1:
                    return [True, D]
                return [False, D]

    wieder vereinfachen

    Code
    return [True, D] if pow(int(D), exp, n) == n - 1 else [False, D]

    und ein 'elif' einbauen.

    Es ist verwirrend wenn eine Funktion zwei Arten von Rückgabewerte hat. Eine Liste oder eine negative Zahl. Normal gibt eine Funktion immer den gleichen Datentyp zurück.


    'vektor_anlegen' wird nicht benutzt. Man muss nicht alles an einen Namen binden, wenn man den Namen nur benutzt um ihn danach zum Beispiel zurück zu geben. dann kannst du gleich return laenge * [False] schreiben.


    In 'liste_vorbereiten' man will Index so wenig wie möglich benutzen, weil das relativ undurchsichtig ist. Du kannst direkt über den Inhalt der Tuple iterieren:

    Code
        for x_werte, _, y_roh in vektor:
            xwerte.append(x_werte)
            y_rohdaten.append(y_roh

    In 'liste_vorbereiten' würde ich die Werte nicht als Liste zurück geben, sondern einfach zwei Werte und die dann auch so entgegen nehmen und dabei kannst du dann wieder auf den Index verzichten.


    Soviel mal zum Allgemeinen Code. Für mehr Details ist es mir jetzt ehrlich gesagt zu spät und den Zwischenstand von dem hier geschriebenen in Form von Code, reiche ich morgen nach :thumbup:


    Grüße

    Dennis

    Hallo,


    vielleicht könnte man ja noch einwerfen, dass 'time' auch Funktionen zur Messung der Prozessdauer bietet, zum Beispiel process_time


    Der letzte Code von Hofei:

    Code
    Dauer: 0.013281221000000003


    Aus Interesse der gleiche Code, nur mit list-comprehension (weil ich das wirklich gerne nutze)

    Code
    Dauer: 0.009870833999999995


    Und dann noch der multiprocessing-Code von __blackjack__

    Code
    Dauer: 0.039969237000000005


    Alles mit der gleiche Hardware, allerdings ging gerade die Sonne unter 8o


    Grüße

    Dennis


    neuernutzer ich kann mich dem letzten Post von Hofei nur anschließen. So habe ich auch mit Python gestartet und auf diesem Weg lerne ich so auch regelmäßig weiter :thumbup:

    Hallo,


    bitte immer genau den Code posten, der einen Fehler geworfen hat und bitte die vollständige Fehlermeldung mit dazu posten.

    Ich persönlich werde aus deinem Beitrag leider nicht schlau.



    Grüße

    Dennis


    Edit: Fast vergessen 'global' ist nicht dafür bekannt Probleme zu lösen, eher um welche zu verursachen. Zumindest auf langfristige Sicht.

    Hallo,


    und falls du bei der 'combobox' bleiben willst:



    Weitere Infos:

    https://docs.python.org/3/libr…obox#tkinter.ttk.Combobox


    Grüße

    Dennis

    erstaunlicherweise werden beide Funktionen get_picture(ir_light, camera und

    send_mail() unmittelbar nach Aktivierung des Scripts ausgeführt, unabhängig

    von der eingegebenen Zeit und das Script bricht ab mit:

    Das ist nicht erstaunlich, sondern das ist genau das was du programmiert hast. Wenn der Interpreter das erste mal deinen Code durchgeht, dann sieht er einen Funktionsaufruf und ruft die Funktion auf. Ein Klammerpaar nach einem Funktionsname bedeutet, dass die Funktion aufgerufen werden soll.

    Stichwort: 'partial', falls 'sheudel da nicht was anbietet um Argumente mit zu übergeben. Schau mal in die Doku dazu.


    Grüße

    Dennis

    Hallo,


    'Button' hat gar kein 'was_held' :

    https://gpiozero.readthedocs.i…ble/api_input.html#button


    Du solltest nicht irgendwas an der 'Button'-Klasse hinzufügen oder überschreiben.

    Du benötigst das auch nicht, weil du einfach 'value' abfragen kannst, da bekommst du je nach gedrückt oder nicht eine 1 oder eine 0 ausgegeben.


    Was passiert, wenn du den Button jetzt 2 Sekunden gedrückt hälst?


    Grüße

    Dennis

    Hallo,


    'wait_for_motion' funktioniert so nicht. In der Doku steht dazu:

    Quote

    Pause the script until the device is activated, or the timeout is
    reached.

    https://gpiozero.readthedocs.i…ml#motionsensor-d-sun-pir


    Dein Programm wird solange angehalten, bis eine Bewegung erkannt wird. Du musst dann die Funktion 'on_moition' danach aufrufen, wenn das Programm fortgesetzt wird. Wenn du das so verwenden willst, dann muss das in eine Schleife, damit das Programm danach wieder wartet.



    Grüße

    Dennis

    Hallo,


    dein vorherigen Code mit dem 'relais' angepasst:

    Vielleicht kannst du so erkennen, was ich gemeint habe.


    Grüße

    Dennis

    Es ist in der Funktion 'main' definiert, aber nicht in 'get_picture'. Wie geschrieben, du musst das noch übergeben. Schau dir an, was in der 'main' alles mit 'camera' gemacht wird.


    Wenn du den Code von blackjack im Terminal startest und eine Bewegung erkannt wird, dann wird im Terminal nichts ausgegeben?


    Grüße

    Dennis

    Auf der Github-Seite gibt es ein Beispielcode:


    Was passiert wenn du den ausführst und die Karte an den Reader hälst? Bekommst du eine Ausgabe?


    Grüße

    Dennis

    Hallo,


    sorry für die Zwischenfrage.

    __blackjack__ ich bin neulich auf 'contextlib.suppress' gestoßen und ich finde das, nach dem ich jetzt weis was das macht, lesbarer wie die Ausnahmebehandlung mit 'pass'.

    Also zum Beispiel in der aktuellen 'main' könnte man ja schreiben:

    Code
            with contextlib.suppress(KeyboardInterrupt):
                motion_sensor.when_motion = partial(
                    on_motion, push_bullet, ir_light, camera
                )
                motion_sensor.when_no_motion = on_no_motion
                pause()


    Ich schau mir ja relativ viele Codebeispiele von dir und anderen Programmierer an, aber das ist mir noch nie aufgefallen. Wieso wird das nicht benutzt?


    Dank und Grüße

    Dennis

    Hallo,


    bitte poste immer die Fehlermeldung dazu.

    In Zeile 91wird vermutlich ein Fehler geworfen, weil es in deinem Code kein 'RELAIS_PIN' gibt. Sollte es aber, du kannst dir den 'MotionSensor' als Vorbild nehmen.

    Der Pin ist eine Konstante und erst in der 'main' wird dann der Sensor oder in deinem Fall das Relaise definiert. Das wird dann wiederum an die Funktion übergeben, die es benötigt.


    So wie jetzt ist dein Relaise global verfügbar. So etwas möchte man nicht haben, das kann ein sehr unordentliches und undurchsichtiges Programm zur Folge haben.


    Grüße

    Dennis

    Hallo,


    das wird ja nicht die ganze Klasse sein, den 'ki' und 'kp' wird gar nicht benutzt, aber ich vermute mal dass da noch irgendwo ein PI(D)-Regler auftauchen wird und da wäre 'ki' und 'kp' gebräuchliche Bezeichnungen in der Regelungstechnik: https://en.wikipedia.org/wiki/PID_controller

    Sonst würde ich aber auch keine weiteren genutzten Abkürzungen verteidigen wollen :)



    Grüße

    Dennis