-忘備録- Python基礎

##参考書籍
[最短距離でゼロからしっかり学ぶ Python入門　必修編](https://www.amazon.co.jp/%E6%9C%80%E7%9F%AD%E8%B7%9D%E9%9B%A2%E3%81%A7%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%97%E3%81%A3%E3%81%8B%E3%82%8A%E5%AD%A6%E3%81%B6-Python%E5%85%A5%E9%96%80-%E5%BF%85%E4%BF%AE%E7%B7%A8-%E3%80%9C%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%82%A8%E3%83%A9%E3%83%BC%E5%87%A6%E7%90%86%E3%80%81%E3%83%86%E3%82%B9%E3%83%88%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9%E3%81%BE%E3%81%A7-Eric-Matthes-ebook/dp/B08GP27B1P/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E6%9C%80%E7%9F%AD%E8%B7%9D%E9%9B%A2%E3%81%A7%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%97%E3%81%A3%E3%81%8B%E3%82%8A%E5%AD%A6%E3%81%B6+Python%E5%85%A5%E9%96%80&qid=1617017293&s=digital-text&sr=1-2)

###はじめに
上記書籍を読んでPythonを用いたプログラミングの基礎について忘備録をまとめてます。
普段swiftを触ることが多いので、swiftと比べて感想を書いているところがあります。


#基本
###コメントアウト
```Python
#でコメント
```
メモ
・VSCodeを使用する際は、cmd+/でコメントアウトできる

###変数
文字列は"または'でも可能

```python
hoge = "hello world hoge"
fuga = 'hello world hoge'
```
複数代入可能

```python
x, y, z = 1, 2, 3
```
数値は_で区切れる

```python
want = 5000_0000_0000_0000
```
型変換

```Python
message = '1'
x = int(message)

print(x + 2) #変換したので計算で利用できる
#3
```

メモ
・型指定がない
・"も使えるので使いたくなってしまうが、参考書籍には'の方が優先的に使われていた。

###print文
文字だけ出力

```python
print("hello world")
```

変数を出力する時はfをつけて{}でかこむ

```python
hoge = 'hello world hoge'
print(f"{hoge}")
```
メモ
・()ではなく{} (この間違いで何回もコンパイルエラーに)

#リスト (配列)
~~正直配列の方が馴染み深い~~

基礎

```python
hoge_list = ['hoge', 'fuga', 'piyo','poyo', 'abc']
print(hoge_list)
# ['hoge', 'fuga', 'piyo', 'poyo', 'abc']
print(hoge_list[0])
# hoge
```

-1で最後の配列にアクセスできる。-2だったら後ろから２番目の配列にアクセス

```python
print(hoge_list[-1])
# abc
```

配列の要素を上書き

```python
print(hoge_list)
# ['hoge', 'fuga', 'piyo', 'poyo', 'abc']
hoge_list[0] = 'hogefuga'
print(hoge_list)
# ['hogefuga', 'fuga', 'piyo', 'poyo', 'abc']
```

インデックスを指定して要素を削除 - del -

```python
print(hoge_list)
# ['hogefuga', 'fuga', 'piyo', 'poyo', 'abc']
del hoge_list[1]
print(hoge_list)
# ['hogefuga', 'piyo', 'poyo', 'abc']
```

値を指定して要素を削除 - remove() -

```python
print(hoge_list)
# ['hogefuga', 'piyo', 'poyo']
hoge_list.remove("hogefuga")
print(hoge_list)
# ['piyo', 'poyo']
```

配列最後の要素を削除して取り出す - pop() -

```python
print(hoge_list)
# ['hogefuga', 'piyo', 'poyo', 'abc']
poped_list = hoge_list.pop()
print(hoge_list)
# ['hogefuga', 'piyo', 'poyo']
print(poped_list)
# abc

# インデックスを指定することもできる
# poped_list = hoge_list.pop(1)
```

永続的な並び替え - sort() -

```python
sort_list = ['momo', 'ringo', 'apple', 'mikan']
sort_list.sort()
print(sort_list)
# ['apple', 'mikan', 'momo', 'ringo']
sort_list.sort(reverse=True)
print(sort_list)
# ['ringo', 'momo', 'mikan', 'apple']
```

一時的な並び替え - sorted() -

```python
sort_list = ['momo', 'ringo', 'apple', 'mikan']
print(sorted(sort_list))
# ['apple', 'mikan', 'momo', 'ringo']
print(sort_list)
# ['momo', 'ringo', 'apple', 'mikan']
```

メモ
・配列操作はメソッドの種類がいくつかあるので用途に合わせた使い分け大事
・-で後ろの要素にアクセスできる



#for文

```python
names = ['alice', 'david', 'hoge']
for name in names:
    print(name)
    print('インデントあり')
print('インデントなし')

#(↓↓↓出力結果↓↓↓)
alice
インデントあり
david
インデントあり
hoge
インデントあり
インデントなし
```

メモ
・pythonではforなど{}で囲むわけではなくインデントで区別する

リスト作成 - range() -

```python
numbers = list(range(1,11))
print(numbers)
#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

range()を使ったfor文の省略

```python
#省略前
squares = []
for value in range(1,11):
    square = value ** 2 ##**でべき乗
    squares.append(square)
print(squares)
#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

#省略後
squares = [value ** 2 for value in range(1,11)]
print(squares)
#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

```

#スライス
スライス: リストの一部を利用する

```python
squares = [value ** 2 for value in range(1,11)]

#1番目から4番目まで
print(squares[1:4])
# [4, 9, 16]

#4番目まで
print(squares[:4])
#  [1, 4, 9, 16]
 
#1番目から
print(squares[1:])
# [4, 9, 16, 25, 36, 49, 64, 81, 100]

#全部
print(squares[:])
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
```
スライスによるループ

```python
for square in squares2[:4]:
    print(square)

###出力結果
1
4
9
16
```

スライスを使ったリストのコピー

```python
#__スライスを使う場合__
my_food = ["団子", "白玉"]
friend_food = my_food[:]
my_food.append("抹茶")
friend_food.append("チョコ")
print("私の食べ物")
print(my_food)
print("友達のの食べ物")
print(friend_food)  

###出力結果
私の食べ物
['団子', '白玉', '抹茶']
友達のの食べ物
['団子', '白玉', 'チョコ']  
###ここまで

#__スライスを使わないで代入する場合__
#スライスを使わないとコピーではなく同じものとして扱われる
my_food = ["団子", "白玉"]
friend_food = my_food
my_food.append("抹茶")
friend_food.append("チョコ")
print("私の食べ物")
print(my_food)
print("友達のの食べ物")
print(friend_food) 

###出力結果
私の食べ物
['団子', '白玉', '抹茶', 'チョコ']
友達のの食べ物
['団子', '白玉', '抹茶', 'チョコ']
```
メモ
・単に代入するだけではコピーできないのでスライスを使う (そもそも代入じゃないかも)

#タプル(不変なリスト)
変更できない値をイミュータブル(不変)といい、イミュータブルなリストをタプルと呼ぶ

```python
#[]の代わりに()を使ってリストを定義
dimensions = (200, 50)
print(dimensions[0])
# 200
```

下記のようなコードはエラーになる

```python
dimensions[0] = 300
```

forも使える

```python
for dimension in dimensions:
    print(dimension)
###出力結果
200
50
```
上書きしたいときはタプルそのものを上書きできる

```python
dimensions = (300, 50)
print(dimensions[0])
# 300
```
メモ
・タプルというとSwiftでは異なる型をまとめて扱うもの指すが、Pythonでは不変なリストのことを指す。

#条件式
等しい==, 等しくない!=

```python
print("a"=="a")
#True
print("a"!="b")
#True
```


and条件はand, or条件はor

```python
print("a"=="a" and 1==1)
#True
print("a"=="a" and 1==2)
#False
print("a"=="a" or 1==1)
#True
print("a"=="a" or 1==2)
#True
```


値がリストに存在することを確認する

```python
lunch = ["ラーメン", "うどん", "パスタ"]
print("ラーメン" in lunch)
#True
print("そば" in lunch)
#False

#否定形
print("ラーメン" not in lunch)
#False
print("そば" not in lunch)
#True
```

##if文, elif文, else文

```python
ages = [20, 1, 15]
for age in ages:
    if age < 5:
        print("子供料金")
    elif age < 18:
        print("学生料金")
    else:
        print("大人料金")
###出力
大人料金
子供料金
学生料金
```

リストの空欄チェック

```Python
list = [] #list = [1] とすると trueになる
if list:
    print("中身あり")
else:
    print("空")
```


メモ
・Pythonではelse if文ではなく elif文。気づかずコンパイルエラーになることも

#辞書

```Python
yusya = {'NAME':'yusya', 'LV':5}
print(yusya["LV"])
# 5
```
キーと値の追加

```Python
yusya['quest'] = "魔王を倒す"
print(yusya)
#{'NAME': 'yusya', 'LV': 5, 'quest': '魔王を倒す'}

#空の辞書からでも追加できる
maou = {}
maou['LV'] = 99
maou['status'] = '無敵'
print(maou)
#{'LV': 99, 'status': '無敵'}
```

キーと値を消す

```Python
maou = {'LV': 99, 'status': '無敵'}
del maou['status']
print(maou)
#{'LV': 99}
```

キーがあれば取得 - get() -

```Python
maou = {'LV': 99}
#print(maou['status'])
#キーがない場合エラーになる

print(maou.get('status', 'ステータスなし')) #キーが無い場合ステータスなしの文字列を返す
#ステータスなし
```
辞書をループする

```python
user_0 = {
    'name' : 'hoge',
    'first' : 'hoge',
    'flast': 'fuga',
}
for key, value in user_0.items(): #ここでkeyとvalueの順番を逆にしたら入れ替わってしまうので注意
    print(f"キー:{key}")
    print(f"値:{value}")
###出力結果
キー:name
値:hoge
キー:first
値:hoge
キー:flast
値:fuga
```
メモ
・[]ではなく{}で囲む。(個人的に癖で[]で囲みがちなので注意)

#While文

```python
current_number = 1
while current_number <= 5:
    print(current_number)
    current_number += 1

###出力結果
1
2
3
4
5
```

#関数

```python
def hoge_fuga(hoge, fuga):
    print(hoge_name)
    print(fuga_name)

hoge_fuga(1, 2)
hoge_fuga("fuga", "hoga")

###出力結果
1
2
fuga
hoga
```
引数指定もできる

```python
hoge_fuga(fuga=2, hoge=1)
hoge_fuga(1, fuga=2)
```

ダメな呼び方

```python
hoge_fuga(fuga_name=2, 1) #コンパイルエラーになる
```

戻り値ありの関数

```python
def fuga():
    return 111
print(fuga())
#111
```

可変長の引数を持つ関数

```python
def print_names(*names):
    for name in names:
        print(name)
print_names('a', 'b', 'c')

###出力結果
a
b
c
```

・関数呼び出しするときの自由度が高い
・順番通りに書くなら引数名を書いても書かなくてもいい
・引数名を書く場合は順番を守らなくてもいい


#クラス

```Python
class Dog:
    # selfを引数に書かないといけない
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def sit(self):
        print(f"{self.name}はお座りしている")

    # selfを引数に書かないといけない
    def birthday(self):
        self.age = self.age + 1
```

インスタンス生成

```Python
my_dog = Dog('ポチ', 1)
```

属性(メンバー変数?)にアクセス

```Python
print(f"{my_dog.name}は{my_dog.age}才")
#ポチは1才
```

メソッドを呼び出す

```Python
my_dog.sit()
#ポチはお座りしている
```

属性の値を直接編集

```Python
my_dog.age = 2
print(f"{my_dog.age}")
#2
my_dog.birthday()
print(f"{my_dog.age}")
#3
```

クラスの継承

```Python
class Chihuahua(Dog):
    def __init__(self, name, age, coat):
        super().__init__(name, age)
        self.coat = coat
    # オーバーライド
    def birthday(self):
        print("誕生日おめでとう")

my_chihuahua = Chihuahua("チワワ", 1, "hoge")
my_chihuahua.sit()
#チワワはお座りしている
my_chihuahua.birthday()
#誕生日おめでとう
print(f"{my_chihuahua.age}") #上書きしたのでage+1されない
#2
```

メモ
・initを宣言するときに__で囲まないといけない。（正直手間だしなんでこのように書くのかわかってない）
・クラス内でselfを使うときは引数にselfを宣言する。呼び出すときはself以外の引数だけ指定する

#モジュール(別ファイル)の関数を使う

```Python:method.py
def method1(name, *hobbys):
    print(f"{name}さんの趣味一覧")
    for hobby in hobbys:
        print(hobby)

def method2():
    print("method2")
```

全部インポート

```Python:hoge.py
import method
method.method1("hoge1", "movie", "game")
method.method2()
```

一部関数だけインポート

```Python:hoge.py
from method import method1
#ファイル名を省略できる
method1("hoge2", "movie", "game")
```

全部の関数インポート

```Python:hoge.py
from method import *
method1("hoge4", "movie", "game")
method2()
```

#モジュール(別ファイル)のクラスを使う

```Python:tesy_class.py
class Hoge:
    # selfを引数に書かないといけない
    def __init__(self, hoge):
        self.hoge = hoge

    def log(self):
        print(f"{self.hoge}")

class Fuga(Hoge):
    # selfを引数に書かないといけない
    def __init__(self, hoge, fuga):
        super().__init__(hoge)
        self.fuga = fuga
```

モジュールからクラスをインポート")

```python:hoge.py
from test_class import Fuga

fuga = Fuga("hoge", "fuga")
fuga.log()
#hoge
```

複数のクラスをインポート

```python:hoge.py
from test_class import Hoge, Fuga
hoge = Hoge("hoge")
hoge.log()
```

メモ
・クラス名はキャメルケースで書く、インスランスやモジュールはスネークケースでかく