Endlosschleife bei PixelChecksum

  • Hallo zusammen,

    ich bin neu hier im Forum.

    Als Autodidakt im Bereich Programmiersprachen lese ich zwar schon länger mit, möchte jetzt aber meine erste Frage stellen:

    Ich habe mir mittels der Funktion PixelChecksum ein SKript geschrieben, welches einen Telegram-Chat auf eingehende Nachrichten überwacht und jede neue Nachricht kopiert und an einen zweiten account weiterleitet. Dies ist ein reines Übungsscript und dient zunächst einmal nur dem Erlernen grundsätzlicher Funktionen.


    Folgende Situation liegt vor:

    Das Programm scannt den unteren Bildbereich auf Veränderungen und führt dann eine bestimmte Klickfolge durch, um den Text zu kopieren und anschließend weiter zu leiten.

    Bei einem ersten Probelauf habe ich jedoch festgestellt, dass sich das Programm in eine Endlosschleife begibt und durchgehend Nachrichten verschickt. Bei jeder neuen Nachricht ändert sich zwar der Text, die ENdlosschleife bleibt jedoch. Leider habe ich wohl ein Brett vor dem Kopf und finde den Fehler (die Endloschleife) nicht. Deshalb hoffe ich auf eure fundierte UNterstützung :)

  • Danke für den Link. Das klingt deutlich komplexer für mich, da ich mich wie gesagt noch im absoluten Anfängerbereich bewege. Zumal ich für Telepot (von der Arbeit aus) keine wirklichen Anfängervideos / Tutorials finden konnte...

  • Hi, ich hab da eine Vermutung was bei dir schief läuft. Es ist nicht direkt erstichtlich ob das gewollt oder ein Bug ist, aber mal sehen. Da dies (laut deiner Aussage) sowieso ein Übungsskript ist, helfe ich dir mal den Fehler zu finden. Ich werde dir keine Antwort präsentieren, jedoch eine Hilfestellung geben den Fehler selber zu finden. Das ist viel mehr lehrreicher meiner Ansicht nach. :P

    Schreib dir doch einfach mal nieder, was dein Skript genau macht in Form einer Flowchart. Du kannst dafür draw.io nutzen. Wenn du dann fertig bist, poste doch mal die Flowchart hier im Forum. Achte aber darauf dass diese sich auch mit deinem Skript deckt. Danach gehen wir den Fehler auf den Grund, vielleicht findest du Ihn ja auch schon beim Erstellen der Flowchart. ;)

  • Challenge accepted ?


    Ich suche noch eine Möglichkeit mir den Zustand des Skriptes (aktiv/pause) grafisch anzeigen zu lassen. Gibt es so etwas wie eine kleine Statusleiste oder eine andere Grafik dafür?


    VG

  • Gibt es so etwas wie eine kleine Statusleiste oder eine andere Grafik dafür?

    Schaue mal auf die rechte Seite der Statusleiste. Dort müsste eine kleine Grafik (A für AutoIt) erscheinen, falls Du ein Skript laufen hast. Damit lässt sich das Skript auch Abbrechen (Exit), wenn es 'hängt'

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Mit "TraySetToolTip" kannst Du auch Werte setzen, die bei MouseOver über das "A" Icon in der Statusleiste angezeigt werden.

  • Zitat

    Ich vermute es liegt an der Variablendefinition von $iChecksum?

    Nicht mal zwangsläufig. Deine Notizen da sind ziemlich auf den Punkt gebracht. Nun überleg dir einmal welcher Fehler genau auftritt und versuch mal die Stelle auf deiner Flowchart zu ermitteln. Fasse doch beides einmal in ausführlichere Worte hier im Forum zusammen.

    Dies soll dir dabei helfen die "Problemzone" in deinem Skript zu ermitteln. Sprich: Die exakte Stelle in deinem Skript was nicht so läuft wie es eigentlich sollte. Es ist wichtig sich einmal vor Augen zu führen was man bezwecken will und was demnach schief läuft. Der ganze Prozess nennt sich "debuggen". Das wirst du noch häufiger machen, zwar nicht in dieser exakten Form, kann jedoch nicht schaden das ganze einmal in einer Übungsaufgabe durchzugehen. Die Flowchart soll dir nur als mentale Stütze dienen.

    Achja - Und notiere dir auch JEDEN Schritt den du beim testen deines Skriptes gemacht hast. Es ist wichtig den Fehler reproduzieren zu können.

    PS: Wenn du keine Lust darauf hast, kannst du das auch gerne sagen. Dann nenne ich dir mal ein paar Stellen die dein Problem hervorrufen könnten.

  • Ich versuche es mal anders: ;)

    1. Das Skript wird gestartet

    2. Die aktuelle Nachricht steht im Chat

    3. iChecksum wird beschrieben (XXX)

    4. Das Programm wartet

    5. Eine neue Nachricht trifft ein

    6. Die aktuelle Checksum ist /= iChecksum

    7. Die Klicks werden ausgeführt

    8. iChecksum wird neu definiert


    ABER jetzt ist iChecksum = der aktuellen Checksum =>> Endlosschleife bis eine neue Nachricht eintrifft...


    Das müsste es doch sein, oder?

  • Und was soll dein Programm stattdessen machen als in der Endlosschleife zu warten? Wenn du die betroffene Stelle gefunden hast, markiere sie doch mal mit einem Kommentar im Skript und schreib dazu was stattdessen geschehen soll. Lad das dann mal hoch :P

  • Ich meine es heute Nacht während des Beruhigens unseres Nachwuchses gelöst zu haben:

    Ich habe jetzt die Variable zunächst außerhalb der _search-Funktion definiert und schreibe nach jedem Klick-Durchlauf den aktuellen Wert der PixelChecksum hinein. Und erst wenn dieser Wert ungleich zur aktuellen Summe ist, wird die _search wieder ausgeführt.

    Das ist jetzt nicht ganz dein Weg bzgl. Debugging, aber in meinem Kopf funktioniert es ;)

    VG Bucardo (und danke für die Unterstützung! V.a. Yjuq)

    Nachtrag: Leider funktioniert es nicht im Skript. Jetzt brauche ich doch einen Schubs in die richtige Richtung :-|

  • Hi Bucardo !

    Ich möchte den Lehrprozess von Yjuq nicht unterbrechen, daher nur einige Anmerkungen :

    Ich habe jetzt die Variable [Anm. : $iCheckSum] zunächst außerhalb der _search-Funktion definiert

    Das kannst Du natürlich machen. Da Du die Variable $iCheckSum derzeit aber nur innerhalb der _search-Funktion verwendest, ändert sich dadurch erst mal nichts.

    ... schreibe nach jedem Klick-Durchlauf den aktuellen Wert der PixelChecksum hinein.

    Da Du zu Beginn der _search-Funktion immer :

    $iCheckSum = PixelChecksum(1120, 936, 1632, 952)

    zuweist, ist eine erneute Zuweisung am Ende der If-Abfrage auch nicht relevant.

    Debugging :

    Füge an verschiedenen Stellen ConsoleWrites ein, damit Du den Ablauf verfolgen kannst.

    Um die Ausgaben beim Betrieb der .exe zu sehen, füge zu Beginn des Skriptes folgende Zeile ein :

    #AutoIt3Wrapper_Change2CUI=y

    Hier ein Demobeispiel, wie das aussehen könnte :

    Statt PixelChecksum habe ich die Veränderung einer Zufallszahl (1 oder 2) verwendet.

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Teste doch einmal das Skript von Musashi und dann guck doch mal ob sich das mit dem gewünschten Verhalten, wie du es dir vorstellst, auch deckt. Das ist im prinzip dein Skript nur vereinfacht auf die pure Logik. Wenn nicht, such die Stelle raus die dich stört und überleg dir was du ändern musst damit das Skript sich so verhält wie du es möchtest. Es hilft einfach mal niederzuschreiben was das Skript derzeitig macht und was es machen soll.

    Derzeitiges Verhalten:

    Wenn ich die Taste 3 drücke, beendet sich das Programm.

    Gewünschtes Verhalten:

    Wenn ich die Taste 3 drücke, soll der Benutzer gefragt werden ob sich das Programm beenden soll.

    Mal als einfaches Beispiel. Damit führst du dir selber vor Augen was du eigentlich willst und auf was du dich fokusieren musst. Und ich wiederhole das noch mal. Schreib es ins Forum! Warum? Weil aus deinen ganzen Antworten nicht ersichtlich wird was du willst! Ich hab eine Vermutung, bin mir aber nicht ganz sicher. Bisher ist nämlich niemand (außer dir) in der Lage den Fehler zu sehen. Warum? Weil es auf mich so wirkt, als ob du gerne eine Verhaltensänderung im Programm haben möchtest. Allerdings hast du nie benannt welches Verhalten du stattdessen gerne hättest.

    Deine Skriptlogik funktioniert nämlich! Du sagtest zwar du wärst in einer Endlosschleife, ja - Du hast ja auch 2 davon definiert. Allerdings hast du meine Frage aus Post #11 noch nicht beantwortet:

    Zitat

    Und was soll dein Programm stattdessen machen als in der Endlosschleife zu warten?

    Und vermutlich liegt auch hier dein Problem. Du weißt nicht wie du dein gewünschtes Verhalten umsetzt oder aber weißt nicht was du eigentlich willst und wofür, oder sehe ich das falsch? :P

    Ist aber in Ordnung, ich bin durchaus in der Lage dir Hilfe zur Selbsthilfe zu geben ohne dein Ziel zu kennen.

  • Danke für eure Anregungen (und die offenen Worte ;) )


    ich sehe das Problem des Skriptes darin, dass es immer wieder die Klickabfolge durchführt (als Schleife) bis eine neue Nachricht eintrifft, um diese dann wieder in einer Endlosschleife weiterzuleiten.


    ich möchte es aber so haben, dass jede Nachricht nur einmal weitergeleitet wird u d das Skript so lange wartet bis eine neue Nachricht eintrifft.


    Bitte entschuldigt dieses umständliche Rumgewurste :saint:

  • Dein Hauptaugenmerk sollte auf folgendes momentan liegen:

    Code
    $iCheckSum = PixelChecksum(1120, 936, 1632, 952)  ;gebe den aktuellen CheckSum-Wert in die Variable ein
       
    While $iCheckSum = PixelChecksum(1120, 936, 1632, 952) ; solange sich nicht ändert -> warte
        Sleep(1000)
    WEnd

    Im Prinzip hast du es schon dazu geschrieben, das sollte so lange warten bis sich was ändert. Was ist also die logische Konsequenz daraus? Dass sich in dem Bereich irgendein Pixel wohl verändert. Beobachte mal das Programm was du versuchst zu automatiseren. Verändert sich da etwas in dem definierten Bereich? - PS: Wir kommen den Bug schon ziemlich näher, mal schauen ob du Ihn findest. Er ist nicht gerade leicht ersichtlich. ;)

    Nachtrag: Hmn, vielleicht noch ein Hinweis. Geh mal diesen Teil (nur den Abschnitt) Schritt für Schritt durch, im Prinzip sieht dein Code verkürzt gerade so aus:

    Code
    While True
        $iCheckSum = PixelChecksum(1120, 936, 1632, 952)  ;gebe den aktuellen CheckSum-Wert in die Variable ein
       
        While $iCheckSum = PixelChecksum(1120, 936, 1632, 952) ; solange sich nicht ändert -> warte
            Sleep(1000)
        WEnd
    Wend

    Jetzt bedenke mal was passiert, wenn die erste Nachricht eintrifft. Darauf basierend müsstest du eigentlich erkennen können, was passiert und wieso es einfach weitere Nachrichten verschickt.

    2 Mal editiert, zuletzt von Yjuq (10. Oktober 2019 um 13:43)

  • Ich verstehe deinen Punkt. Was mich aber irritiert ist die Tatsache, dass neu eingehende Nachrichten (=Änderung der Prüfsumme) erkannt werden. Im Moment verhält sich das Programm so als hätte ich gar keine Bedingung für die Aktion (=Klicks) eingebaut. Es führt die Klickfolge immer wieder durch.


    Wenn ich deinen Code-Ausschnitt betrachte würde ich erwarten, dass das Skript sich in der „sleep“-Schleife dreht. Aber es führt ja die Mausklicks aus.


    in einem früheren Programm habe ich mal mit Schaltern rumprobiert:


    wenn Bedingung erfüllt und Schalter = 0 -> Aktion und Schalter auf 1. Beim nächsten zu beobachtenden Ereignis Schalter auf 0 und von vorne. Damit ließen sich die „Dauerklicks“ auch vermeiden.

  • Zitat

    wenn Bedingung erfüllt und Schalter = 0 -> Aktion und Schalter auf 1. Beim nächsten zu beobachtenden Ereignis Schalter auf 0 und von vorne. Damit ließen sich die „Dauerklicks“ auch vermeiden.

    Sieh mal einer an, du bist auf einer sehr heißen Spur! Die Frage ist nun, warum dein momentanes Skript sich anders verhält. Betrachten wir mal die momentane ausgangslage:

    Code
    While True
        $iCheckSum = PixelChecksum(1120, 936, 1632, 952)  ;gebe den aktuellen CheckSum-Wert in die Variable ein
       
        While $iCheckSum = PixelChecksum(1120, 936, 1632, 952) ; solange sich nicht ändert -> warte
            Sleep(1000)
        WEnd
    Wend

    Schreib mal alles nieder, was passiert sobald die erste Nachricht eintrifft. Und zwar so detailliert wie möglich! Wie lange dauert es, spielen sich Animationen ab? Zu welchem Zeitpunkt wird die Pixel Checksumme eingefangen? etc.

    Ich hoffe dir fällt dann langsam selber auf was da eigentlich passiert. :)

    Obwohl ich dir eigentlich schon die Lösung auf dem Präsentierteller vorlege...

  • Werde das nachher mit einer IF/THEN/ELSE Funktion ausprobieren. Ich glaube das Problem liegt in der While Funktion und der Tatsache, dass er solange 1=1 ist (im übertragenen Sinne) eben einfach die Schleife abfährt. Diese einmalige Ausführung pro neue Nachricht lässt sich wohl einfacher durch die IF/THEN/ELSE Funktion lösen...


    p.s. das mit dem ausführlichen Aufschreiben lässt sich im Moment schlecht umsetzen, da ich sehr viel unterwegs bin und immer nur kurze Pausen habe.

  • Nö, der Bug ist ein anderer...

    Nachdem dein Program die Klickabfolge durch hat, geht diese ja aus deiner _search() Funktion raus. Allerdings ist $go noch auf 1, wodurch diese direkt wieder in die _search() Funktion geht. Logischerweise wird dadurch auch $iCheckSum = PixelChecksum(1120, 936, 1632, 952) gespeichert. Das geschieht alles ziemlich schnell.

    Was ist aber, wenn das Versenden der Nachricht noch in der Animation ist und $iCheckSum = PixelChecksum(1120, 936, 1632, 952) gerade die Momentaufnahme erwischt, wo das Program noch die Animation für das Versenden der Nachricht abspielt? Tja, dann hast du Pech. Heißt: Dein Program nimmt ZU SCHNELL die Pixel Checksumme auf... Da kannst du noch so viele If-Abfragen rein packen, das löst das Problem nicht. In deiner momentanten Skriptversion ist es am einfachsten, wenn du am Anfang der _search() Funktion einfach mal Testweise ein Sleep(1000) rein packst. Das ist der Bug.

    PS: Ich nutze Telegram nicht oder habe es jemals genutzt. Darum weiß ich nicht wie das ganze per Animationen etc. in dem Programm aussieht. Aber ich bin ziemlich zuversichtlich das dies exakt der Fehler ist der auftritt.