###### tags: `Python勉強会` # Python勉強会 第5回 課題解説 :::info **<第5回Web会議日程>** 2024年03月21日(木) 19:00から **<第5回の自習範囲>** **【Pythonチュートリアル】**  https://docs.python.org/ja/3.9/tutorial/index.html [8. エラーと例外](https://docs.python.org/ja/3/tutorial/errors.html)  [8.1. 構文エラー](https://docs.python.org/ja/3/tutorial/errors.html#syntax-errors)  [8.2. 例外](https://docs.python.org/ja/3/tutorial/errors.html#exceptions)  [8.3. 例外を処理する](https://docs.python.org/ja/3/tutorial/errors.html#handling-exceptions)  [8.4. 例外を送出する](https://docs.python.org/ja/3/tutorial/errors.html#raising-exceptions)  [8.5. 例外の連鎖](https://docs.python.org/ja/3/tutorial/errors.html#exception-chaining)  [8.6. ユーザー定義例外](https://docs.python.org/ja/3/tutorial/errors.html#user-defined-exceptions)  [8.7. クリーンアップ動作を定義する](https://docs.python.org/ja/3/tutorial/errors.html#defining-clean-up-actions)  [8.8. 定義済みクリーンアップ処理](https://docs.python.org/ja/3/tutorial/errors.html#predefined-clean-up-actions) [9. クラス](https://docs.python.org/ja/3/tutorial/classes.html)  [9.1. 名前とオブジェクトについて](https://docs.python.org/ja/3/tutorial/classes.html#a-word-about-names-and-objects)  [9.2. Python のスコープと名前空間](https://docs.python.org/ja/3/tutorial/classes.html#python-scopes-and-namespaces)   [9.2.1. スコープと名前空間の例](https://docs.python.org/ja/3/tutorial/classes.html#scopes-and-namespaces-example)  [9.3. クラス初見](https://docs.python.org/ja/3/tutorial/classes.html#a-first-look-at-classes)   [9.3.1. クラス定義の構文](https://docs.python.org/ja/3/tutorial/classes.html#class-definition-syntax)   [9.3.2. クラスオブジェクト](https://docs.python.org/ja/3/tutorial/classes.html#class-objects)   [9.3.3. インスタンスオブジェクト](https://docs.python.org/ja/3/tutorial/classes.html#instance-objects)   [9.3.4. メソッドオブジェクト](https://docs.python.org/ja/3/tutorial/classes.html#method-objects)   [9.3.5. クラスとインスタンス変数](https://docs.python.org/ja/3/tutorial/classes.html#class-and-instance-variables)  [9.4. いろいろな注意点](https://docs.python.org/ja/3/tutorial/classes.html#random-remarks)  [9.5. 継承](https://docs.python.org/ja/3/tutorial/classes.html#inheritance)   [9.5.1. 多重継承](https://docs.python.org/ja/3/tutorial/classes.html#multiple-inheritance)  [9.6. プライベート変数](https://docs.python.org/ja/3/tutorial/classes.html#private-variables)  [9.7. 残りのはしばし](https://docs.python.org/ja/3/tutorial/classes.html#odds-and-ends)  [9.8. イテレータ (iterator)](https://docs.python.org/ja/3/tutorial/classes.html#iterators)  [9.9. ジェネレータ (generator)](https://docs.python.org/ja/3/tutorial/classes.html#generators)  [9.10. ジェネレータ式](https://docs.python.org/ja/3/tutorial/classes.html#generator-expressions) [12. 仮想環境とパッケージ](https://docs.python.org/ja/3/tutorial/venv.html)  [12.1. はじめに](https://docs.python.org/ja/3/tutorial/venv.html#introduction)  [12.2. 仮想環境の作成](https://docs.python.org/ja/3/tutorial/venv.html#creating-virtual-environments)  [12.3. pip を使ったパッケージ管理](https://docs.python.org/ja/3/tutorial/venv.html#managing-packages-with-pip) [14. 対話入力編集と履歴置換](https://docs.python.org/ja/3/tutorial/interactive.html)  [14.1. タブ補完と履歴編集](https://docs.python.org/ja/3/tutorial/interactive.html#tab-completion-and-history-editing)  [14.2. 対話的インタープリタの代替](https://docs.python.org/ja/3/tutorial/interactive.html#alternatives-to-the-interactive-interpreter) ::: *** ## 構文エラー一覧表 | エラー名 | 内容 | | -------- | -------- | | SyntaxError| 括弧()やコロン:が足りない場合などのエラー | | IndentationError | インデントが正しくない場合のエラー | ## 例外処理一覧表 | 例外名 | 用途 | | -------- | -------- | | ZeroDivisionError| 0で割り算が行われた場合のエラー | | NameError | 名前が見つからなかった場合のエラー | | IndexError | リストやタプルにおいて添字が範囲外を指定している場合に発生するエラー | | KeyError | 辞書(dict型)の値をキーを指定して取得する際に、存在しないキーを指定してしまった場合のエラー | | ValueError | 関数の引数についてのエラー | **※※もっと詳しく見たい方は以下を参照してみてください** [Python 標準ライブラリ ~組み込み例外~](https://docs.python.org/ja/3.9/library/exceptions.html) *** ## 課題① ### 次のコードを実行して「整数a:」に「5」、「整数b:」に「0」を入力した場合の正しい結果はA~Dのどれでしょうか? ```javascript= try: int_a = int(input('整数a:')) int_b = int(input('整数b:')) print(int_a ** 2) print((int_a ** 2) / int_b) except(ValueError) as v: print(type(v)) print('C') except(ZeroDivisionError) : print('D') except: print('E') else: print('F') finally: print('G') ``` **A**  25    C    F    G **B**  25    0    C    G **C**  25    D    G **D**  25    D    F    G *** ### エラーと例外 :::warning  Pythonにおいて、エラーは構文エラー(syntax error)と例外(exception)に区別される。構文として誤っているものは**構文エラー**、構文として正しくても実行中に発生するエラーは**例外**と呼ばれる。 ::: :::info Pythonで例外(実行中に検出されたエラー)をキャッチして処理するには**try**, **except**を使う。例外が発生しても途中で終了させずに処理を継続できる。さらに**else**, **finally**を使うと終了時の処理を設定可能。 【基本構造】 try: 処理 except 例外1: 例外1が発生した場合の処理 except 例外2: 例外2が発生した場合の処理 else: 例外が発生しなかった場合の処理 finally: 例外の発生有無に関わらず常に実行 ::: **課題①の解説** ``` try: ``` try文で例外処理を指定します ``` int_a = int(input('整数a:')) int_b = int(input('整数b:')) ``` input()関数を設定するとキーボード入力を求められる。 input()関数は入力されたデータを文字列とし扱うため、今回の問題では数値を扱いたいため、int()型を設定している ``` print(int_a ** 2) print((int_a ** 2) / int_b) ``` print(5 ** 2) ⇒ 25 print((5 ** 2) / 0) ⇒ 0 ``` except(ValueError) as v: print(type(v)) print('C') except(ZeroDivisionError) : print('D') except: print('E') ``` try文で例外が発生した場合に実行される ``` else: print('F') ``` except節の例外処理で当てはまらなかったら実行される ``` finally: print('G') ``` finallyは例外の発生有無に関わらず常に実行される *** ## 課題① 解答 :::spoiler 解答 <br> **C**  25    D    G ::: *** ## 課題② ### 仮想環境とパッケージに関する次の記述のうち誤っているものはA~Dのどれでしょうか? **A**  pip install でパッケージ名を指定し、そのパッケージ名の後ろに==とバージョン名を付けると、そのバージョンのパッケージをインストールできる。 **B**  pip install --upgradeとすることで、当該パッケージを最新バージョンにアップグレードすることができる。 **C**  「pip list パッケージ名」で、ある特定のパッケージの詳細情報が表示される。 **D**  pip uninstall にパッケージ名を指定すると、その仮想環境からパッケージを削除できる。削除対象となるパッケージの複数指定も可能である。 **※参考内容**:[12.3. pip を使ったパッケージ管理](https://docs.python.org/ja/3/tutorial/venv.html#managing-packages-with-pip) *** :::warning **<pip>**  Pythonの**パッケージを管理する**ためのツール ::: **A**  pip install でパッケージ名を指定し、そのパッケージ名の後ろに==とバージョン名を付けると、そのバージョンのパッケージをインストールできる。 以下はチュートリアルの抜粋となります。 :::warning [12.3. pip を使ったパッケージ管理](https://docs.python.org/ja/3/tutorial/venv.html#managing-packages-with-pip) パッケージ名を指定してそのパッケージの最新版をインストールすることができます: ``` (tutorial-env) $ python -m pip install novas Collecting novas Downloading novas-3.1.1.3.tar.gz (136kB) Installing collected packages: novas Running setup.py install for novas Successfully installed novas-3.1.1.3 ``` パッケージ名のあとに == とバージョン番号を付けることで、特定のバージョンのパッケージをインストールすることもできます: ``` (tutorial-env) $ python -m pip install requests==2.6.0 Collecting requests==2.6.0 Using cached requests-2.6.0-py2.py3-none-any.whl Installing collected packages: requests Successfully installed requests-2.6.0 ``` ::: 上記内容の記述に当てはまるため、**A**は正解 *** **B**  pip install --upgradeとすることで、当該パッケージを最新バージョンにアップグレードすることができる。 以下チュートリアルの抜粋となります。 :::warning [12.3. pip を使ったパッケージ管理](https://docs.python.org/ja/3/tutorial/venv.html#managing-packages-with-pip) 同じコマンドを再び実行した場合、pip は要求されたバージョンがインストール済みだと表示して何もしません。別のバージョン番号を指定すればそのバージョンをインストールしますし、pip install --upgrade を実行すればそのパッケージを最新版に更新します: ``` (tutorial-env) $ python -m pip install --upgrade requests Collecting requests Installing collected packages: requests Found existing installation: requests 2.6.0 Uninstalling requests-2.6.0: Successfully uninstalled requests-2.6.0 Successfully installed requests-2.7.0 ``` ::: 上記内容の記述に当てはまるため、**B**は正解 *** **D**  pip uninstall にパッケージ名を指定すると、その仮想環境からパッケージを削除できる。削除対象となるパッケージの複数指定も可能である。 以下チュートリアルの抜粋となります。 :::warning [12.3. pip を使ったパッケージ管理](https://docs.python.org/ja/3/tutorial/venv.html#managing-packages-with-pip) ``` (tutorial-env) $ python -m pip install --upgrade requests Collecting requests Installing collected packages: requests Found existing installation: requests 2.6.0 Uninstalling requests-2.6.0: Successfully uninstalled requests-2.6.0 Successfully installed requests-2.7.0 ``` pip uninstall コマンドに削除するパッケージ名を1つ以上指定します。 ::: ※「pip uninstall」についてはチュートリアルでは内容が不十分のため、以下も確認しております。 [Pythonのパッケージ管理システムpipの使い方 ~パッケージのアンインストール: pip uninstall~](https://note.nkmk.me/python-pip-usage/) 上記内容の記述に当てはまるため、**D**は正解 *** **C**  「pip list パッケージ名」で、ある特定のパッケージの詳細情報が表示される。 以下はチュートリアルの抜粋となります。 :::warning [12.3. pip を使ったパッケージ管理](https://docs.python.org/ja/3/tutorial/venv.html#managing-packages-with-pip) pip show は指定されたパッケージの情報を表示します: ``` (tutorial-env) $ pip show requests --- Metadata-Version: 2.0 Name: requests Version: 2.7.0 Summary: Python HTTP for Humans. Home-page: http://python-requests.org Author: Kenneth Reitz Author-email: me@kennethreitz.com License: Apache 2.0 Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages Requires: ``` pip list は仮想環境にインストールされた全てのパッケージを表示します: ``` (tutorial-env) $ pip list novas (3.1.1.3) numpy (1.9.2) pip (7.0.3) requests (2.7.0) setuptools (16.0) ``` ::: 上記内容より、「pip list」は**ある特定のパッケージの詳細情報が表示される**ではなく、 **全てのパッケージを表示される**ため、**C**は不正解となる。 **ある特定のパッケージの詳細情報が表示される**のは「pip show」の説明になる。 *** ## 課題② 解答 :::spoiler 解答 <br> **C**  「pip list パッケージ名」で、ある特定のパッケージの詳細情報が表示される。 ::: *** ## 課題③ ### 「<span style="color:blue">sample.py</span>」を作成し、実行したときの結果として正しいものはA~Dのどれでしょうか? [<span style="color:blue">sample.py</span>] ```javascript= class Sample: c_list = [] def add_c_list(self,data): self.c_list.append(data) print("kekka:", end=" ") sample1 = Sample() sample1.add_c_list("shioya") sample2 = Sample() sample2.add_c_list("taketo") for item_data in sample1.c_list: print(item_data, end=" ") ``` **A**  kekka: shioya taketo **B**  kekka: **C**  kekka: shioya **D**  kekka: taketo shioya *** 「<span style="color:blue">sample.py</span>」の解説 :::info ``` class Sample: ``` Sampleという名称でクラスを作成する ``` c_list = [] ``` 変数c_listに空のリスト [] を作成 ``` def add_c_list(self,data): self.c_list.append(data) ``` add_c_list関数を作成 クラス変数自信(self)のc_listの末尾に(data)を追加 ``` print("kekka:", end=" ") sample1 = Sample() sample1.add_c_list("shioya") ``` "kekka:"を出力 Sampleクラスから、sample1オブジェクトを作成 sample1オブジェクトに対してadd_c_list()関数を適用 -> 文字列”shioya″は、dataへ ``` sample2 = Sample() sample2.add_c_list("taketo") ``` Sampleクラスから、sample2オブジェクトを作成 sample2オブジェクトに対してadd_c_list()関数を適用 -> 文字列”taketo″は、dataへ -> appendなので末尾に追加される ``` for item_data in sample1.c_list: print(item_data, end=" ") ``` for文の繰り返し ::: 上記から、「kekka: shioya taketo」が表示される。 ## 課題③ 解答  :::spoiler 解答 <br> **A**  kekka: shioya taketo ::: *** ## クラス変数 :::warning クラス内でかつメソッドの外で宣言され、すべてのインスタンス間で共通した値をもつ変数 宣言時には「**変数名 = ~**」という形式を用いる ::: ## インスタンス変数 :::warning 個々のインスタンスに格納される変数 宣言時には「**self.変数名**」という形式を用いる ::: 課題③はクラス変数の問題でしたが、以下はインスタンス変数を用いた例となります。 ```javascript= class Sample: def __init__(self): self.c_list = [] def add_c_list(self,data): self.c_list.append(data) print("kekka:", end=" ") sample1 = Sample() sample1.add_c_list("shioya") sample2 = Sample() sample2.add_c_list("taketo") for item_data in sample1.c_list: print(item_data, end=" ") ``` インスタンス変数を実行すると「**shioya**」として出力されます。 *** ## 課題④ ### 以下(1)~(4)のコードを実行すると、「<span style="color:red">構文エラー</span>」「<span style="color:red">例外</span>」どちらの結果になるでしょうか? (1) ```javascript= if i == "OFFICE54": print("OFFICE54") ``` (2) ```javascript= def divide(x): return 54 / x print(divide(0)) ``` (3) ```javascript= if x==1: print("1") ``` (4) ```javascript= d = {'a': 1, 'b': 2, 'c': 3} print(d['x']) ``` **A**  ①構文エラー ②構文エラー ③例外    ④構文エラー **B**  ①例外    ②構文エラー ③例外    ④例外 **C**  ①構文エラー ②例外    ③例外    ④例外 **D**  ①例外    ②例外    ③構文エラー ④構文エラー *** :::info (1) ```javascript= if i == "OFFICE54": print("OFFICE54") ``` ::: ``` if i == "OFFICE54": ``` iの値が"OFFICE54"と等しいか確認 ``` print("OFFICE54") ``` "OFFICE54"を出力する 実行すると「インデントエラー」となり、 インデントエラーは「**構文エラー**」となる。 :::info (2) ```javascript= def divide(x): return 54 / x print(divide(0)) ``` ::: ``` def divide(x): ``` divide(x)を呼び出す ``` return 54 / x ``` 「54 / x」の結果を返す ``` print(divide(0)) ``` 実行すると「ZeroDivisionError」となり、 ZeroDivisionErrorは「**例外**」となる。 :::info (3) ```javascript= if x==1: print("1") ``` ::: ``` if x==1: ``` iの値が1と等しいか確認 ``` print("1") ``` "1"を出力する 実行すると「NameError」となり、 NameErrorは「**例外**」となる。 :::info (4) ```javascript= d = {'a': 1, 'b': 2, 'c': 3} print(d['x']) ``` ::: ``` d = {'a': 1, 'b': 2, 'c': 3} ``` dにa=1,b=2,c=3を入力する ``` print(d['x']) ``` 'x'を出力する 実行すると「キーエラー」となり、 キーエラーは「**例外**」となる。 ## 課題④ 解答 :::spoiler 解答 <br> **C**  ①構文エラー ②例外    ③例外    ④例外 ::: ***