###### tags: `Python勉強会`
# Python勉強会 第2回 解説
:::info
**<第2回Web会議日程>**
2023年12月20日(水) 19:00から
**<第2回の自習範囲>**
**【Pythonチュートリアル】**
https://docs.python.org/ja/3/tutorial/index.html
4. その他の制御フローツール
4.1. if 文
4.2. for 文
4.3. range() 関数
4.4. break 文と continue 文とループの else 節
4.5. pass 文
4.6. match Statements
4.7. 関数を定義する
4.8. 関数定義についてもう少し
4.9. 間奏曲: コーディングスタイル
**【スッキリわかるPython入門】**
第3章 条件分岐
第4章 繰り返し
第5章 関数
:::
***
## 課題①
### 以下のコードの実行結果として正しいものはA~Dのどれでしょう?
```
for i in range(0,10,3):
print(i,end=",")
```
**A** 1 , 4 , 7 , 10
**B** 0 , 3 , 6 , 9
**C** 1 , 4 , 7
**D** 3 , 6 , 9
:::warning
**<range関数>** ※テキスト174p
range(開始値 , 終了値 [ , 増加量 ] )
開始値から増加量を足していき、終了値を超えない範囲までの、連続した数値を要素として持つオブジェクトを作成
**<for文>** ※テキスト171~176p
for 変数 in オブジェクト :
実行する処理
オブジェクトから順に要素を取り出し、変数に格納し、オブジェクトの個数・回数分処理を繰り返す
:::
```
range(0,10,3)
```
0から3ずつ足していき、 10を超えない連続した数値を要素として持つオブジェクトを作成
結果を **list(range(0,10,3))** で確認すると、**[0, 3, 6, 9]** となる
```
for i in range(0,10,3):
print(i,end=",")
```
1つ目の要素「0」を「i」に格納し、**print(i,end=",")** を実行すると、**0,** となる
これをrange(0,10,3)の個数分繰り返す
***
## 課題① 解答
:::spoiler 解答
<br>
**B** 0 , 3 , 6 , 9
:::
***
## 課題②
### 以下実行結果を得たい場合、コードの【 】に入る適切なものはどれでしょう?
### 1行目と同じ数の空白でインデントされているものとする
[実行結果]
Apple
Orange
Grape
ループ処理が終了しました!
[コード]
```
for i in ['Apple','Orange','Grape']:
print(i)
【 】
print("ループ処理が終了しました!")
```
**A** pass
**B** break
**C** continue
**D** else:
:::warning
**<pass>** ※テキスト146p
何の処理もしない。文法上なにかを書く必要があるが何も実行することがないときに使う。
**<break>** ※テキスト181~182p
繰り替えし処理を強制終了する。
**<continue>** ※テキスト181~182p
現在の回の繰り替えし処理のスキップし、次の回の処理に移る。
**<else>**
ループ処理を正常に終了した時に実行する処理
<br>

