Fehlersuche in der PyneIDE
Du hältst das Programm an einem Haltepunkt an und prüfst seine Variablen Kerze für Kerze.
Code kann den Sprachregeln entsprechen und trotzdem etwas anderes berechnen als beabsichtigt. Mit dem Debugger kannst du die Ausführung anhalten, Variablen ansehen und Anweisungen einzeln verfolgen.
In diesem Kapitel untersuchst du den Abstand zwischen Schlusskurs und gleitendem Durchschnitt mit Länge fünf. Zuerst sagst du das Ergebnis voraus, dann siehst du nach, was das Programm berechnet hat.
Drei Arten von Fehlern
Ein Syntaxfehler verletzt die Schreibregeln des Codes. Dazu gehören ein fehlender Doppelpunkt oder eine falsche Einrückung. Der Editor zeigt das oft schon beim Tippen an.
Ein Laufzeitfehler tritt während der Programmausführung auf. Beispielsweise liest du einen Array-Index, zu dem es kein Element gibt. Die Ausführung kann dann mit einer Fehlermeldung stoppen.
Bei einem logischen Fehler kann das Programm trotzdem durchlaufen. Steht statt close - average der Ausdruck average - close im Code, kehrt sich das Vorzeichen um. Die Sprachregeln verbieten das nicht. Deshalb musst du das Ergebnis mit der Aufgabe vergleichen.
Unter View → Problems in Visual Studio Code findest du die vom Editor gemeldeten Probleme. Klicke auf eine Zeile, um zur Fehlerstelle zu springen. Lies die genaue Fehlermeldung, bevor du mehrere Zeilen umschreibst.
Ein Programm zum Untersuchen
Lege die Datei debug_average.py an:
"""
@pyne edge
"""
from pynecore import Series
from pynecore.lib import bar_index, close, color, log, plot, script, ta
@script.indicator("Average Distance", overlay=False)
def main():
average: Series[float] = ta.sma(close, 5)
gap = close - average
if bar_index == 10:
log.info("close={0}, average={1}, gap={2}", close, average, gap)
plot(gap, "Distance", color=color.blue)bar_index ist die Nummer der gerade verarbeiteten Kerze und beginnt bei null. Index 10 ist die elfte Kerze. Der Protokollaufruf schreibt in diesem historischen Lauf deshalb nur einmal.
log.info erzeugt eine formatierte Nachricht. Anstelle von {0}, {1} und {2} werden die drei anschließend angegebenen Werte in dieser Reihenfolge eingesetzt. Den Text mit den nummerierten Platzhaltern verarbeitet das Protokollsystem.
Führe das Programm einmal mit Run Pyne code aus. Die Linie muss positiv sein, wenn der Schlusskurs über dem Durchschnitt liegt. Auf den ersten vier Kerzen fehlen sowohl Durchschnitt als auch Abstand.
Vor einer bestimmten Zeile anhalten
- Klicke links neben der Zeilennummer von
plot(gap, ...). Die Markierung eines Haltepunkts erscheint. - Klicke über dem Code auf Debug.
- Falls eine Datenauswahl erscheint, wähle
demo. - Das Programm hält am Haltepunkt an. Öffne die Ansicht Run and Debug.
Ein Haltepunkt ist eine Stelle, an der der Debugger das Programm anhält. Die markierte Zeile ist noch nicht ausgeführt. Die Ergebnisse der vorherigen Zuweisungen kannst du bereits ansehen.
Der erste Halt kann auf der ersten Kerze liegen. Dort fehlt gap, weil noch kein vollständiges Fenster über fünf Kerzen vorhanden ist. Der Debugger zeigt diesen Zustand; der fehlende Wert ist für sich kein Programmfehler.
Erreiche eine Kerze nach der Aufwärmphase
Auf der während der Fehlersuche eingeblendeten schwebenden Werkzeugleiste führt die PyneIDE-Schaltfläche Next Bar zur nächsten Kerze. Die Namen der Symbole liest du, indem du den Mauszeiger darüber hältst. Suche Run to Bar…, klicke darauf, gib im erscheinenden Feld 10 ein und drücke Enter.
Auf der elften Kerze ist das Fenster für den Durchschnitt über fünf Kerzen vollständig. Suche in Variables nach average und gap. In der Gruppe Pyne kannst du die Daten der verarbeiteten Kerze prüfen, darunter bar_index und close.

