デバッグとは何ぞや?
ども。ねっこと愉快な仲間たち、うんたんです。
今回は、デバッグとは何か、についてプログラミング超初心者の方でも分かるように説明したいと思いますので、よろしくお願いします。
デバッグはプログラミングでは必要不可欠な過程です。デバッグとは、ざっくりいうと、バグが起きた時のプログラムを修正することです。
この記事では、具体的にどのようにデバッグをするのかについて解説していきたいと思います。
1.デバッグの難しさ
バグを直すのに最も重要なことは、バグの原因を見つけ出すことです。当たり前のことですが、プログラミングでは、これは難しいことなんです。
1-1.プログラムには処理がたくさん
なぜなら、プログラムは、いくつもの処理が積み重なっているからです。
普通、プログラムを実行したときに出力されるものは、結果もしくはエラーコード(エラーの種類を示したもの)だけです。エラーコードが出る場合、結果を出力してくれません(途中で実行不可能になるため)。これだけの情報だと、原因となるのは「処理1」なのか「処理2」、「処理3」なのか分かりにくいです。
普通のプログラムでは、このような「処理」が無数にあるので、一つ一つチェックするのは途方に暮れる作業です。
1-2.条件分岐でさらに複雑に
さらに、プログラムは条件分岐をして処理を進めていきます。
バグが起きた時、どちらに条件分岐していたのかも分かりにくいので、原因を突き止めるのはさらに複雑になります。
2.デバッグの基本
では、どこにバグの原因があるのかを突き止めるには、どうすればいいのでしょうか?
2-1.プログラムの途中の状態を知ろう
一つ重要なのは、プログラムの途中での状態を知ることです。
「状態を知る」とは、すなわち、処理で扱われるデータ(変数)を知るということです。プログラムの中のそれぞれの処理で、このようなデータ(変数)は変化していきます。その変化が正常かどうか見ていくわけですね。
多くのプログラミング言語では、プログラムの途中でも、データを出力することができます。出力されたデータは、コンソールで確認することができます。
この画像のように、それぞれの処理の後に、扱っているデータ(変数)を出力すると、「処理2」の後に異常なデータが出力されていることが分かります。このことから、「処理2」がバグの原因であることが分かりますね。
2-2.実行したプログラムの「足跡」を見る
1-2では、条件分岐のあるプログラムでは、どこに分岐しているのかが分かりにくいので、バグが見つかりにくいと書きました。しかし、先ほどのようにプログラムの途中で細かく出力していけば、プログラムの「道筋」も明らかになります。
このように、条件分岐をした直後である文を出力します。出力された文を見れば、どちらに分岐したのか、つまり「道筋」が明らかになるのです。
このように、足跡を可視化してプログラムの道筋を確認するのはデバッグの基本となります。
3.デバッグの例
では、ここで実際にプログラムのデバッグの例を示します。
今回は、三角形の3つの辺の長さを入力として、もし三角形として成立するなら三角形の面積を出力し、成立しないなら3つの和を出力するプログラムを作りました。言語はpythonです。
import math
a = 3
b = 4
c = 5
if a < b + c and b < c + a and c < a + b:
s = (a + b + c) / 2
S = math.sqrt((s - a) * (s - b) * (s - c))
print(S)
else:
s = a + b + c
print(s)
a, b, cは辺の長さです。ifから始まる行で、三角形の条件で分岐しています。また、面積の計算はヘロンの公式を用いています。sqrt()というのは()内の平方根を計算する関数です。
辺の長さが例のような場合、面積は6になる(有名な直角三角形)ので、結果は6になるはずです。
結果を見てみましょう。
2.449489742783178
おかしいですね。バグが発生しました。
デバッグしましょう!
まず、最初の条件分岐でどちらに分岐したのか確かめてみます。条件分岐の後に文を出力するように書きました。
import math
a = 3
b = 4
c = 5
if a < b + c and b < c + a and c < a + b:
print("三角形です") # 追加
s = (a + b + c) / 2
S = math.sqrt((s - a) * (s - b) * (s - c))
print(S)
else:
print("三角形ではありません") # 追加
s = a + b + c
print(s)
結果を見てみましょう
三角形です
2.449489742783178
どうやら面積を求める処理に分岐したようです。
では、処理の途中のデータである、sの値を出力してみましょう。sを計算した後に出力の処理を書きました。
import math
a = 3
b = 4
c = 5
if a < b + c and b < c + a and c < a + b:
s = (a + b + c) / 2
print(s) # 追加
S = math.sqrt((s - a) * (s - b) * (s - c))
print(S)
else:
s = a + b + c
print(s)
結果を見てみましょう。
6.0
2.449489742783178
sの値は6のようです。これも正しい値ですね。
このことから、バグの原因なのは、Sを計算する処理だということがわかりました。
よく見てみると、平方根の中のsが足りないですね。
修正します。
import math
a = 3
b = 4
c = 5
if a < b + c and b < c + a and c < a + b:
s = (a + b + c) / 2
S = math.sqrt(s * (s - a) * (s - b) * (s - c)) # 修正後
print(S)
else:
s = a + b + c
print(s)
結果を見てみましょう。
6.0
正しい結果が出ました。デバッグ成功です!
4.まとめ
今回解説したのは、基礎的なデバッグの仕方です。しかし、いろんな箇所に出力する処理を書くのはたいへんですよね。
実は、一部のエディタでは、もっと楽にデバッグができる機能があるんです。
別の記事で書こうと思いますので、よかったらそちらも読んでください!
(特に学生さんが)初心者からプログラミングでアルバイト出来るように支援する新しい形態のサービスの運営に使わせていただきます!(あとちょっぴり学費) よろしければサポート頂けるとめちゃ嬉しいです!