[参考:Pythonのfor文のelseの使い方](https://www.headboost.jp/python-for-else/)
:::
[実行結果]を確認すると、3つの要素をprintするループ処理終了後に、
"ループ処理が終了しました!"を表示させている
4つの選択肢のうち、ループ処理終了時の処理を記述できるのは、**else:** のみ
***
## 課題② 解答
:::spoiler 解答
**D** else:
:::
***
## 課題③
### 以下のコードの実行結果として正しいものはA~Dのどれでしょう?
```
def culc(a, b, list1=[], list2=[]):
list1.append(a ** 2)
list2.append(b ** 3)
return list1, list2
culc(1, 2)
culc(2, 3)
print(culc(3, 4))
```
**A** ([ 1 , 4 , 9 ] , [ 8 , 27 , 64 ])
**B** ([ 9 ] , [ 64 ])
**C** ([ 1 , 8 ] , [ 4 , 27 ], [ 9 , 64 ])
**D** ([ 9 , 64 ])
:::warning
**<デフォルト引数>** ※テキスト223p
* 関数定義時の引数に、デフォルト値を設定可能
* 関数呼び出し時に、指定がなかった場合、デフォルト値を利用して、関数を実行する **≒ 関数呼び出し時の引数指定を省略可能**
* デフォルト値は**関数定義時の1度だけしか評価されない**ため、リストや辞書のような変更可能なオブジェクトの時には、注意が必要
:::
```
def culc(a, b, list1=[], list2=[]):
list1.append(a ** 2)
list2.append(b ** 3)
return list1, list2
```
**関数「culc」の処理**
aとbの値を2乗してそれぞれ、list1、list2に追加して返す
list1、list2は、空のリストをデフォルト引数として、定義しているが、関数定義時にしか評価されない
そのため、list1、list2の値は、前回の実行結果を引き継ぐ
```
culc(1, 2)
```
([1], [8])
```
culc(2, 3)
```
([1, 4], [8, 27])
```
culc(3, 4)
```
([1, 4, 9], [8, 27, 64])
***
## 課題③ 解答
:::spoiler 解答
**A** (\[ 1 , 4 , 9 \] , \[ 8 , 27 , 64 \])
:::
***
## 課題④
### 以下の関数を呼び出す際に、引数の指定として正しくないものはどれでしょう?
```
def location(city, prefecture='Tokyo', country='Japan'):
print("I live in", country, ".")
print("My company is located in",city,",",prefecture,".")
```
**A** `location('Toshimaku')`
**B** `location('Toshimaku',prefecture='Tokyo','Japan')`
**C** `location('Urawa','Chiba','Japan')`
**D** `location('Yokohana',country='Japan',prefecture='Kanagawa')`
:::warning
**<位置引数>** ※テキスト208~210p
関数定義時に複数の引数を指定した場合、関数呼び出し時にも、**順番通り**に引数を記述する方法
**<キーワード引数>** ※テキスト225~226p
関数呼び出し時にどの引数にどの値を渡すのかを **引数名=値** の形式で引数を記述する方法
引数の順序に関係なく指定することができる
★両方を混ぜて関数を呼び出すことができますが、位置引数を先に書かないといけない
:::
```
def location(city, prefecture='Tokyo', country='Japan'):
print("I live in", country, ".")
print("My company is located in",city,",",prefecture,".")
```
#### 関数「location」の引数
cityはデフォルト引数なしのため、関数呼び出し時に必須
prefecture、countryはデフォルト引数が指定されているため、関数呼び出し時に省略可能
#### **A** `location('Toshimaku')`
cityを位置引数で指定
prefecture、countryは省略可能なので、実行可能
#### **B** `location('Toshimaku',prefecture='Tokyo','Japan')`
city、countryを位置引数で、prefectureをキーワード引数で指定
countryの位置引数が、prefectureのキーワード引数より後に指定されているため、エラーとなる
#### **C** `location('Urawa','Chiba','Japan')`
city、prefecture、countryを位置引数で指定、実行可能
#### **D** `location('Yokohana',country='Japan',prefecture='Kanagawa')`
city位置引数で、country、prefectureををキーワード引数で指定
キーワード引数の場合、順序に関係なく指定することができるため、実行可能
***
## 課題④ 解答
:::spoiler 解答
<br>
**B** location('Toshimaku',prefecture='Tokyo','Japan')
:::
***
## 4.6. `match` Statements について
### 基本構文
```
match 調べたいオブジェクト:
case パターン1:
処理1
case パターン2:
処理2
case _:
パターン1, 2以外の場合の処理
```
### サンプルコード
```
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case 401 | 403 | 404:
return "Not allowed"
case _:
return "Something's wrong with the Internet"
```
「status」を引数として、引数によって戻り値が変わるhttp_error関数を定義
```
http_error(400)
```
400を引数としてhttp_error関数を実行すると、以下が返ります
```
'Bad request'
```
### リストのパターンマッチ
```
def vaccine(record) :
match record:
case [name, date1]:
print(f"{name}さんは{date1}に1回目接種、2回目は未接種です")
case [name, date1, date2]:
print(f"{name}さんは{date1}に1回目接種、{date2}に2回目接種しました")
case _: # ワイルドカード
print("不正なデータです")
```
「record」には、名前、1回目接種日、2回目接種日と続くリスト型変数が入ると想定して、「record」を引数とするvaccine関数を定義
```
shioya = ['shioya','2021/3/5']
vaccine(shioya)
```
引数に 名前、1回目接種日 のみ定義されていたため
1つ目のケースにあてはまるパターンの結果が返る
```
ozaki = ['ozaki','2022/1/1','2022/2/1']
vaccine(ozaki)
```
引数に 名前、1回目接種日、2回目接種日 と定義されていたため
2つ目のケースにあてはまるパターンの結果が返る
```
sawahata = ['sawahata','2021/2/1','2021/4/1','2022/2/1']
vaccine(sawahata)
```
引数に 名前、1回目接種日、2回目接種日、2回目接種日 と定義されていたため
あてはまるパターンがなく、"不正なデータです"が返る