Wir nutzen Cookies, um das allgemeine Benutzerelebnis zu verbessern. Mit der Nutzung unseres Wikis stimmst du der Nutzung von Cookies zu.

Debuggen von Skripten

Debuggen von Skripten

Ein häufiges Problem für Scratcher ist es, wenn ein Skript, welches einem zuvor fehlerfrei erschien sich nicht so verhält wie gewollt oder sich rot färbt. Diese Fehler sind im Normalfall menschliche Fehler, die, wenn man weiß wie, recht einfach zu beheben sind. Dieses Verfahren nennt man "debugging" (engl. entkäfern). Der Name stammt aus dem Jargon von amerikanischen Technikern im späten 19. Jahrhundert und wurde im frühen 20ten Jahrhundert mit Computern in Verbindung gebracht, als Grace Hopper ein "Ungeziefer" (engl. bug) aus ihrem Computer entfernte.

Skripte Inspizieren

Skripte inspizieren funktioniert häufig nicht so einfach wie erhofft. Wenn du ein Skript inspizierst macht es meist am meisten Sinn für den Schreiber. Du musst das Skript aber aus Sicht des Computers analysieren um den Fehler zu entdecken und zu beheben. Als Beispiel versuchst du die Summe der Faktoren 1/2+1/3+1/4+…+1/100 zu finden, dabei verwendest du folgendes Skript:

setze [n v] auf [100]
setze [summe v] auf [0]
wiederhole bis <(n) < (1)>
 ändere [n v] um [-1]
 ändere [summe v] um ((1) / (n))
ende

Dieses Skript funktioniert nicht, da beim letzten Durchlauf der Schleife die Variable n gleich 0 ist. Das führt dazu dass die Summe durch 0 geteilt wird und einen Rechenfehler hervorruft.

Es gibt auch andere Fehler die auftreten ohne das der Schreiber etwas bemerkt. Zum Beispiel in dieser Fortsetzung des vorherigen Skripts:

sage [Ich habe die Summe!]
sage (summe)
sage[War das nicht super?]

Das Skript wird beim Durchlauf lediglich "War das nicht super?" anzeigen, weil die vorherigen zwei Blöcke im einem Bruchteil einer Sekunde durchlaufen werden. Falls du Scratch 1.4 benutzt kannst du auch Einzelschritte benutzen. Diese verlangsamen dein Programm und hebt den momentan ausgeführten Block hervor. Leider wurde dieses Funktionalität mit Scratch 2.0 entfernt

Manchmal ist der Fehler rein logisch und erscheint einem komplett unbegründet. Diese Fehler sind meistens die Schlimmsten, weil du keinen richtigen "Fehler" erkennst. Zum Beispiel hast du ausersehen eine falsche Variable eingesetzt und überliest diesen weil er nicht offensichtlich ist. In solchen Situationen solltest du dein Programm selbst oder einen Freund Fragen es Block für Block durch zu lesen. Sei dir sicher das dein Freund jeden Schritt versteht und du Unklarheiten auflöst.

Übe das Entdecken von Fehlern

In diesen Scratch-Projekten sind absichtlich kleine Fehler eingebaut: Werde ein Code-Detektiv und versuche sie alle zu finden und zu beheben!

Fehler vermeiden

  • Die beste Methode unnötige Fehler zu vermeiden ist es schöne aufgeräumte Programme zu schreiben. Sortiere Skripte nach ihrer Funktion
  • Schreibe Kommentare damit du dich in die Funktion von deinen Skripten nach Pausen einlesen kannst oder um herauszufinden wo du bei Änderungen im Skript eingreifen musst.
  • Erstelle für häufig verwendete Skriptabschnitte benutzerdefinierte Blöcke, gegebenenfalls mit Parametern.
  • Kopiere nicht blindlings aus anderen Projekten, außer es ist die Intention des Originalprojektes. Neben moraler Urheberrechtsverletzung wird das kopierte Skript in deinem Projekt meist ohne große Änderungen nicht funktioniert.

