はじめに
Day3では、calc.py を calculator.py/main.py に分割する作業の途中で、day3 フォルダで起動していたにもかかわらず親ディレクトリ全体を読まれてしまうという出来事がありました。原因はClaude Codeが親ディレクトリの CLAUDE.md まで自動的に読み込む仕様だったためで、ルートと各Dayフォルダに CLAUDE.md を分割することで対応しました。
Day4の今日は、エラー修正・デバッグをClaude Codeにやらせてみます。
1. 今日やったこと
Day3で分割した calculator.py/main.py を発展させて、今日は2種類のバグを仕込み、それぞれ違うアプローチでデバッグを依頼しました。
-
calculator.pyにaverage()関数を追加(空リストでZeroDivisionErrorになるバグ入り) - スタックトレースをそのまま貼ってデバッグを依頼
- Plan Modeでの確認質問に回答し、修正を適用
-
calculator.pyにdiscount_price()関数を追加(符号ミスで計算結果が逆になるバグ入り、エラーは出ない) - 期待する動作と実際の動作の違いを説明してデバッグを依頼
- 修正を適用し、動作確認
# day4フォルダに移動してClaude Codeを起動
cd D:\AI\work\day4
claude
:: コマンドプロンプトの場合
cd D:\AI\work\day4
claude
スタックトレースを貼るデバッグ
average() を実行してエラーを再現し、スタックトレースをそのまま貼りました。
Traceback (most recent call last):
File "D:\AI\work\day4\main.py", line 9, in <module>
print(average([]))
File "D:\AI\work\day4\calculator.py", line 23, in average
return total / len(numbers)
ZeroDivisionError: division by zero
「以下のエラーが出ました。原因を調査して直してください。」という一言に続けて、上記のスタックトレースをそのまま貼りました。
Plan Modeで、いきなり修正案を出すのではなく「空リストの場合の挙動をどうするか」を選択肢付きで質問されました。しかもその選択肢は、calc() 関数が採用している「エラーメッセージ文字列を返す」スタイルを踏まえたものになっていました。
calc() と同じ思想で揃えたかったので、「1. エラーメッセージ文字列を返す(推奨)」を選びました。提示された計画は、calc() の0除算ガードと同じパターン(先頭でチェックし、エラー文字列を早期returnする)に統一する内容でした。検証方法にも「average([10, 20, 30]) のような通常ケースでも正しく平均値が返ることを確認する」という、修正が他に影響していないかのチェックまで含まれていました。
差分を見る練習も兼ねて「2. Yes, manually approve edits」で1つずつ確認しました。
動作確認のコマンド実行時にも承認が求められ、実行結果が一度文字化けした際は、指示していないのに Claude自身が判断して PYTHONIOENCODING=utf-8 付きで再実行してくれました。
エラーが出ないバグを説明するデバッグ
続けて、スタックトレースが出ないタイプのバグも試しました。discount_price() という関数を仕込みます。本来はprice - 割引額のはずが、符号を間違えてprice + 割引額になっているというバグです。期待する動作と実際の動作の違いを文章で説明しました。
discount_price(1000, 10)を実行すると1100が返ってきますが、
本来は「1000円の10%引き」なので900が返ってきてほしいです。
まず原因を特定してから、修正方針を教えてください
スタックトレースという手がかりがない状態でも、price * percent / 100 の計算自体は正しく、それを price に加算してしまっている箇所(本来は減算すべき箇所)を正確に特定してくれました。
修正は + を - に変えるだけでしたが、既存コメントに「符号を間違えている」という原因がそのまま書かれていたため、修正後は「このコメントは不要になり削除するのが妥当」という指摘も添えられていました。
検証は、main.py 全体ではなく python -c "from calculator import discount_price; print(discount_price(1000, 10))" と該当関数だけを直接呼び出す形で、しかも今度は最初から PYTHONIOENCODING=utf-8 を付けたコマンドになっていました。
最後に main.py 全体を通しで再実行し、両方の修正がそのまま反映されており、他の行に影響が出ていないことも確認できました。
2. つまずいたポイント
今日は大きなつまずきはありませんでした。2つのバグとも、Claude Codeとのやり取りだけで原因特定から修正・検証までスムーズに完了しています。
3. どう解決したか
つまずきらしいつまずきがなかった分、今日は「どんな聞き方をすると解決に近づくか」の違いが際立った回でした。スタックトレースがあるバグはそれをそのまま貼るだけ、スタックトレースがないバグは期待する動作と実際の動作の差を説明するだけで、どちらもClaude Codeが原因を正確に特定してくれました。詳しい流れは上の「今日やったこと」の通りです。
4. 今日の学び
- スタックトレース付きのエラーは、貼るだけでClaudeが該当ファイル・行を特定してくれます。ただし挙動の選択肢が複数あるとき(今回なら「空リストのときどう振る舞うか」)は、Plan Modeが一問一答で確認してくれるので、既存コードのスタイル(
calc()の書き方)に揃えるかどうかも含めて相談できました。 - スタックトレースが出ない「実行はできるが結果が間違っている」バグは、期待する動作と実際の動作の差を文章で説明するだけで、原因を正確に特定してくれました。エラーメッセージの有無に関わらず、同じように頼れる印象です。
- バグの原因を説明するコメントが残っていると、修正後にそのコメント自体が古い情報になって紛らわしくなります。今回はコメントごと削除する提案まで自動でしてくれましたが、自分で直すときも意識しておきたいポイントです。
- Windowsコンソールの文字化け問題(Day2・Day3でも発生)に、今回はClaudeが指示なしで対策込みのコマンドを組み立てるようになっていました。同じセッション内で繰り返し遭遇した問題を踏まえて、先回りして対応してくれた形です。
- 検証は「バグが直ったか」だけでなく「他のケースが壊れていないか」もセットで確認する、という進め方が今回も一貫していました。修正のたびに全体を再実行するだけでなく、該当関数だけを直接呼び出して手早く確認する方法も使い分けられていました。
5. 次回への疑問・やりたいこと
- Day5はいよいよ最終回です。実務タスクへの投入や、通常のClaudeチャットとの使い分けを整理する予定です。
- 今日は1つの関数に閉じたバグでしたが、複数ファイルにまたがるバグ(Day3で分割した
calculator.pyとmain.pyの連携部分で起きるような不具合)を調査させると、どこまで的確に追ってくれるのかも気になっています。











