プログラミングでエラーが出たときの読み方。初心者が試す5つの手順
PythonのTypeErrorを実際の値と型から直し、構文・実行時・計算ミスを見分けます。エラーの読む順、最小例、質問の作り方、境界値の練習と模範解答を解説します。
赤い文字が何行も出ると、思わず全部閉じたくなることがありますよね。でも、そこでコードを丸ごと書き直す前に、表示の中の小さな手がかりを拾ってみましょう。
エラーは「向いていない」という評価ではなく、コンピューターが処理を進められなかった場所の情報です。今回はPythonの短い例を使い、5つの手順で原因を絞ります。
コードはPython 3を想定しています。エラーメッセージや矢印の形はバージョン・実行方法で違うことがあります。
まず覚えたい3種類
| 種類 | 何が起きているか | 例 |
|---|---|---|
| 文法・構文エラー | 書き方のルールとして読めない | 閉じかっこの不足 |
| 実行時のエラー | 読めるが、その値や状況では処理できない | 数へ変換できない文字 |
| 論理的な不具合 | 動くが目的と違う | 個数を掛けずに足した |
構文はコードの並べ方のルール、実行時はプログラムが実際に動いている段階です。論理は、何をどの順で行うかという処理の筋道です。
まず「エラーが出て止まる」のか「止まらないが結果が違う」のかを分けます。両方とも直す必要はありますが、探す手がかりが違います。
手順1:最後の1〜3行を読む
次を error_practice.py へ保存して実行すると、意図的にエラーが出ます。大事なファイルは変更しない、独立した練習例です。
price = "120"
count = 3
total = price + count
print(total)
エラーの末尾には、一般的に次のような表示が出ます。
TypeError: can only concatenate str (not "int") to str
最初から全文を訳さず、3つに分けて読みます。
TypeError:データの種類、つまり型の扱いに問題があるstr:文字列を扱っているint:整数も混ざっている
concatenate は「つなげる」という意味です。この場合は「文字列へ、整数をそのままつなげられない」と読めます。
最後から読むのは、まずPythonの例外の場合
Pythonでは、実行中の問題を例外として知らせます。例外の表示は、最後に種類と説明が出る形が基本です。
ただし、すべての言語・ツールで最後が原因とは限りません。C/C++のコンパイルでは最初のエラーを直すと後ろも消える場合があり、JavaScriptのコンソールでは先頭のエラー名とその下の呼び出し元を見ます。
ツールの終了メッセージ「処理に失敗しました」だけでは原因が分からないこともあります。その場合は少し上へ戻り、具体的なファイル名やエラーを探します。
手順2:ファイル名と行番号を探す
Pythonの長い表示には、次のような箇所があります。
File ".../error_practice.py", line 3, in <module>
total = price + count
line 3 は3行目です。エディターで該当ファイルを開き、total = price + count を確認します。環境によっては問題の部分へ矢印も表示されます。
エラーに至った呼び出しの流れを示す部分をトレースバックと呼びます。関数が別の関数を呼んでいる場合、複数のファイルや行が並びます。
止まった場所と原因を作った場所は違う
今回止まったのは3行目ですが、文字列を作ったのは1行目の price = "120" です。3行目だけを見ても、どこで値が決まったか分からないんですね。
順番は次です。
- エラーが発生した行を見る
- そこで使う変数を調べる
- その値を作った行へ戻る
構文エラーでも、表示された行の少し前に原因がある場合があります。例えば前の行で ) を閉じ忘れると、後の行まで続いていると解釈されることがあります。
まず表示箇所を手がかりにし、絶対にその1行だけが原因とは決めつけないようにします。
手順3:値と型を表示する
型は、整数や文字列など、データの種類です。値を確認しながら原因を調べる作業をデバッグと呼びます。
失敗する計算の直前へ、表示を追加してみます。
price = "120"
count = 3
print("price:", repr(price), type(price))
print("count:", repr(count), type(count))
total = price + count
エラーの前に、次が表示されます。
price: '120' <class 'str'>
count: 3 <class 'int'>
type() は型を調べる機能です。repr() は値をコード寄りの表現で示す機能で、文字列の引用符や、見えにくい改行・空白を確認しやすくなります。
print(price) だけなら 120 と出るため、整数と見分けにくいですよね。型まで調べると、想像と違うことが分かります。
修正は「何をしたいか」で変わる
エラーを消すだけなら、どちらかの型へそろえればよい場合があります。ただし、正しい直し方は目的次第です。
数の120に3を足したいなら、文字列を整数へ変えます。
price = int("120")
count = 3
total = price + count
print(total)
結果は 123 です。
一方、120円の商品を3個買う合計金額なら、必要なのは掛け算です。
price = int("120")
count = 3
total = price * count
print(total)
結果は 360 です。ここが大切で、123 を出せたから買い物の計算が完成したとは限りません。エラーが消えたことと、目的を満たすことは別です。
文字として 1203 とつなげたいなら、"120" + str(3) という別の書き方になります。変数と型変換でこの違いを練習できます。
手順4:問題を小さくする
長いコードで何か所も一度に変えると、効いた修正も分からなくなります。元の作業を保存したうえで、別の練習ファイルへ、問題に関係する部分だけ取り出します。
入力・変換・計算を分ける
user_input = input("値段を入力してください: ")
print("受け取った文字:", repr(user_input))
print("型:", type(user_input))
まずはここまでです。120 を入力しても str になることを確認します。
次に整数への変換を追加します。
user_input = input("値段を入力してください: ")
price = int(user_input)
print("変換後:", price, type(price))
ここで abc を入れると ValueError になります。ValueErrorは、受け取る種類としては扱えても、その値では要求した処理ができない場合などに出る例外です。この場合は「abcという文字は整数表記ではない」が原因です。
正常な 120、小数の 120.5、空入力をそれぞれ試すと、どこまで扱えるかが見えます。今回の int() では、後の2つも整数への変換に失敗します。
最小例にすると分かること
入力を固定した int("120") が動き、実入力でだけ失敗するなら、入力内容を調べる方向へ進めます。関係ない画面処理やファイル操作を減らすと、確認する候補も減ります。
この小さく再現できるコードを最小再現例と呼びます。最小は「絶対に最短」の意味ではなく、問題が再現する範囲まで絞ったものです。
修正は「1か所変える → 同じ入力で動かす → 結果を見る」の順にします。別の入力ばかり試すと、直ったのか、たまたま起きなくなったのか区別できません。
手順5:検索やAIへ渡す情報を整える
自分で分からないときは、質問して構いません。質問のために状況をまとめると、その途中で原因に気付くこともあります。
用意するのは次の5つです。
- 言語・ツールとバージョン
- エラー名と前後の表示
- 問題を再現する短いコード
- 期待する結果と、実際の結果
- 試した修正と、その結果
例えば次のように書けます。
Python 3を使っています。
inputで「120」を受け取り、整数3を足すとTypeErrorになります。
目的は文字の連結ではなく、数として123を出すことです。
typeで確認すると、入力はstr、3はintでした。
入力をどこで変換すればよいでしょうか。
実際に質問するときは、使っている細かなバージョンとコードも添えます。検索ではエラー名と特徴的な文を使い、個人のフォルダーパスなどは省くと、近い問題を探しやすくなります。
パスワード、APIキー、アクセストークン、個人情報を貼らないでください。APIキーなどは外部サービスを利用する秘密情報の場合があり、第三者に使われるおそれがあります。ダミー値へ置き換えても同じエラーが再現するか確かめます。
AIや検索結果の修正案は、そのまま信じず差分を読みます。ファイル削除、権限緩和、セキュリティ設定の解除など、大きな操作を理由なく試さないようにしましょう。
よくある確認ポイント
| 手がかり | 確認すること |
|---|---|
SyntaxError |
記号、かっこ、引用符、周辺の行 |
NameError |
名前のつづり、大文字小文字、定義前に使っていないか |
TypeError |
値の種類と、使う演算の組み合わせ |
ValueError |
その値を変換・処理できるか |
IndexError |
配列やリストの長さと、指定位置 |
FileNotFoundError |
ファイル名と、実行時のフォルダー |
エラー名は調べる方向の手がかりであり、修正方法が1つに決まるものではありません。
また、コードが正しく見えるときこそ、「保存したか」「別の同名ファイルを実行していないか」を確認します。修正したファイルとは別の場所を実行していたら、正しい修正も反映されません。
すべての例外を握りつぶして何も表示しないようにすると、原因まで隠れてしまいます。必要な例外を扱う方法はPythonのエラーとファイル操作で学べます。
小さな練習
次は意図的なエラーのあるコードです。最後の値 30 を表示できるように直してください。
numbers = [10, 20, 30]
print(numbers[3])
模範解答
numbers = [10, 20, 30]
print(numbers[2])
出力は 30 です。
解説
Pythonのリストの位置は0から数えます。
| 位置 | 値 |
|---|---|
| 0 | 10 |
| 1 | 20 |
| 2 | 30 |
要素は3個ありますが、使える位置は0〜2です。numbers[3] は「添字3、つまり4番目の要素」を要求するので存在しません。「3番目の要素がない」のではなく、3番目はあるが、その添字は2なのです。
リストの長さが変わる前提で最後を選びたいなら numbers[-1] という書き方もあります。ただし空のリストではそれも失敗するので、要素があるかを確認する必要があります。
追加問題:止まらないが答えが違う
price = 120
count = 3
print(price + count)
目的が「120円を3個分の代金」なら、どこを直しますか。
模範解答は print(price * count) です。 出力は360になります。型は問題なくても、計算の選び方が目的と違います。期待する結果を先に用意しておくと、この種の不具合も見つけられます。
まとめ
まずはエラー名を読み、場所を探し、値と型を見ます。次に小さく再現して、1か所ずつ直します。最後に「止まらなくなったか」だけでなく「ほしかった結果か」を確認しましょう。
一度で直せなくても、候補が1つ減れば前進です。エラー表示を読むことは、そのままプログラムを読む練習になります。