Werte überprüfen

Musst du einen Wert überprüfen um herauszufinden warum ein Skript nicht funktioniert, gibt es ein paar Möglichkeiten.

Unter Nutzung des Sage () (Block) Blocks kannst du einen sich ändernden Wert überprüfen.

wiederhole fortlaufend
sage (((var1) + (var2)) * (var3)) //Liefert die Summe von (var1 + var2) * var3
ende

Erneuern einer Variable.

wiederhole fortlaufend
setze [teste v] auf (((var1) + (var2)) * (var3)) //Liefert die Summe von (var1 + var2) * var3
ende

Diese Methoden können auch benutzt werden um einen Wahrheitswert zu überprüfen:

wiederhole fortlaufend
sage <wird [Objekt1 v] berührt?> //Sagt aus ob Objekt1 berührt wird
end

Programme testen

Große, komplexe Programme zu testen ist oft sehr überwältigend, weil selbst die kleinste Änderung eine Kette von Fehlern auslösen könnte.

Der beste Weg ein Projekt zu testen ist durch dieses immer und immer wieder durchlaufen zu lassen. Bei großen Spiele oder Animationen ist diese Methode jedoch sehr schmerzhaft. An stattdessen kannst du sogenannte "Testskripte" in dein Projekt implementieren, die dir helfen Fehler zu finden. Du musst aber daran denken sie bei der Veröffentlichung deines Projektes sie wieder zu entfernen. Zum Beispiel fügst du in deinem Platformer ein Skript ein das auf Knopfdruck zum nächsten Level wechselt. Solche Programme sparen dir viel Zeit beim testen.

Um sicher zu gehen das dein Projekt funktionstüchtig bleibt solltest du bestimmte Tests automatisieren. Bei numerischen Funktionen zum Beispiel könntest du testen ob das Ergebnis korrekt ist:

Definiere quadriere (5) 
//Stell dir vor das wäre deine Funktion
falls <nicht <(lösung) = (25)>> dann
 Sage [Ups!] für (5) Sek.
 Sage [Fehler mit Eingabewert 5] für (5) Sek.
 stoppe [alles v]
ende

Definiere quadriere (n) erwarteter Wert (k)  
//Automatisiere den Test mit diesem Block
quadriere (n)
Falls <nicht <(Lösung) = (k)>> dann
 Sage [Ups!] für (2) Sek.
 Sage (n) für (2) Sek.
 stoppe [alles v]
ende

wenn gf angeklickt
quadriere (1) erwarteter Wert (1)
quadriere (2) erwarteter Wert (4)
quadriere (3) erwarteter Wert (9)

Häufige Fehlerquellen

Invalide Operationen

Mehr als häufig schreiben Scratcher Skripte mit ähnlichen Fehlern wie folgendes:

setze x auf (10)
wiederhole fortlaufend
ändere x um (-1)
sage ((1) / (x position))

Dieses Skript wirft einen Fahler auf, weil in der 10ten Wiederholung des Skripts X durch 0 geteilt wird. Man kann keine Zahl durch 0 teilen deswegen ist Scratch verwirrt und überspringt das Skript. In Scratch 1.4 streicht Scratch dir ein Programm rot an, falls solch ein Fehler auftreten sollte.

Ähnliche Probleme tauchen oft bei Wurzelrechnung, Logarithmen und Trigonometrie auf.

setze x auf (10)
wiederhole fortlaufend
ändere x um (-1)
sage ([Wurzel v] von (x Position))// Dieser Block wirft einen Fehler auf wenn x < 0.
sage ([Wurzel v] von ([Betrag v] von (x Position)))// Weil x immer größer als 0 ist gibt es hier keinen Fehler

Reihenfolge der Befehle

Das häufigste Problem für Scratcher ist es, wenn man seine Befehle in einer falschen Reihenfolge geschrieben hat. Zum Bespiel versucht man ein Objekt zu einer anderen Position gleiten zu lassen. Dafür benutzt man folgendes Programm:

