Open4

わざとエラーを起こせるなら、それはもう十分理解しているだろう的な会

mohiramohira

README

発想とか気持ちとか気分

  • エラーをわざと起こせたら、十分に理解しているだろう
    • デバッグする力が重要みたいな話はよく挙がるし賛成だけど、デバッグのためにはバグっているコードの存在が前提
    • エラーをわざと起こすようなトレーニングをする教材は少ない
  • "きれいな"サンプルコードも必要だけど、バグったサンプルコードも必要だと思う。世の中には。
  • 「○○すると○○エラーが起きます」って説明は多いけど、そのサンプルがないので、自力で深めにくい
    • とはいえ、用意するのが大変なのもわかるし、ドキュメントにそればっか書いてあっても読みくくなるのはわかる
  • 「プログラミングで必要な英語」ってのは、エラーメッセージに登場する単語と、エラーメッセージ的な文法の理解だと思う。だから、それを補強する教材があればいいはず。
    • Pythonを題材にするけど、たぶん、言語に依存は少なめな話。
  • 「エラーメッセージを読め!」って言われるし、言うし、聞くけど、その題材がないことが多いし、人によってエラーが違うので面倒だよなあと思っていた。「読め」というのなら、何をどのようにまでがセットかな〜と。
  • エラーメッセージのパターンは実は多くないので、基本のところだけ丁寧に押さえれば多分どうとでもなる
    • あとは、その技術に対する詳しさとかだと思う

これが理解できれば初心者卒業だろ! 的なError 11選

  • KeyboardInterrupt

  • AttributeError

  • ImportError

  • ModuleNotFoundError

  • IndexError

  • KeyError

  • NameError

  • FileNotFoundError

  • SyntaxError

  • TypeError

  • ValueError

  • MEMO

    • 構文エラーと実行時エラーの区別がつくのも大事かも
    • 他のErrorはあとでいいかも。

「理解している」を標的行動に言い換える

次のような行動を取れたらパーフェクトだと思う。

  • 単一のエラーのみを含む10行未満のコードをデバッグできる
  • エラーメッセージ(TraceBack含まず)から、原因を推測し、言語化できる
  • Errorを再現するコードを実装できる
  • 他にもあるかな?

具体的な問題の例

例1: 単一のエラーのみを含む10行未満のコードをデバッグできる

たかしくんは、3 + 4 の答えを計算したいです。Pythonコードを書いてみましたがエラーでうまく動きません。

x = 3
y = '4'

answer = x + y

print(answer)
Traceback (most recent call last):
  File "sample.py", line 5, in <module>
    answer = x + y
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Q1. エラーメッセージの意味を解釈せよ

  • TypeErrorが起きている。よって、データ型に関するエラーだろう
  • +という中置演算子を intstr に対して適用しているが、それはサポートされていない

Q2. 目的を達成するようにコードを修正せよ

x = 3
# y = '4'
y = 4

answer = x + y

print(answer)

例2: エラーメッセージ(TraceBack含まず)から、原因を推測し、言語化できる

Q1. NameError: name 'username' is not defined

  • 未定義の変数の呼び出し
  • 未定義の関数の呼び出し <- こっちは気づかない人多そう

Q2. ModuleNotFoundError: No module named 'john'

  • john が installされていない
  • john が installされているが、設定がおかしい

例3: Errorを再現するコードを実装できる → TypeError編

次のようなエラーメッセージを出力するようなコードを書け

Q1. TypeError: unsupported operand type(s) for +: 'int' and 'str'

>>> 3 + '4'

Q2. TypeError: can only concatenate str (not "int") to str

>>> '3' + 4
mohiramohira

UnboundLocalError¶

関数やメソッド内のローカルな変数に対して参照を行ったが、その変数には値が代入されていなかった場合に送出されます。
NameError のサブクラスです。

example01

import os


def foo():
    bar = os.environ[bar]


# UnboundLocalError: local variable 'bar' referenced before assignment
foo()
mohiramohira
mohiramohira

OSError: [Errno 24] Too many open files: 'foo.txt'

import os
from pathlib import Path


def main():
    Path('foo.txt').touch()

    # OSError: [Errno 24] Too many open files: 'foo.txt'
    while True:
        os.open('foo.txt', os.O_RDONLY)


if __name__ == '__main__':
    main()