この記事では、プログラムのバグを発見し修正するための強力なツールであるデバッガ
の基本的な使い方について解説します。print
文を多用するデバッグ方法とは異なり、デバッガはプログラムを一行ずつ実行しながら、その時々の変数の状態を監視することができます。
デバッガの基本操作
ほとんどの統合開発環境(IDE)やテキストエディタに付属するデバッガには、プログラムの実行を制御するための共通の機能があります。
Continue
(Go) プログラムの実行を再開し、次にブレークポイントが設定された行か、プログラムの終端まで実行を続けます。
Step Into
(Step) 現在の一行を実行します。もしその行が関数呼び出しである場合、デバッガは関数の中に入り、その関数の最初の行で停止します。
Step Over
(Over) 現在の一行を実行します。もしその行が関数呼び出しであっても、関数の中には入らず、関数全体の処理を実行した上で、次の行で停止します。
Step Out
(Out) 現在実行中の関数を最後まで実行し、その関数から抜け出した直後の行で停止します。
Stop
(Quit) デバッグプロセスを完全に終了します。
デバッガによる問題の発見
デバッガがどのようにバグ発見に役立つか、簡単な加算プログラムを例に見てみましょう。このプログラムには、意図的にバグが含まれています。
# 3つの数値を合計するつもりのプログラム
print("1つ目の数値を入力してください:")
val1 = input()
print("2つ目の数値を入力してください:")
val2 = input()
print("3つ目の数値を入力してください:")
val3 = input()
total = val1 + val2 + val3
print(f"合計は: {total}")
このプログラムで10
、20
、30
と入力すると、期待する60
ではなく102030
と表示されてしまいます。
デバッガを使ってこのプログラムを一行ずつStep Over
で実行していくと、total = val1 + val2 + val3
の行に到達する直前の変数の中身を確認できます。すると、val1
が数値の10
ではなく、文字列の'10'
であることがわかります。input()
関数は常に入力を文字列として返すため、+
演算子が数値の加算ではなく、文字列の連結として機能してしまったことが、バグの直接的な原因だと特定できます。
ブレークポイント
プログラムが長い場合、最初から一行ずつ実行するのは非効率です。ブレークポイントは、プログラム内の特定の行に設定する「一時停止の目印」です。
デバッগেরContinue
(Go)機能を使うと、プログラムはブレークポイントまで一気に実行され、そこで停止します。これにより、問題が起きていると疑われる箇所の直前まで、すぐにジャンプすることができます。
import random
# 1000回のうち、表が何回出るかを数える
coin_flips = 0
for i in range(1, 1001):
if random.randint(0, 1) == 0: # 0を裏、1を表とする
coin_flips += 1
# この行にブレークポイントを設定
if i == 500:
# プログラムは500回目のループでここで停止する
print("ループが半分完了しました。")
print(f"最終的に、表は{coin_flips}回出ました。")
例えば、500回目のループでcoin_flips
の値が期待通りかを確認したい場合、if i == 500:
の行にブレークポイントを設定します。そしてデバッグを開始しContinue
をクリックすれば、プログラムは499回のループを高速で実行し、500回目で停止します。そこから、変数の状態を詳しく調査することができます。
まとめ
デバッガは、プログラムの動作を内部から詳細に観察するための不可欠なツールです。Step Over
やStep Into
によるステップ実行で処理の流れを追い、ブレークポイントで関心のある箇所に素早く移動することで、print
文だけでは見つけにくい複雑なバグも効率的に特定し、修正することができます。