Ankündigung

Einklappen
Keine Ankündigung bisher.

In der Tiefe: Validierungskonzept

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • saft6luck
    antwortet
    Zitat von enertegus Beitrag anzeigen
    Sorry, da weiss ich nicht was Du mit meinst?
    Klar.
    Normale Abfragen, also
    [highlight=epc]
    if a>2 then a=3 endif
    [/highlight]
    sind "normal" [was das auch heissen mag] zu behandeln und richtig.
    eben nicht, denn ein a>2 wird nur ausgewertet, wenn a sich ändert UND nur jetzt größer als 2 wird.
    Normale Fälle, also a ist weiterhin größer 2 sind problematisch und wenn ich change verwende, muss ich aufpassen, dass das ja im nächsten Zyklus sein kann, was die ganze Kette wieder durchlaufen kann.
    Die Denke ist grundsätzlich ereignisorientiert, wie es eben am KNX Bus so ist und die Programmierung an diesen orientiert ist.
    Also: Warum soll Rollo_Sonnenaufgang_m neu berechnet werden? Weil sich etwas ändert, hier change( sunriseminute() ) oder Rollo_Sonnenaufgang_frueher. Man muss also das Ergeignis nicht das Ergebnis (hier: Rollo_Sonnenaufgang_m) im Auge haben.
    Klar, weil der Bus Ereignisorientiert ist (wie ja die ganze Welt) kann man nur Ereignisorientierte Logiken implementieren. Das macht natürlich Sinn und daran beißt man sich dann fest. Ist ja auch leichter immer die gesamte Ereigniskette im Blick zu haben.
    [highlight=epc]
    // Sonnenaufgang
    Rollo_Sonnenaufgang_frueher = 15u08
    Rollo_Sonnenaufgang_h = sunrisehour()
    Rollo_Sonnenaufgang_m = sunriseminute(); /* -> Minuten: 0 <= m <= 59 */
    if change( sunriseminute() ) or Rollo_Sonnenaufgang_frueher then {
    if ( Rollo_Sonnenaufgang_m < Rollo_Sonnenaufgang_frueher ) then {
    Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_m + 60u08;
    Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_h - 1u08;
    } endif;
    Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_m - Rollo_Sonnenaufgang_frueher
    } endif
    [/highlight]
    Tja, und wann sieht change dann den change? Mit dem Init, erst nach der ersten Änderung oder wenn ich eine Konstante addiere? Darf ich die gesamte Logik dann noch in den Systemstart setzen? Das nenne ich basteln.

    Einen Kommentar schreiben:


  • enertegus
    antwortet
    Zitat von saft6luck Beitrag anzeigen
    Das mag schon sein, aber wie soll man denn ganz normale Abfragen mit Aktionen schreiben? Immer gleich neue Variablen für jeden Schritt?
    Sorry, da weiss ich nicht was Du mit meinst? Normale Abfragen, also
    [highlight=epc]
    if a>2 then a=3 endif
    [/highlight]
    sind "normal" [was das auch heissen mag] zu behandeln und richtig.
    Die Frage ist einfach: Wie kann man ganz gewöhnlichen Code programmieren?
    Nun, auf diese allgemeine Frage spare ich mir eine Binsenweisheit.

    Die Denke ist grundsätzlich ereignisorientiert, wie es eben am KNX Bus so ist und die Programmierung an diesen orientiert ist.
    Also: Warum soll Rollo_Sonnenaufgang_m neu berechnet werden? Weil sich etwas ändert, hier change( sunriseminute() ) oder Rollo_Sonnenaufgang_frueher. Man muss also das Ergeignis nicht das Ergebnis (hier: Rollo_Sonnenaufgang_m) im Auge haben.
    [highlight=epc]
    // Sonnenaufgang
    Rollo_Sonnenaufgang_frueher = 15u08
    Rollo_Sonnenaufgang_h = sunrisehour()
    Rollo_Sonnenaufgang_m = sunriseminute(); /* -> Minuten: 0 <= m <= 59 */
    if change( sunriseminute() ) or Rollo_Sonnenaufgang_frueher then {
    if ( Rollo_Sonnenaufgang_m < Rollo_Sonnenaufgang_frueher ) then {
    Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_m + 60u08;
    Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_h - 1u08;
    } endif;
    Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_m - Rollo_Sonnenaufgang_frueher
    } endif
    [/highlight]

    Einen Kommentar schreiben:


  • bmx
    antwortet
    Zitat von saft6luck Beitrag anzeigen
    "Wo steht denn, dass change() im nächsten Zyklus auf diese Änderung von a reagiert? Und warum merkt man davon nichts?" <- Die 2. Frage steht noch im Raum. Ich habe getestet und kann keine Rekursion erkennen. Es wird 1x durchlaufen und das war es.
    Michael hat im Betaforum am 8.1.2011 mal geantwortet auf ein Problem von mir:

    Zitat von enertegus
    Eine Variable ändert sich in einem Zyklus => Change(Variable) macht einen Impuls in der nächsten Verarbeitungsschleife. [...]
    Es hilft nur die Abfragen etwas zu entschachteln.
    Ich nehme an, das er das in die nächste Revision der Doku mit einpflegen wollte.

    Einen Kommentar schreiben:


  • saft6luck
    antwortet
    Zitat von enertegus Beitrag anzeigen
    Seufz - Ich bitte doch höflich um Sachlichkeit.
    Ja, ja, bin ja schon wieder still.
    Wie sollte sie denn sonst reagieren? Denk Dir das mal durch und mach auch gerne einen anderen Vorschlag.
    Das mag schon sein, aber wie soll man denn ganz normale Abfragen mit Aktionen schreiben? Immer gleich neue Variablen für jeden Schritt?
    Ich nehm die Kritk mal als Anregunng zur Ergänzung im Handbuch.
    ok
    Ja sischer. sischer - ich versteh ehrlich gesagt die Frage nicht
    Ich möchte doch nur eine einfache Rechnung und einen einfachen Vergleich.
    1. Der Vergleich nach größer ist immer wahr wenn einmal wahr und weiterhin größer: Wie soll ich also einen normalen Vergleich schreiben, wenn change auch nicht hilft?
    2. Wenn der Vergleich wahr ist, soll die Variable verändert werden, ist halt so ... Wie soll das dann gemacht werden, ohne dass das als Rekursion interpretiert wird und ohne neuen event?
    3. 'else' kann man auch nicht nehmen, da das ja eine 2. Abfrage wird, die nach der Änderung dann ja auch gleich wahr wird. Wie dann?

    Die Frage ist einfach: Wie kann man ganz gewöhnlichen Code programmieren?


    BTW. "Wo steht denn, dass change() im nächsten Zyklus auf diese Änderung von a reagiert? Und warum merkt man davon nichts?" <- Die 2. Frage steht noch im Raum. Ich habe getestet und kann keine Rekursion erkennen. Es wird 1x durchlaufen und das war es. EDIT: Manchmal sieht man den Wald vor lauter Bäumen nicht :-( War durch die innere Abfrage richtig so.
    BTW2. "Wenn nun a initialisiert wird, ist bei der ersten Verarbeitung a gültig und if change() wird nie ungültig." <- Warum ist a=10 anders initialisiert als a=sunriseminute()+5, bzw. löst das 2. direkt einen change aus?

    Einen Kommentar schreiben:


  • enertegus
    antwortet
    Zitat von saft6luck Beitrag anzeigen
    Auch wenn das mal wieder in die Kerbe schlägt:
    Seufz - Ich bitte doch höflich um Sachlichkeit.
    Wo steht denn, dass change() im nächsten Zyklus auf diese Änderung von a reagiert? Und warum merkt man davon nichts?
    Wie sollte sie denn sonst reagieren? Denk Dir das mal durch und mach auch gerne einen anderen Vorschlag.
    Ich nehm die Kritk mal als Anregunng zur Ergänzung im Handbuch.
    Und wie soll man dann in Stufen auf Werte reagieren können? Durch's Auge in die Schulter vom Fuß in's Knie?
    [
    Ja sischer. sischer - ich versteh ehrlich gesagt die Frage nicht

    Einen Kommentar schreiben:


  • saft6luck
    antwortet
    Zitat von enertegus Beitrag anzeigen
    Das wäre sicher eine Lösung.
    Wie gesagt, das Problem liegt m.E. in
    Auch wenn das mal wieder in die Kerbe schlägt: DAS ist mein Problem mit deiner Programmiersprache. "m.E." sollte es nicht geben, sondern klar verständliche Regeln.

    Ich habe diverse Versionen generiert, auch zweistufig, nur den change von sunriseminute() etc. und die einzige Version, die funktioniert ist die oben. Was nützen mir atomare Kommandos, wenn ich mich Stunden wegen solcher Kleinigkeiten spielen darf?

    [highlight=epc]
    a=10
    if change(a) then a=a+1 endif
    [/highlight]
    Wenn nun a initialisiert wird, ist bei der ersten Verarbeitung a gültig und if change() wird nie ungültig.
    Ändert aber man im Debugger a auf z.B. 0 so wird die if-Anweisung ungültig und einmal ausgeführt. Im nächsten Verarbeitungszyklus ist a wieder verändert und if change ist wieder ungültig und so weiter
    Wo steht denn, dass change() im nächsten Zyklus auf diese Änderung von a reagiert? Und warum merkt man davon nichts?

    Und wie soll man dann in Stufen auf Werte reagieren können? Durch's Auge in die Schulter vom Fuß in's Knie?

    Einen Kommentar schreiben:


  • saft6luck
    antwortet
    Zitat von bmx Beitrag anzeigen
    Moin, moin,

    nur mal so eine Vermutung: Es scheinen bei Systemstart alle Ausdrücke gültig zu sein. Da Du beim Untergang vor dem If-Konstrukt etwas dazuaddierst, wird das anscheinend auch entsprechend geändert. change() bedeutet lt. Michael ja, das sich in der vorigen Programmschleife an der Variable etwas geändert hat.
    Vielleicht addierst Du einfach einen Dummy wie unten und probierst mal, ob das dann klappt
    Ehrlich gesagt glaube ich das auch ... oder der Interpreter erkennt die Rekursion tatsächlich und führt den Code nicht aus ...

    So oder so ist es eine elende Bastelei, bis man mal eine funktionsfähige Version bekommt, nur um den Überlauf zu prüfen. Finde ich z.K.!

    Hier mal eine lauffähige Version (warum auch immer!):

    [highlight=epc]
    // Sonnenaufgang
    Rollo_Sonnenaufgang_frueher = 15s08
    Rollo_Sonnenaufgang_h = sunrisehour()
    Rollo_Sonnenaufgang_m_s = convert( sunriseminute(), 0s08) - Rollo_Sonnenaufgang_frueher; /* -> Minuten: -15 <= m <= 44 */


    if change( Rollo_Sonnenaufgang_m_s ) then {
    if ( Rollo_Sonnenaufgang_m_s < 0s08 ) then {
    Rollo_Sonnenaufgang_m_s = Rollo_Sonnenaufgang_m_s + 60s08;
    Rollo_Sonnenaufgang_h = sunrisehour() - 1u08;
    } endif
    } endif

    Rollo_Sonnenaufgang_m = convert( Rollo_Sonnenaufgang_m_s, 0u08 )
    [/highlight]

    Einen Kommentar schreiben:


  • enertegus
    antwortet
    Zitat von bmx Beitrag anzeigen
    [highlight=epc]
    // Sonnenaufgang
    Rollo_Sonnenaufgang_frueher = 15u08
    dummy = 1u08

    Rollo_Sonnenaufgang_h = sunrisehour()
    Rollo_Sonnenaufgang_m = sunriseminute() +dummy; /* -> Minuten: 0 <= m <= 59 */
    [/highlight]
    Das wäre sicher eine Lösung.
    Wie gesagt, das Problem liegt m.E. in
    [highlight=epc]
    a=10
    if change(a) then a=a+1 endif
    [/highlight]
    Wenn nun a initialisiert wird, ist bei der ersten Verarbeitung a gültig und if change() wird nie ungültig.
    Ändert aber man im Debugger a auf z.B. 0 so wird die if-Anweisung ungültig und einmal ausgeführt. Im nächsten Verarbeitungszyklus ist a wieder verändert und if change ist wieder ungültig und so weiter

    Einen Kommentar schreiben:


  • bmx
    antwortet
    Moin, moin,

    nur mal so eine Vermutung: Es scheinen bei Systemstart alle Ausdrücke gültig zu sein. Da Du beim Untergang vor dem If-Konstrukt etwas dazuaddierst, wird das anscheinend auch entsprechend geändert. change() bedeutet lt. Michael ja, das sich in der vorigen Programmschleife an der Variable etwas geändert hat.
    Vielleicht addierst Du einfach einen Dummy wie unten und probierst mal, ob das dann klappt ...

    [highlight=epc]
    // Sonnenaufgang
    Rollo_Sonnenaufgang_frueher = 15u08
    dummy = 1u08

    Rollo_Sonnenaufgang_h = sunrisehour()
    Rollo_Sonnenaufgang_m = sunriseminute() +dummy; /* -> Minuten: 0 <= m <= 59 */
    [/highlight]

    Einen Kommentar schreiben:


  • makki
    antwortet
    Natürlich lese ich das

    Makki

    Einen Kommentar schreiben:


  • enertegus
    antwortet
    Zitat von saft6luck Beitrag anzeigen
    Hallo Michael,
    kannst du mir noch schnell sagen, warum folgendes geht:
    Das zweite generiert u.U. (z.b Minuten auf 47 und Offset 50) eine Art Endlosschleife, da nach jeder Änderung "if change" immer wieder gültig ist.
    Ich dachte das sollte gefixt worden sein?!
    Was meinst Du sei hier nicht in Ordung? Auf die Schnelle (es ist ja schon spät [hoffentlich sieht das der Makki nicht, 23:00 und spät, tsss]) seh ich da nix Ungewöhnliches.

    Einen Kommentar schreiben:


  • saft6luck
    antwortet
    Hallo Michael,

    kannst du mir noch schnell sagen, warum folgendes geht:
    [highlight=epc]
    // Sonnenuntergang
    Rollo_Sonnenuntergang_verzoegerung = 20u08

    Rollo_Sonnenuntergang_h = sunsethour()
    Rollo_Sonnenuntergang_m = sunsetminute() + Rollo_Sonnenuntergang_verzoegerung; /* -> Minuten: 20 <= m <= 79 */

    if change( Rollo_Sonnenuntergang_m ) then {
    if ( Rollo_Sonnenuntergang_m > 59u08 ) then {
    Rollo_Sonnenuntergang_m = Rollo_Sonnenuntergang_m - 60u08;
    Rollo_Sonnenuntergang_h = Rollo_Sonnenuntergang_h + 1u08;
    } endif
    } endif
    [/highlight]
    folgendes aber nicht(?):
    [highlight=epc]
    // Sonnenaufgang
    Rollo_Sonnenaufgang_frueher = 15u08

    Rollo_Sonnenaufgang_h = sunrisehour()
    Rollo_Sonnenaufgang_m = sunriseminute(); /* -> Minuten: 0 <= m <= 59 */

    if change( Rollo_Sonnenaufgang_m ) then {
    if ( Rollo_Sonnenaufgang_m < Rollo_Sonnenaufgang_frueher ) then {
    Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_m + 60u08;
    Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_h - 1u08;
    } endif;
    Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_m - Rollo_Sonnenaufgang_frueher
    } endif
    [/highlight]

    Ich dachte das sollte gefixt worden sein?!

    Einen Kommentar schreiben:


  • saft6luck
    antwortet
    Zitat von enertegus Beitrag anzeigen
    Lokale Variablen werden gesondert definiert, alle anderen sind global, oder was meinst Du da?
    Ja, etwa so:

    [highlight=epc]
    :begin Akt(Aktor,Now)
    :global
    InitGA(Aktor)
    Urlaub=AUS
    :local
    Variable=0
    :return {
    Variable=Variable+1;
    if Now and !Urlaub then write(Aktor,Variable) endif
    }
    :end
    [/highlight]

    :global ist generell optional, ohne sind variablen auch global
    :lokal ist optional. Variablen, die unter :local deklariert werden, werden vom Compiler wie von dir vorgeschlagen bei jeder Ersetzung eibPC-intern mit einer einmaligen Kennung ergänzt und sind somit programmtechnisch lokal.

    Ob beide Schlüsselwörter nur einmal im Makro stehen dürfen ist dann von den Möglichkeiten des Parsers abhängig (vermeidet evtl. aber auch Fehler).

    Übrigens: Warum brauch denn :return einen Block, während unter :begin keiner notwendig ist?

    Einen Kommentar schreiben:


  • enertegus
    antwortet
    Zitat von saft6luck Beitrag anzeigen
    Ok, so hatte ich mir das vorgestellt. Dann könnte man ja dem Makro einen Parameter für die lokalen Variablen mitgeben, der deren Namen ergänzt -> kann man leicht selber machen
    So war das ja mal gedacht, doch der Anwenderkreis hier wollte ja eben lokale Definitionen.
    Finde ich zwar umständlich und ein Kommando im Makro würde mir besser gefallen, à la ':local ...' und ':global', aber wenn nur entweder oder geht würde ich für global plädieren mit einer Anleitung für lokale Variablen im Text.
    Das versteh ich nicht so ganz:
    Lokale Variablen werden gesondert definiert, alle anderen sind global, oder was meinst Du da?

    Einen Kommentar schreiben:


  • SnowMaKeR
    antwortet

    Wenn die Verarbeitung eines „Programmdurchlaufs“ abgeschlossen sind
    entweder Verarbeitungen oder ist

    Einen Kommentar schreiben:

Lädt...
X