Python 基本構文メモ

忘れそうな構文を記載します。
## 参照サイト
[Pythonに関する情報](https://note.nkmk.me/python/)
[VScodeでコードの自動整形(Alt+Shift+F)](https://qiita.com/mitashun/items/e2f118a9ca7b96b97840)
[タプルとリストの違い、タプルの使いどころ](https://www.lifewithpython.com/2017/12/python-tuple-list-difference.html)
[key_valueのfor文](https://note.nkmk.me/python-dict-keys-values-items/)
[関数内からグローバル変数を変更したときに関数の外側に与える影響](https://snowtree-injune.com/2018/07/29/post-738/)
[例外処理](https://note.nkmk.me/python-error-message/)
## 変数文字列展開
```python
text = "ピザ"
print(f"今日は{text}を食べました")
```
```:結果
今日はピザを食べました
```

## 基本のfor文
```python
magics = ['alice', 'mike', 'konbu']
for magic in magics:
    print(magic)
```
```:結果
alice
mike
konbu
```
## for文のリストに関数
```python
for value in range(1, 3):
    print(value)
```
```:結果
1
2
```
# for文での配列一括追加
```python
squares = [value**2 for value in range(1, 11)]
print(squares) 
```
```:結果
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
```

## 基本のif文
```python
age = 12
if age < 12:
    print("12未満")
else:
    print("12以上")
```
```:結果
12以上
```

```python
age = 12
if age < 4:
    price = 0
elif age < 65:
    price = 4000
elif age >= 65:
    price = 2000
print(price)
```
```:結果
4000
```

## 基本のkey_value
```python
key_value = {'color':'green','point':'5pt'}
print(key_value['color'])
```
```:結果
green
```

## key_valueの要素追加
```python
key_value = {'color':'green','point':'5pt'}
key_value['weight'] = '100kg'
print(key_value)
```
```:結果
{'color': 'green', 'point': '5pt', 'weight': '100kg'}
```


## key_valueのfor文
```python
key_value = {'color':'green','point':'5pt'}
for key,value in key_value.items():
    print(key)
    print(value)
```

```:結果
color
green
point
5pt
```

```python
key_value = {'color':'green','point':'5pt'}
for key in key_value.keys():
    print(key)
```

```:結果
color
point
```

```python
key_value = {'color':'green','point':'5pt'}
for value in key_value.values():
    print(value)
```
```:結果
green
5pt
```

## 入れ子のkey_value
```python
alien_0 = {'color':'green','point':1}
alien_1 = {'color':'yellow','points':2}
alien_2 = {'color':'red','points':3}
aliens = [alien_0,alien_1,alien_2]

for alien in aliens:
    print(alien)
```

```:結果
{'color': 'green', 'point': 1}
{'color': 'yellow', 'points': 2}
{'color': 'red', 'points': 3}
```

## key_valueで複数の値
```python
favorite_languages = {
    'jen':['python','ruby'],
    'sarah':['c'],
    'edward':['ruby','go'],
    'bill':['pyton','haskell']
}

for name,languages in favorite_languages.items():
    print(f"\n{name.title()}の好きな言語")
    # 変数に格納したvalue(language)を更にfor文で回す
    for language in languages:
        print(f"\t{language.title()}")
```
```:結果
Jenの好きな言語
        Python
        Ruby
Sarahの好きな言語
        C
Edwardの好きな言語
        Ruby
        Go
Billの好きな言語
        Pyton
        Haskell
```

```python
users = {
    'aeinstein': {
        'first': 'albert',
        'last': 'einstein',
        'location': 'princeton',
    },
    'mcurie': {
        'first': 'marie',
        'last': 'curie',
        'location': 'paris',
    }
}

for username,user_info in users.items():
    print(username)
    fullname = f"{user_info['first']}{user_info['last']}"
    print(fullname.title())
```
```:結果
aeinstein
Alberteinstein
mcurie
Mariecurie
```

## 基本のwhile
```python
current_number = 1
# 3以下の間ループ
while current_number <= 3:
    print(current_number)
    current_number += 1
```
```:結果
1
2
3
```

## breakとcontinue
```python
prompt = "何か書いて、終わる場合は終了を入力breakでも終わるよ"
active = True
while active:
    message = input(prompt)
    if message == '終了':
        active = False
    elif message == "break":
        break
    else:
        print(message)
```
```:結果
何か書いて、終わる場合は終了を入力 break
PS C:\Python_Lesson> 
```
```python
current_number = 0
while current_number < 10:
    current_number += 1
    if current_number % 2 == 0:
        continue
    # 上部continueの為下記printは実行されずwhileに戻る
    print(current_number)
```
```:結果
1
3
5
7
9
```
## whileで要素が無くなるまでループ
```python
unconfirmed_users = ['alice', 'brain', 'candace']
confirmed_users = []

# unconfirmed_usersが空になるまでループ
while unconfirmed_users:
    # 末尾から要素をひとつづつ取得する
    current_user = unconfirmed_users.pop()
    print(f"確認中のユーザー{current_user.title()}")
    confirmed_users.append(current_user)

print("\n以下のユーザーは確認済みです")
for confirmed_user in confirmed_users:
        print(confirmed_user.title())
```
```:結果
確認中のユーザーCandace
確認中のユーザーBrain
確認中のユーザーAlice

以下のユーザーは確認済みです
Candace
Brain
Alice
```

## 基本の関数
```python
def greet_user():
    """"シンプルな挨拶"""
    print("こんにちは")
greet_user()
```
```:結果
こんにちは
```

## 関数のreturn
```python
def get_format(first,last):
    full_name = f"{first}{last}"
    return full_name.title()

musician = get_format("jim","carry")
print(musician)
```
```:結果
Jimcarry
```

## 関数で辞書のreturn
```python
def get_format(first,last):
    full_name = {'first_name':first,'last_name':last}
    return full_name

musician = get_format("jim","carry")
print(musician)
```
```:結果
{'first_name': 'jim', 'last_name': 'carry'}
```


## 関数での参照渡し
[関数内からグローバル変数を変更したときに関数の外側に与える影響](https://snowtree-injune.com/2018/07/29/post-738/)
要素の変更ではなく、変数の再定義では値は変わらない
```python
def print_models(unprinted_designs, completed_models):
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        print(current_design)
        completed_models.append(current_design)


def show_compeleted_models(completed_models):
    for completed_model in completed_models:
        print(completed_model)


unprinted_designs = ['iphone', 'ロボット', '12明太']
#関数内で値を追加する
completed_models = []

print_models(unprinted_designs, completed_models)
show_compeleted_models(completed_models)
```
```:結果
12明太
ロボット
iphone
12明太
ロボット
iphone
```

## 可変の引数
```python
def make_pizza(*args):
    print(args)
    
make_pizza('ペパロニ')
make_pizza('マッシュルール','ピーマン','チーズ')
```
```:結果
('ペパロニ',)
('マッシュルール', 'ピーマン', 'チーズ')
```

## 別ファイルの関数を呼び出し
```python:pizza.py
def make_pizza(size,*toppings):
    print(f"\n{size}")
    for topping in toppings:
        print(f"{topping}")
```
```python:make_pizza.py
import pizza

pizza.make_pizza(16,'ペパロニ')
pizza.make_pizza(12,'マッシュルーム','ピーマン','チーズ')
```
```:結果
16
ペパロニ

12
マッシュルーム
ピーマン
```
### 関数を指定して呼び出す方法(.が必要無くなる)
```python:make_pizza.py
from pizza import make_pizza

make_pizza(16,'ペパロニ')
make_pizza(12,'マッシュルーム','ピーマン','チーズ')
```
### モジュール名省略して呼び出す方法
```python:make_pizza.py
import pizza as p

p.make_pizza(16,'ペパロニ')
p.make_pizza(12,'マッシュルーム','ピーマン','チーズ')
```

### モジュールの全関数を読み込み
```python:make_pizza.py
from pizza import*

make_pizza(16,'ペパロニ')
make_pizza(12,'マッシュルーム','ピーマン','チーズ')
```
## 基本のクラス
```python
class Dog:
    # 初期化メソッド
    def __init__(self, name, age):
        # self.変数名はクラス内の全てのメソッドで使用可能
        self.name = name
        self.age = age

    def sit(self):
        print(f"{self.name}はおすわり")

    def roll_over(self):
        print(f"{self.name}がごろんとした")


# インスタンス生成
my_dog = Dog('ウィリー', 6)
print(f"{my_dog.name}です。")
print(f"{my_dog.age}歳です。")
my_dog.sit()
my_dog.roll_over()
```
```:結果
ウィリーです。
6歳です。
ウィリーはおすわり
ウィリーがごろんとした
```

## クラスのプロパティ値を変更する
```python
class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        # selfの値を挿入
        self.odometer_reading = 0

    def get_descriptive_name(self):
        long_name = f"{self.year}{self.make}{self.model}"
        return long_name.title()

    def read_odometer(self):
        print(f"走行距離は{self.odometer_reading}")

    def update_odometer(self, km):
        if km >= self.odometer_reading:
            self.odometer_reading = km
        else:
            print("走行距離は減らせません")

    def increment_odometer(self,km):
        self.odometer_reading += km
    
    def fill_gas_tank(self):
        print("ガソリンタンクありますよ")

my_new_car = Car('audi', 'a4', 2019)
# return文
print(my_new_car.get_descriptive_name())
# 値の変更 プロパティを直接変更 パターン1
my_new_car.odometer_reading = 20
my_new_car.read_odometer()
# 値の変更 kmに渡される パターン2
my_new_car.update_odometer(19)
my_new_car.read_odometer()

my_used_car = Car('subaru','outback',2015)
my_used_car.update_odometer(23500)
my_used_car.read_odometer()
my_used_car.increment_odometer(100)
my_used_car.read_odometer()
```
```:結果
走行距離は23500
走行距離は23600
2019Audia4
走行距離は20
走行距離は減らせません
走行距離は20
```

## クラスの継承
上記のコード(親クラス)の後に記載する
```python
class ElectricCar(Car):
    def __init__(self, make, model, year):
        # superで親クラスのメソッドを呼び出す
        super().__init__(make, model, year)
        self.battery_size = 75

    def describe_battery(self):
        print(f"{self.battery_size}kWh")


子クラスのインスタンスを作成__init__に仮引数を渡す
my_tesla = ElectricCar('tesla', 'model', '2019')
継承したため親クラスのメソッドが使える
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
```
```:結果
2019Teslamodel
75kWh
```
### 継承後メソッドの上書き
```python
class ElectricCar(Car):
    def __init__(self, make, model, year):
        # superで親クラスのメソッドを呼び出す
        super().__init__(make, model, year)
        self.battery_size = 75

    def describe_battery(self):
        print(f"{self.battery_size}kWh")

    def fill_gas_tank(self):
        print("ガソリンタンクはないよ")


# 子クラスのインスタンスを作成__init__に仮引数を渡す
my_tesla = ElectricCar('tesla', 'model', '2019')
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
my_tesla.fill_gas_tank()
```
```:結果
2019Teslamodel
75kWh
ガソリンタンクはないよ
```

## クラスの分割
```python
class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        # selfの値を挿入
        self.odometer_reading = 0

    def get_descriptive_name(self):
        long_name = f"{self.year}{self.make}{self.model}"
        return long_name.title()

    def fill_gas_tank(self):
        print("ガソリンタンクありますよ")


class Battery:
    def __init__(self, battery_size=75):
        self.battery_size = battery_size

    def describe_battery(self):
        print(f"この車のバッテリーは{self.battery_size}")

    def get_range(self):
        if self.battery_size == 75:
            range = 420
        elif self.battery_size == 100:
            range = 510
        print(f"{range}kmです")

# 親クラスの継承とBatteryクラスの継承
class ElectricCar(Car):
    def __init__(self, make, model, year):
        # superで親クラスのメソッドを呼び出す
        super().__init__(make, model, year)
        # ElectricCarのインスタンスを生成すると自動的に
        # Batteryインスタンスを持つこととなる
        self.battery = Battery()

# 子クラスのインスタンスを作成__init__に仮引数を渡す
my_tesla = ElectricCar('tesla', 'model', '2019')
print(my_tesla.get_descriptive_name())
my_tesla.fill_gas_tank()
# Batteryクラスのメソッドを呼び出す
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()
```
```:結果
2019Teslamodel
この車のバッテリーは75
ガソリンタンクありますよ
420kmです
```

## 別ファイルのクラスインポート
```python:car.py
""""自動車を表すクラス"""
class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        # selfの値を挿入
        self.odometer_reading = 0

    def get_descriptive_name(self):
        long_name = f"{self.year}{self.make}{self.model}"
        return long_name.title()

    def read_odometer(self):
        print(f"走行距離は{self.odometer_reading}")

    def update_odometer(self, km):
        if km >= self.odometer_reading:
            self.odometer_reading = km
        else:
            print("走行距離は減らせません")

    def increment_odometer(self, km):
        self.odometer_reading += km

    def fill_gas_tank(self):
        print("ガソリンタンクありますよ")
```
```python:my_car.py
from car import Car

my_new_car = Car('audi','a4',2019)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23
my_new_car.read_odometer()
```
```:結果
2019Audia4
走行距離は23
```

### モジュールにある複数のクラスをインポートする場合
```python
from car import Car, ElectricCar

my_beetle = Car('volkswagen','beetle',2019)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla','roadstar',2019)
print(my_tesla.get_descriptive_name())
```

### さらにクラスをファイル毎に分けてインポートする
```python:car.py
""""自動車を表すクラス"""
class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        # selfの値を挿入
        self.odometer_reading = 0

    def get_descriptive_name(self):
        long_name = f"{self.year}{self.make}{self.model}"
        return long_name.title()

    def read_odometer(self):
        print(f"走行距離は{self.odometer_reading}")

    def update_odometer(self, km):
        if km >= self.odometer_reading:
            self.odometer_reading = km
        else:
            print("走行距離は減らせません")

    def increment_odometer(self, km):
        self.odometer_reading += km

    def fill_gas_tank(self):
        print("ガソリンタンクありますよ")
```
```electric_car.py
from car import Car

class Battery:
    def __init__(self, battery_size=75):
        self.battery_size = battery_size

    def describe_battery(self):
        print(f"この車のバッテリーは{self.battery_size}")

    def get_range(self):
        if self.battery_size == 75:
            range = 420
        elif self.battery_size == 100:
            range = 510
        print(f"{range}kmです")

# 親クラスの継承とBatteryクラスの継承


class ElectricCar(Car):
    def __init__(self, make, model, year):
        # superで親クラスのメソッドを呼び出す
        super().__init__(make, model, year)
        # ElectricCarのインスタンスを生成すると自動的に
        # Batteryインスタンスを持つこととなる
        self.battery = Battery()
```
```mycar.py
from car import Car
from electric_car import ElectricCar

my_beetle = Car('volk','beetle',2019)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla','roadster',2019)
print(my_tesla.get_descriptive_name())
```
```:結果
2019Volkbeetle
2019Teslaroadster
```
## ファイルを開く
```txt:pi_digits.txt
3. 1415926535
8979323846
2643383279

```
```python
# closeが無いのはpythonが自動的に閉じてくれている
with open('pi_digits.txt') as file_object:
    contents = file_object.read()
    print(contents)
```
```:結果
3. 1415926535
8979323846
2643383279
```

### 空行を削除
```python
filename = 'pi_digits.txt'
with open(filename) as file_object:
    for line in file_object:
        print(line.rstrip())
```

### 変数に格納後表示
```python
filename = 'pi_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines()

    for line in lines:
        print(line.rstrip())
```

## ファイルの生成
```python
# w    書き込みモード
# r    読み込みモード
# a    追記モード
# r+   読み書きモード
filename = 'programming.txt'
with open(filename,'w') as file_object:
    file_object.write("I love programming\n")
    file_object.write("I love creating new games\n")
```


## 例外処理
### ゼロ除算エラー(ZeroDivisionError)
下記はtracebackが表示される
```python
print(5/0)
```
```:結果
Traceback (most recent call last):
  File "c:\Python_Lesson\division_calculator.py", line 1, in <module>
    print(5/0)
ZeroDivisionError: division by zero
```
下記で例外が設定できる
```python
try:
    print(5/0)
except ZeroDivisionError:
    print("ゼロで割れません")
```
```:結果
ゼロで割れません
```
### ゼロ除算エラー2(ZeroDivisionError)
下記は割れないとエラーが表示される
```python
print("数を2つ入力")
print("終了はqを入力")

while True:
    first_number = input("\n1番目の数値")
    if first_number == 'q':
        break
    
    second_number = input("2番目の数値")
    if second_number == 'q':
        break
    
    answer = int(first_number)/int(second_number)
    print(answer)
```
下記でエラー処理を記載
```python
print("数を2つ入力")
print("終了はqを入力")

while True:
    first_number = input("\n1番目の数値")
    if first_number == 'q':
        break

    second_number = input("2番目の数値")
    if second_number == 'q':
        break
    try:
        # 割り算を実行する　成功した場合elseブロックへ
        answer = int(first_number)/int(second_number)
    #  エラーが表示される際にの処理を記載
    except ZeroDivisionError:
        print("割れません")
    else:
        print(answer)
```
```:結果
ゼロで割れません
```
### ファイル読み込みエラー(FileNotFoundError)
```python
filename = 'alice.txt'
try:
# fは慣例となっている、また引数でエンコードを合わせている
   with open(filename, encoding='utf-8') as f:
        contents = f.read()
except FileNotFoundError:
        print("ファイルが見つかりません")
```
```:結果
ファイルが見つかりません
```
### ファイル読み込みエラー2(FileNotFoundError)
```python
filename = 'alice.txt'
try:
# fは慣例となっている、また引数でエンコードを合わせている
   with open(filename, encoding='utf-8') as f:
        contents = f.read()
except FileNotFoundError:
        print("ファイルが見つかりません")
else:
    # 単語を取得する
    words = contents.split()
    num_words = len(words)
    print(f"{filename}には{num_words}含まれる")
```
```:結果
alice.txtには29465含まれる
```
### ファイル読み込みエラー3(FileNotFoundError)
```python
def count_words(filename):
    try:
        # fは慣例となっている、また引数でエンコードを合わせている
        with open(filename, encoding='utf-8') as f:
            contents = f.read()
    except FileNotFoundError:
        print("ファイルが見つかりません")
    else:
        # 単語を取得する
        words = contents.split()
        num_words = len(words)
        print(f"{filename}には{num_words}含まれる")

filenames = ['alice.txt', 'siddhartha.txt', 'mob_dick.txt', 'little_women.txt']
for filename in filenames:
        count_words(filename)
```
```:結果
alice.txtには29465含まれる
ファイルが見つかりません
ファイルが見つかりません
ファイルが見つかりません
```

### ファイル読み込みエラー4(pass)
```python
def count_words(filename):
    try:
        # fは慣例となっている、また引数でエンコードを合わせている
        with open(filename, encoding='utf-8') as f:
            contents = f.read()
    except FileNotFoundError:
        #エラーでもあえて何も起こさないようにする
        pass
    else:
        # 単語を取得する
        words = contents.split()
        num_words = len(words)
        print(f"{filename}には{num_words}含まれる")

filenames = ['alice.txt', 'siddhartha.txt', 'mob_dick.txt', 'little_women.txt']
for filename in filenames:
        count_words(filename)
```
```:結果
alice.txtには29465含まれる
```
## Json処理
```python
# jsonモジュール
import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json'
# jsonファイルを生成しnumbersを書き込む
with open(filename, 'w') as f:
    json.dump(numbers, f)

with open(filename) as f:
    numbers = json.load(f)

print(numbers)
```
```:結果
[2, 3, 5, 7, 11, 13]
```

## テスト
これは別でまとめた方がいい気がしました。