9.3 Logikfehler und Rechenfehler

Fehler dieser Art sind schon wesentlich schwerer zu finden. Schon deswegen weil keine Fehlermeldung ausgegeben wird. Das Programm läuft bis zum Ende durch. Allerdings ist das Ergebnis durch den Fehler nicht wie erwartet. In Sonic Pi kann das zum Beispiel ein falscher Ton sein.

In einem einfach strukturiertem Song ist es recht einfach, die Stelle zu identifizieren, wo der falsche Ton erzeugt wird. Der Log-Viewer kann hierbei wertvolle Dienste leisten.

Aber manchmal muss man doch etwas mehr Aufwand in die Fehlersuche stecken. Hat man den ungefähren Fehlerort im Code herausgefunden, dann sollte man „puts“ Befehle in geeigneten Abständen einbauen, um die aktuellen Werte der Variablen auszugeben.

In Code 21 ist ein Beispiel zu sehen, das tatsächlich einen Fehler enthält. Eigentlich sollen im Song alle 4 Instrumente nacheinander zu hören sein:

sound = [:piano, :fm, :pulse, :prophet]

Tatsächlich werden alle Töne mit dem Piano-Sound gespielt. Das ist zu hören (wenn Du den Code unten in Sonic Pi kopierst und dann laufen lässt), und auch im Log-Viewer zu sehen.

 

Wenn der Sound sich nicht verändert, dann liegt die Vermutung nahe, dass der Sound nicht richtig aus der Liste ausgewählt wird. Um mir anzeigen zu lassen, welcher Eintrag in der Sound-Liste ausgewählt wird, füge ich an der Stelle, wo der Sound eingestellt wird – also bei „use_synth“ – zwei Befehle ein:

puts iSound
puts sound[iSound]
Da diese Befehle aber nur eine Ausgabe unter vielen erzeugen, unterdrücke ich die normale Ausgabe mit
use_debug false
Wenn ich jetzt das Programm laufen lasse, werden im Log-Viewer die gewünschten Ausgaben angezeigt.

Tatsächlich ist in der Ausgabe zu sehen, dass immer der erste (mit dem Index 0) Soundname aus der Liste ausgewählt wird. Das liegt daran, dass der Zähler für den Index immer auf der 0 bleibt und nicht hochgezählt wird. Das kann jetzt 2 Gründe haben.

1. Der Code, der den Zähler hoch zählt ist verkehrt: Vielleicht wird eine andere Variable hochgezählt oder die Rechenoperation des Zählens ist an sich verkehrt.

2. Der Code ist an sich richtig aber nicht an der richtigen Stelle angeordnet.

Schauen wir uns die letzten Zeilen des Codes genau an:

end
end
end
iSound = iSound + 1

Die letzte Zeile, in der der Zähler „iSound“ hochgezählt wird, scheint in Ordnung zu sein. Die Variable ist die richtige und dir Rechnung ist auch OK. Die Anordnung dieser Zeile ist aber auffällig. Sie steht hinter dem letzten „end“ in diesem Programm, also außerhalb jeder Schleife. Das ist übrigens auch an der Einrückung zu erkennen.

Damit ist es kein Wunder, dass das Hochzählen nicht funktioniert. Um den Fehler zu korrigieren, muss die letzte Zeile vor das letzte „end“ geschoben werden.

 

error_4

 

################################
# Lists and Loops II with error
# Hans Gruendel
# 10.4.2016
################################

sound = [:piano, :fm, :pulse, :prophet]

bar1_4 = [60, 64, 67, 72, 76, 67, 72, 76]

iSound = 0
4.times do
use_synth sound[iSound]
2.times do
iterator = 0
8.times do
play bar1_4[iterator]
sleep 0.25
iterator = iterator +1
end
end
end
iSound = iSound + 1
Code 21. Code mit einem logischen Fehler.

 

error_2

 

error_3