average ist eine Series-Variable. Deshalb kannst du im Programm mit average[1] auch den vorherigen Wert verwenden. Der Durchschnitt der vorherigen Kerze muss nicht dem aktuellen entsprechen, denn das Fenster ist um eine Kerze weitergewandert.
Beobachtete Ausdrücke
Unter Watch kannst du Ausdrücke ergänzen, die du bei jedem Halt sehen möchtest. Probiere Folgendes:
close
close[1]
average
close - averageclose[1] ist der Schlusskurs der Kerze vor der angehaltenen Kerze. average ist deine eigene Variable. Das Ergebnis von close - average muss dem bereits berechneten gap entsprechen.
Beobachte Variablen und einfache Berechnungen. Schreibe keine Aufrufe von ta.sma, keine Orderaktionen und keine Aufrufe, die Arrays verändern, in Watch. Die Prüfung beim Debuggen darf den Programmzustand nicht verändern.
Zeilenweise und kerzenweise
Step Over führt zur nächsten Anweisung, ohne in die Einzelheiten einer aufgerufenen Funktion zu springen. Step Into kann in deine eigene Funktion hineingehen. Continue setzt die Ausführung bis zum nächsten Halt fort. Disconnect trennt die Debugger-Verbindung und beendet die Fehlersuche.
Next Bar arbeitet auf einer anderen Ebene: Es geht zur nächsten Kerze. Zeilenweises Vorgehen zeigt die Berechnung einer Kerze im Detail; kerzenweises Vorgehen zeigt die Entwicklung des Ergebnisses über die Zeit.
Die Verarbeitung der angehaltenen Kerze ist noch nicht abgeschlossen. Deshalb kann der Chart den zuvor fertigen Zustand anzeigen. Prüfe Index und Daten der aktuellen Kerze in der Gruppe Pyne.
Sieh dir vor dem Ablesen einer Variablen die markierte Zeile an. Liegt ihre Zuweisung noch vor dir, enthält sie noch nicht das gerade erwartete Ergebnis.
Einen Vorzeichenfehler finden
Beende den Debugger. Ändere die Zeile in:
gap = average - closeStarte die Fehlersuche erneut und gehe zur selben Kerze. Liegt der Kurs über dem Durchschnitt, ist gap jetzt negativ, obwohl die Aufgabe einen positiven Abstand verlangte.
In Watch zeigt close - average weiterhin die ursprünglich gewünschte Richtung. Der Vergleich beider Werte macht den Unterschied sofort sichtbar. Stelle die richtige Subtraktion wieder her und prüfe dieselbe Kerze noch einmal.
Probiere es selbst aus
Ergänze die Variable previous_close = close[1] und untersuche sie im Debugger. Welchen Kerzenindex muss ihr Schlusskurs bei Index 10 haben? Welchen Wert hat sie auf der allerersten Kerze?
Lösung der Aufgabe
previous_close = close[1]Auf Kerze 10 liefert sie den Schlusskurs von Kerze 9. Auf der ersten Kerze mit Index 0 fehlt der Wert, weil die Datei keine frühere Kerze enthält.
Setze die Zeile vor den Haltepunkt, damit sie beim Halt bereits ausgeführt ist. Nach der Prüfung kannst du die Hilfsvariable und die nur zur Kontrolle verwendete Protokollzeile entfernen.
Eine hilfreiche Fehlerbeschreibung
Wenn du um Hilfe bittest, nenne die Datei, die verwendeten Daten, die tatsächlichen Inputs und den Zeitpunkt der untersuchten Kerze. Gib auch erwarteten und erhaltenen Wert an. Statt „Die Linie stimmt nicht“ beispielsweise: „Auf dieser Kerze ist der Schlusskurs 101 und der Durchschnitt 100, aber der Abstand ist −1.“ Damit lässt sich die Berechnung prüfen.