setze Richtung auf (45 v) 
warte (0.5) Sek.
gleite in (2) Sek. zu x: (54) y: (0)
setze Richtung auf (90 v)

Das Objekt zeigt beim gleiten aber leider in die falsche Richtung und dreht sich erst um wenn es an seinem Ziel angekommen ist.

Ein guter Problemlösungsansatz ist es einfach die Befehle noch einmal durch zu gehen und jeden Schritt zu analysieren. Man kann aber auch einfach herumprobieren und die Lösung aus Zufall entdecken. Der Fehler in diesem Programm liegt daran, dass der "setze Richtung auf (90)" Block nach dem tatsächlichem Bewegen ausgelöst wird. Ordnet man die Blöcke richtig an sieht das ganze dann so aus.

setze Richtung auf (45 v) 
warte (0.5) Sek.
setze Richtung auf (90 v)
gleite in (2) Sek. zu x: (54) y: (0)

zeitliche Koordinierung

Ein anderes Problem ist das manchmal Skripte nicht zur korrekten Zeit ausgeführt werden und dadurch Fehler entstehen. Dieser Fehler taucht in Projekten auf, in denen 2 oder mehr Skripte mit einander ohne die Benutzung von Senden Blöcken oder Variablen co-operieren. Wenn das Timing nicht perfekt ist kann sich der Skriptablauf im kompletten Projekt verschieben. Hier sind einige Wege dieses Problem zu lösen:

Senden und Variablen

Das Nutzen von Senden Blöcken und Variablen kann dir helfen dein Programm wieder zu synchronisieren. Empfängerblöcke fangen immer ein neues Skript an. Sei also Bereit ein paar mehr Skripte in dein Programm zu implementieren. Bei der Nutzung von Variablen möchtest du vermutlich auf die Nutzung vom Warte bis () (Block) zurückgreifen. Alternativ kann man auch den "Wiederhole bis () (Block)" oder einen "Falls () (Block)" benutzen.

Exaktes timing

Wenn du nicht mit Senden Blöcken oder Variablen herumschlagen möchtest kannst du auch versuchen alle deine Skripte perfekt zu timen. Dafür solltest du den "Warte bis () (Block)" benutzen. Dieses Verfahren ist bei größeren Projekten aber nicht zu empfehlen.

Wiederholter Prozesse

Diese Methode ist hauptsächlich für komplizierte Spiele. Wenn du Schleifen besitzt solltest du bei Fehlern den Inhalt dieser Stück für Stück auseinander nehmen um den Fehlerhaften Teil zu finden. Gehe dabei systematisch von oben nach unten vor damit du den Fehler nicht überspringst.

Stoppuhr

Du kannst auch Programme mithilfe der Stoppuhr (Block) schreiben. Die Stoppuhr kannst du zurücksetzen und anderweitig manipulieren. Probier es ruhig aus man kann eine Menge damit anfangen!

Unverträglichkeit

Das seltenste Problem ist die Unverträglichkeit von Blöcken mit Scratch. In diesem Fall färbt sich ein Block rot und verliert seine Funktion. Dies passiert wenn du zum Beispiel Scratch 2.0 Blöcke in Scratch 1.4 versuchst zu verwenden. Das ist nicht machbar, da diese erst mit der neuen Version hinzugefügt wurden.

In Scratch 2.0:

Wenn gf angeklickt
erzeuge Klon von [mir selbst v]
Setze Stoppuhr zurück

In 1.4:

Wenn gf angeklickt
Unverträglich!
Setze Stoppuhr zurück

Blöcke wie "sage nichts" sind versteckt in Scratch 1.4 werfen aber auch keine Fehler auf.

Solch ein Fehler kann auch entstehen, wenn du einen Definiere () (Block) löschst, aber noch Verweise auf diesen in deinem Programm besitzt.



Code zum Einbinden ins Forum:
[wiki=de:Debuggen von Skripten]Debuggen von Skripten[/wiki]