Scheife nur einmal ausführen

  • Hallo Forum,

    ich frage mit meinem Script den Stromverbrauch ab und möchte einen Event auslösen wenn der Verbrauch einen Schwellenwert unterschreitet. Das allerdings nur einmal, dafür habe ich es mit einer Schleife versucht:

    Code
    while 1:
            current_value = wert()
            if current_value < 10.0:
                    for i in [1]:
                            Message()
                    break
            else:
                    continue

    Der else Teil läuft wie gewünscht, also wert > 10 mache nichts und warte, aber der If Teil wird entweder unendlich ausgeführt, oder die Schleife beendet sich nach dem Message() einmal ausgeführt wurde.
    Ist die Schleife der richtige weg für mich ? Ich weiß das es für die GPIO´s einen Interrupt gibt der die Veränderung feststellt, aber so etwas läuft wohl hierfür nicht. Hätte jemand noch eine Idee ?

    Gruß
    Frank

  • Hi,
    also nur um erstmal die Gedanken zu sortieren und weil du immer von einer Schleife und dem else-Teil schreibst. Du hast in deinem Script eine while-Schleife, eine if-else-Anweisung und eine for-Schleife. while-Schleife um auf den Wert zu warten, ok. if-Anweisung, um den Wert zu prüfen, ok. Das continue im else-Teil ist überflüssig, da ist nichts mehr zu überspringen. Aber wenn der Event (Message()?) nur einmal ausgeführt werden soll, warum dann in eine for-Schleife, die bis 1 zählt?. Die for-Schleife ist für mich unnütz.

    Woran erkennst du, dass der if-Teil 'unendlich' ausgeführt wird? Wird dann Message() auch unendlich ausgeführt? Der if-Teil kann eigentlich gar nicht unendlich ausgeführt werden, sondern es ist die while-Schleife, die immer wieder durchlaufen wird. Aber sobald die if-Bedingung eintritt müsste nach Message() die break-Anweisung die while-Schleife beenden.

    Gruß

    Einmal editiert, zuletzt von rob.z (11. Juli 2015 um 10:41)


  • Hi,
    also nur um erstmal die Gedanken zu sortieren und weil du immer von einer Schleife und dem else-Teil schreibst. Du hast in deinem Script eine while-Schleife, eine if-else-Anweisung und eine for-Schleife. while-Schleife um auf den Wert zu warten, ok. if-Anweisung, um den Wert zu prüfen, ok. Das continue im else-Teil ist überflüssig, da ist nichts mehr zu überspringen. Aber wenn der Event (Message()?) nur einmal ausgeführt werden soll, warum dann in eine for-Schleife, die bis 1 zählt?. Die for-Schleife ist für mich unnütz.

    Woran erkennst du, dass der if-Teil 'unendlich' ausgeführt wird? Wird dann Message() auch unendlich ausgeführt? Der if-Teil kann eigentlich gar nicht unendlich ausgeführt werden, sondern es ist die while-Schleife, die immer wieder durchlaufen wird. Aber sobald die if-Bedingung eintritt müsste nach Message() die break-Anweisung die while-Schleife beenden.

    Gruß

    ja ist etwas verzwickt, meine Idee war hat über die for Schleife nur einen Aufruf zu starten, aber klar ist unnütz. Wenn ich die for schleife rausnehme ändert sich auch nichts. Auf den else Teil könnte ich wohl ganz verzichten ? Wichtig ist für mich das "Message" nur einmal aufgerufen wird wenn der schwellenwert <10 unterschritten wird die Schleife aber aktiv bleibt und beim nächsten unterschreiten des Schwellenwertes wiederum "Message" ausgeführt wird.

    Code
    while 1:
            current_value = wert()
            if current_value < 10.0:
                   Message()
                    break

    Das wäre dann erst mal so aber hierdurch wird die Schleife beendet.

    Einmal editiert, zuletzt von firstfacility (11. Juli 2015 um 11:42)

  • Wartet denn der Programmablauf in der Zeile (Zeile 2), in der wert() ausgelesen wird, solange bis ein neuer Wert kommt, oder kann es sein, dass da mehrmals der gleiche wert() abgerufen wird, weil er sich so schnell nicht geändert hat. Wenn dann jedesmal der wert() unter der Schwelle liegt, wird auch mehrfach Message() ausgegeben. Ein Schleifendurchlauf liegt ja so im Milli- bzw. Mikrosekundenbereich. Mit time.sleep() in der Schleife ließe sich eine Wartezeit einbauen. Die break-Anweisung beendet die while-Schleife komplett. Das bedeutet, es wird mit dem fortgesetzt, was nach der Schleife kommt. Wenn die wert()-Überwachung aber weiter laufen soll, dann muss das break weg.

    Code
    import time
    while 1:
           current_value = wert()
           if current_value < 10.0:
                  Message()
           time.sleep(1)

    Also abhängig davon, in welchem Zeitabstand wert() sich ändern sollte, eine Pause in der Schleife.

  • der wert() wird alle 4 Sek erneuert, und je nach dem welche aktuelle Leistung grade anliegt kommt immer der gleiche Wert, bis sich eben etwas verändert. Dies kann innerhalb der Zeit time.sleep sein oder auch nicht. Von daher leider keinen Erfolg.
    Aber Danke für den Versuch.

  • Hallo firstfacility,

    ich würde dem Programm-Ausschnitt noch eine weitere Variable gönnen, z.B. last_value. Diese wird bei Aufruf von message() auf den Wert von current_value gesetzt. message() wird aber nur aufgerufen, wenn last_value <= 10.0 UND current_value < 10.0 ist.

    Liefert Deine Funktion wert() einen Wert im Abstand von 4 Sekunden - oder wird hier der Mittelwert über diesen 4Sekunden-Zeitraum ermittelt?


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (11. Juli 2015 um 12:42)


  • Hallo Andreas,

    ich bekomme einen Mittelwert über 4 Sek. Dein Vorschlag würde mein Problem um einen Durchlauf nach hinten setzen oder ?

    schöne Grüße
    Frank

  • Hallo Frank,


    ich bekomme einen Mittelwert über 4 Sek. Dein Vorschlag würde mein Problem um einen Durchlauf nach hinten setzen oder ?

    wieso?
    Schau mal hier:

    1. 0 - 4 Sek.: Messwert 11 => Keine Meldung
    2. 4 - 8 Sek.: Messwert 9.7 => Meldung & last_value auf 9.7 setzen
    3. 8 -12 Sek.: Messwert 9.5 => Keine Meldung, da last_value < 10.0
    4. 12-16 Sek.: Messwert 10.5 => keine Meldung, last_value wieder löschen
    5. 16-20 Sek.: Messwert 12 => keine Meldung
    6. 20-24 Sek.: Messwert 9.8 => Meldung & last_value auf 9.8 setzen

    So soll es wohl sein, oder?

    Also gönne Deinem Programm noch eine Hilfsvariable... Das kann aber auch eine Variable sein, die nur den Status festhält (0 bei keine Meldung mehr ausgeben, 1 bei Überschreiten des Messwertes 10, so dass wieder eine Meldung bei Unterschreiten erlaubt ist).


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • wieso?
    Schau mal hier:

    1. 0 - 4 Sek.: Messwert 11 => Keine Meldung
    2. 4 - 8 Sek.: Messwert 9.7 => Meldung & last_value auf 9.7 setzen
    3. 8 -12 Sek.: Messwert 9.5 => Keine Meldung, da last_value < 10.0
    4. 12-16 Sek.: Messwert 10.5 => keine Meldung, last_value wieder löschen
    5. 16-20 Sek.: Messwert 12 => keine Meldung
    6. 20-24 Sek.: Messwert 9.8 => Meldung & last_value auf 9.8 setzen

    So soll es wohl sein, oder?


    bin begeistert, stimmt so soll es sein. Hättest du noch ein Stück code für mich ?

  • Hi Frank,
    für time.sleep() lässt sich eine Zeit festlegen. Das kann 1 Sekunde sein oder 5 oder 60. Wenn also der Wert nur alle 4s erneuert wird, dann wählst du eben für time.sleep() 4s oder größer. Der Vorschlag von Andreas ist absolut richtig, so wird eine Änderung bzw. Nichtänderung festgestellt, aber ohne time.sleep() fragt deine Schleife den Wert tausendfach pro Sekunde ab. Das ist nicht nur unnütz, sondern belastet auch die CPU. Ich würde also time.sleep() und eine Hilfsvariable verwenden.

    Gruß

    Code
    import time
    while 1:
          current_value = wert()
          if current_value < 10.0 And last_value > 10.0:
                 Message()
          last_value = current_value
          time.sleep(4)

    Einmal editiert, zuletzt von rob.z (11. Juli 2015 um 14:27)

  • Hallo Frank

    in Icon würde ich es so machen:

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • danke, danke, danke..... genau das läuft. Eine Kleinigkeit vielleicht wenn ich das in einem Thread laufen lassen möchte:


    bekomme ich einen Fehler:

  • Hallo Frank,

    bevor Du

    Code
    last_value >10


    vergleichen kannst, muss die Variable

    Code
    last_value

    auf irgendeinen Wert gesetzt worden sein... Genau das versucht Dir das System mitzuteilen.


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • hm, blicke grad nicht durch...

    Code
    while 1:
    current_value = wert()
            if current_value < 10.0 and last_value > 10:
                    Message()
            last_value = current_value
            time.sleep(4)

    das läuft aber das nicht ...

    Was mache ich falsch ?

  • du musst die Zuweisung current_value = wert() innerhalb der Schleife machen. Und schreib mal last_value => 10. Also so:


  • geht leider nicht der Fehler bleibt.

  • Hallo Frank,

    warum setzt Du denn unsere Ratschläge von #13 und #15 nicht um? Kein Wunder, dass es nicht funktioniert!

    Nochmal: Du vergleichst eine Variable, die vorher noch nicht gesetzt wurde, mit einer Konstanten. Setze diese Variable vor der [font="Courier New"]while[/font]-Schleife.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Sorry, hab die Fehlermeldung auf der letzten Seite jetzt erst gesehen. Es stimmt was Andreas sagt, last_value muss vor der Schleife einmal gesetzt werden. Aber mit global current_value scheint es auch ein Problem zu geben. Verwendest du die Variable auch außerhalb des Threads. Macht für mich keine Sinn, ich nehme sie mal raus.

    So könnte es funktionieren. Ich würde mir für Thread allerdings noch einen anderen Namen überlegen. Ist ein wenig verwirrend, wenn ein Thread Thread heißt. Fördert nicht gerade die Lesbarkeit.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!