2つ以上の関数で変数を定義する時はその都度変数の定義が必要じゃなかったみたい (2021年3月11日追記)

##0. この記事を読むにあたっての注意!(2021年3月11日追記)
　この記事は2021年3月10日に公開した「2つ以上の関数で変数を定義する時はその都度変数の定義が必要です。」の加筆修正版です。なぜ公開1日で加筆修正に迫られたかといえば、**「2つ以上の関数で変数を定義する時はその都度変数の定義が必要です」**は間違えだったからです。正しくは**「必要じゃない」**です。
　この記事を公開して1日で239viewsを達成して多くの方に読んでいただいて嬉しい反面、間違えたことを記事にしてしまったことを悔やんでいます。この記事を消去することも考えたのですが、逆に自分のような間違えをする人がいるのではないかと思い、加筆修正を行いました。最後に私のような初心者の記事を読んで訂正までしていただいた方、本当にありがとうございます。


##1. はじめに
　Pythonに限らずどのプログラミング言語でも勉強を進めると必ず関数が出てくると思います。今回は関数に関して自分が詰まったエラーを紹介したいと思います(注1)。まずは以下に記載したエラーが発生したコードを読んでどのように直せば良いかを考えてください。

実行環境：Python3.6, Pycharm2020.3

問題：以下のコードには1つエラーがあります。ターミナルに表示されたエラーを参考にしてコードを直してください。

```python:question.py
def write_a_review():
    dict = {}
    dict["prefecture"] = input("都道府県名を入力してください＞")
    dict["school"] = input("学校名を入力してください＞")
    dict["review"] = input("その学校の感想を入力してください＞")
    line = '\n---------------------------'

    print(f'{line}\nあなたが入力した都道府県名は「{dict["prefecture"]}」です。')
    print(f'あなたが入力した学校名は「{dict["school"]}」です。')
    print(f'あなたが入力した感想は\n「{dict["review"]}」\nです。\n{line}')

    list.append(dict)


def read_a_review():
    input_index = int(input('見たいレビューの番号を入力してください＞'))
    dict = list[input_index]
    print(f'{line}\n都道府県名： {dict["prefecture"]}')
    print(f'学校名： {dict["school"]}')
    print(f'感想：{dict["review"]}\n{line}')


list = []

while True:
    print('[0]レビューを書く')
    print('[1]レビューを読む')
    print('[2]アプリを終了する')
    user_input = int(input('行いたい動作の数字を入力してください＞'))

    if user_input == 0:
        write_a_review()
    elif user_input == 1:
        read_a_review()
    elif user_input == 2:
        exit()
    else:
        print("正しい数字を入力してください")

# ターミナル
" NameError: name 'line' is not defined
```

　どうでしたか？エラーを取り除くことができましたか？そろそろ「焦らさずに早く正解を発表しろよ」という声が聞こえてきそうなので正解発表へと移りましょう。

##2. 正解

```python:answer1.py
def write_a_review():
    dict = {}
    dict["prefecture"] = input("都道府県名を入力してください＞")
    dict["school"] = input("学校名を入力してください＞")
    dict["review"] = input("その学校の感想を入力してください＞")
    line = '\n---------------------------'

    print(f'{line}\nあなたが入力した都道府県名は「{dict["prefecture"]}」です。')
    print(f'あなたが入力した学校名は「{dict["school"]}」です。')
    print(f'あなたが入力した感想は\n「{dict["review"]}」\nです。\n{line}')

    list.append(dict)


def read_a_review():
    input_index = int(input('見たいレビューの番号を入力してください＞'))
    dict = list[input_index]
    line = '\n---------------------------'  # この1文を追加するのが正解！
    print(f'{line}\n都道府県名： {dict["prefecture"]}')
    print(f'学校名： {dict["school"]}')
    print(f'感想：{dict["review"]}\n{line}')


list = []

while True:
    print('[0]レビューを書く')
    print('[1]レビューを読む')
    print('[2]アプリを終了する')
    user_input = int(input('行いたい動作の数字を入力してください＞'))

    if user_input == 0:
        write_a_review()
    elif user_input == 1:
        read_a_review()
    elif user_input == 2:
        exit()
    else:
        print("正しい数字を入力してください")
```

　正解は2つ目の関数(read_a_review())に変数「line」の定義を追加することでした。今回は「line」の定義を1つ目の関数(write_a_review())と一緒にしましたが、「line = '\n' + '-' * 20」としても大丈夫です。要は変数「line」の定義を使いできていれば正解です。

(2021年3月11日追記)
　@nkay様から別解を教えていただきました。自分の書いたコードよりも可読性が高く変数「line」の定義を1回しかしなくて良いのでこちらの方が良いと思います。要するに変数「line」の定義を関数の定義外に書くということです。(詳しい解説はぜひ@nkay様のコメントを読んでいただけるとありがいです。変に自分が解説するよりもあるかに分かりやすく書かれています。)


```python:answer2.py
def write_a_review():
    dict = {}
    dict["prefecture"] = input("都道府県名を入力してください＞")
    dict["school"] = input("学校名を入力してください＞")
    dict["review"] = input("その学校の感想を入力してください＞")
    # ここにあった変数「line」の定義を削除

    print(f'{line}\nあなたが入力した都道府県名は「{dict["prefecture"]}」です。')
    print(f'あなたが入力した学校名は「{dict["school"]}」です。')
    print(f'あなたが入力した感想は\n「{dict["review"]}」\nです。\n{line}')

    list.append(dict)


def read_a_review():
    input_index = int(input('見たいレビューの番号を入力してください＞'))
    dict = list[input_index]

    print(f'{line}\n都道府県名： {dict["prefecture"]}')
    print(f'学校名： {dict["school"]}')
    print(f'感想：{dict["review"]}\n{line}')

line = '\n---------------------------'  # この1文を追加するのが正解！

list = []

while True:
    print('[0]レビューを書く')
    print('[1]レビューを読む')
    print('[2]アプリを終了する')
    user_input = int(input('行いたい動作の数字を入力してください＞'))

    if user_input == 0:
        write_a_review()
    elif user_input == 1:
        read_a_review()
    elif user_input == 2:
        exit()
    else:
        print("正しい数字を入力してください")
```

　


##3. 解説(2021年3月11日、誤った説明のため削除)


##4. まとめ(2021年3月11日　修正)
　今回の教訓は2つあります。1つ目はエラー対処の方法は複数あるということです。そして2つ目は「2つ以上の関数で変数を定義する時はその都度変数の定義が必要じゃなかったみたい」ということです。誤った記事を公開してしまったことは反省しております。これからは誤った説明をしないようさらに学習を進めてまいります。


###注一覧
(注1)自分が詰まったのは某テキストの問題を問いていたときなのですが、そのテキストの問題をそのまま無断転載すると著作権法に抵触してしまいます。そのため本記事で使用したコードは某テキストで間違えた問題を筆者が再現したコードです。