[光-Hikari-のPython]07章-01 例外処理（エラーと例外）

##[Python]07章-01 エラーと例外
今までいろいろなプログラムを書いてきました。自分で記載したプログラムを実行するにはおよそ以下の手順で行います。

**【1】プログラムの作成**
例えば、割り算の計算を行うプログラムを例にとってみましょう。

プログラムの作成は、コンピュータに何かを処理させるため、Pythonなどのプログラムの文法に従って、処理のためのコード記述する作業です。これまで何度も実施してきました。

```.py
print('割り算a÷bを求めます。')
a = int(input('aの値を入力してください：'))
b = int(input('bの値を入力してください：'))

print(a / b)
```

なお、上記のコードは人間には読みやすく作られていますが、このままでは実はコンピュータ上では処理はできないのです。正確にはコンピュータ内部にある**CPU（中央処理装置）**で処理するのに、上記のコードを実行はできません。この状態のコードを**ソースコード**と言ったりします。

**【2】インタプリタ処理**
ソースコードを実行できるようにするには、**翻訳**する必要があります。翻訳するには**Pythonのインタプリタ**を指定します。インタプリタを使用することで、CPUが理解できる**マシン語**に翻訳ができます。
実は01章でインタプリタは指定しています。少し見てみましょう。Pycharmの右上にある[Edit Configurations...]をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/e04ffcc3-f765-42d9-fda5-3cfba0820732.png)


[Python interpreter]でインタプリタのある個所を指定していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/40abaf5c-e50f-215f-3a65-c5da86e55114.png)



**【3】一行ずつ実行**
インタプリタで翻訳しながらプログラム一行ずつを実行していきます。
もし、プログラムの実行中に文法ミスがあったら、構文エラーとして以下のようにエラーが表示され、インタプリタによる翻訳を中止します。。

>Traceback (most recent call last):
  File "C:/Users/＊＊＊/Desktop/python/chap07/samp07-01-01.py", line 6, in <module>
    a = inat(input('aの値を入力してください：'))
NameError: name 'inat' is not defined

もし、文法ミスがなければ、そのままプログラムを実行し処理に進みます。

以上がプログラムのコードの記載から実行までの流れです。

##例外（0による除算）
先ほど、プログラムを実行して文法エラーがなければプログラムの実行がされると記載しましたが、プログラムを無事に実行してもその時に問題が起こることもあります。

例えば先ほどのプログラムです。<font color="#00cccc">chap07</font>の中に<font color="#00cccc">samp07-01-01.py</font>というファイル名でファイルを作成し、以下のコードを書いてください。そして実行してみてください。

```samp07-01-01.py
print('割り算a÷bを求めます。')
a = int(input('aの値を入力してください：'))
b = int(input('bの値を入力してください：'))

print(a / b)
```
><font color="#090" bgcolor="black">【実行結果】</font>
割り算a÷bを求めます。
aの値を入力してください：10
bの値を入力してください：4
2.5

プログラムの内容は問題ないかと思います。
さて、今回はインタプリタによる翻訳も無事に成功し、実行はできていることは確認しました。

では、実行後に**b**の値について**0**を入力したらどうなるでしょうか？再度実行して**b**に**0**を入力してみてください。

><font color="#090" bgcolor="black">【実行結果】</font>
割り算a÷bを求めます。
aの値を入力してください：10
bの値を入力してください：<font color=red>0</font>
Traceback (most recent call last):
  File "C:/Users/＊＊＊/Desktop/python/chap07/samp07-01-01.py", line 5, in <module>
    print(a / b)
ZeroDivisionError: division by zero

何が起こったかというと、エラーの最後に**「ZeroDivisionError: division by zero」**とあり、これは「0で割ろうとしてエラーとなっています」という意味です。
実際に算数や数学の世界でも値を0で割ることはできません。

さて、この入力した**0**という値、インタプリタによる翻訳時に発生したエラーではなく、**翻訳が無事に終わった後に起きたエラー**です。
実際には、実行時に実行画面から人による**0**の入力です。こういった文法の誤りでなく実行時に発生したエラーを**例外（Exception）**と言います。
また、インタプリタによる翻訳時に発生する文法のエラーを**構文エラー**と言います。

まとめると、エラーには**構文エラー**と**例外**が存在します。
さて、例外ですが、実行時に人が実行画面から**b**の値として**0**を入力しないように気を付けても、人が入力するものですから、今回のような例外はどこかで必ず発生します。


##例外（リストの要素を超えて指定した場合の例外）
先ほど、0による除算について触れましたが、ほかにもまだあります。例えば、リストの要素の番号を指定する際に、**リストの要素数を超える要素番号を指定した際にも例外が発生**します。<font color="#00cccc">chap07</font>を新たに作成し、その中に<font color="#00cccc">samp07-01-02.py</font>というファイル名でファイルを作成し、以下のコードを書いてください。

```07-01-02.py
ls = [1, 3, 5, 7, 9]
print(ls)
i = int(input('上記のリストの要素番号を指定してください：'))

print(ls[i])
```
><font color="#090" bgcolor="black">【実行結果】</font>
[1, 3, 5, 7, 9]
上記のリストの要素番号を指定してください：<font color=red>5</font>
Traceback (most recent call last):
  File "C:/Users/＊＊＊/Desktop/python/chap07/samp07-01-02.py", line 5, in <module>
    print(ls[i])
IndexError: list index out of range

エラーメッセージの最後に**「IndexError: list index out of range」**とあります。これは、「リストの範囲を超えてインデックスを指定指定しています」といった旨のエラーメッセージです。
今回、リストの要素は**ls[0]～ls[4]**までしかないはずなのに、**ls[5]**と指定しているので、**例外**となります。今回も人の入力によって例外が起こっています。

##最後に
今回はエラーの種類として例外と構文エラーについて触れました。例外の例として、0による除算やリストの要素外の指定などを取り上げました。
このような、人的なミスによる例外はよく見られます。いくら人に対して「気を付けてください」と言っても、ミスは起きてしまいます。こういったミスを起こさないために、人にゆだねるのは危険です。

さて、この例外を避けるためのエラーに強いプログラムを作成するにはどうすればよいか、それについては次回触れたいと思います。

###[【目次リンク】へ戻る](https://qiita.com/ko0821/items/379e8bd9e6ea01089419)