Python 初級入門　制御フロー編

## 前提
- python初学者、触ったことない人が投稿しています
- 個人的にあまり馴染みのない書き方について記載しています
- 誤っている箇所等があればコメントでご指摘いただけると幸いです
- こちらの記事は[基本](https://qiita.com/takemaru_shuna/items/b510a8cc6b3e296c9ca3)の続きとなっていますので気になる方は是非！

## Pythonの基本？
- 複数行にわたって書く場合はダブルクォート3つ
- また、コメントは横ではなく上に書くのが暗黙のルール
- 次の行に行くのは８０文字（これはPython関係ないかも）
```.py
# コメント

# ほんとか？
"""
これがコメントになるらしい
"""

# 一行が長くなって次の行に行きたい時は\
s = "ssssss" \
+ "aaaaaa"
# ()で囲っても同義
s = ("ssssss" 
+ "aaaaaa")

>>> s # ssssssaaaaaa

```

## if文
- インデントで次の行が判断される
- インデントずれでエラーが起こるので注意が必要
- 大体4つのスペースを開けるらしい
- `else if`じゃない
- 条件式の終わりに`:`
```.py
x=10
if x > 0:
    print('plus') # ここが出力される
    # nest
    if x > 5:
        print('Greater than 5')
elif X == 0:
    print('zero')
else:
    print('negative')
```

## 三項演算子
- `&& , || , !value`は使わない
```.py
a =1 
b=2
# && ではなく'and'か'&'
a > 0 and b > 0 
# || ではなく'or'か'|'
a > 0 or b > 0

# !valueのような書き方はできない
value = False
if not value:
    print("valueはFalseです")
```

## 値の判定
- 空の配列falsyな値
- 何も入っていない値（null）はNoneで扱う
→ `None`を比較する際に`is`は使われがち
```.py
empty = []
if not empty:
    print('empty') # empty

# None, is
is_empty = None
if is_empty is None
    print('None') # None
```

## Input関数
- 入力を待つ関数
- [公式](https://www.python.jp/train/string/input.html)
```.py
while True:
    word = input('Enter:')
    if word == 'ok':
     print('ok, next')
```

## enumerate関数
- 第二引数に数値を指定するとの開始数値を指定できる
```py
for i,animal in enumerate(['dog','cat','lion','bard']):
    print(i,animal) 
    # 0,dog
    # 1,cat...
```

## zip関数
- 複数のイテラブル（リスト、タプル、セットなど）から要素を取り出し、対応する要素をペアとしてまとめるために使用される
- まとめられた要素はタプルとして返される
```py
animals = ['dog','cat']
fruits = ['banana','apple']
drinks = ['coffee','juice']
for animal, fruit, drink in zip(animals,fruits,drinks):
    print(animal, fruit, drink)
    # dog,banana,coffee...
```

## 辞書型のループ
- よく使われるらしい
- 重要かも！？
```py
staff = {'太郎': '24歳', '花子': '28歳', '次郎': '18歳'}

# valueを取り出したい場合
for value in staff.values():　# for value in staff:でも取り出せる
    print(value)　# 24歳...

# keyを取り出す
for key in staff.keys():# for key in staff:でも取り出せる
    print(key) # 太郎... 

# key,valueを取り出す
for key, value in staff.items():
    print(key, value)　# 太郎 24歳...
```

## 関数定義
- endがいらない
→railsやってたから間違えてつけそう
- `type : function`
- 値を返す場合は`return`を使う
- キーワード引数は位置順序を気にせず引数に入れることが可能
- デフォルト引数も存在する（省略）
→ pythonはデフォルトの引数にリストを渡すべきではないという暗黙の了解があるらしい

```py 
def greeting()
     print('good morning')

greeting()　# good morning

# 引数あり,型定義した場合
def color(color: string) -> string
    if color == 'red'
        return 'reds'
        
result = color('red') 
print(result) # reds

# キーワード引数
def food(meat,drink,dessert)
    print(meat)
    print(drink)
    print(dessert)

food(meat = 'cow', drink = 'juice', dessert = 'ice cream')

# 位置引数のタプル化
def greet(*args) # *を使ってやると('Hi','good morning','Taro')のようにタプル化される
    for arg in args:
        print (arg) # Hi ...

greet('Hi','good morning','Taro')

# 位置引数とも一緒に使える
def greet(word, *args) 
    for arg in args:
        print (arg) # Hi ...
greet('Hi','good morning','Taro')

# 以下も同じことをしている。展開して渡している
t = ('Hi','good morning','Taro')
greet(*t)

# キーワード引数の辞書化
def menu(**kwargs)
    print(kwargs) # {'drink':'tea','dessert':'ice'}
    for k,v in kwargs
        print(k,v)# drink tea...
        
menu(drink='tea', dessert='ice')

# 以下も同じことをしている。展開して渡している
d = {'drink':'tea','dessert':'ice'}
menu(**d)

## 位置引数のタプル化とキーワード引数の辞書化
def menu(food,*args,**kwargs)
    print(food) # meat
    print(*args) # ('banana','apple')
    print(**kwargs) # {'drink':'tea', 'dessert':'ice'}
menu('meat','banana','apple',drink='tea', dessert='ice')
 ```
 ## デコレーター
 - 関数やクラスの前後に特定の処理を追加できる機能
 - 複数設定可能
 - 複数設定する際は順序が大事なので意識しておくこと

```py
def my_logger(f):
    def _wrapper(*args, **keywords):
        # 前処理
        print('start')

        # デコレート対象の関数の実行
        v = f(*args, **keywords)

        # 後処理
        print('end')

        return v
    return _wrapper

@my_logger
def add(a,b):
    return a + b 

res = add(10,20)
print(res)
# strat
# end
# 30
```

## ラムダ
- functionを省略した形で書くことが可能になる
- 引数に直接記述することも可能

```py
#　通常の関数
 def sample_func(word): 
     return word.capitalize()
     
# ラムダにした場合
sample_func = lamda word: word.capitalize()
# 関数を受け取るfunction
関数(lamda word: word.capitalize())
```

## ジェネレーター
- next()を使って一つずつジェネレートした値を取り出す
- pythonはyieldをジェネレーターとして判断する
- 処理を走った後の状態を保持するのでfor文のように一気に回らずに使える

```py
def greeting():
    yield 'morning'
    yield 'hello'
    yield 'night'

g = greeting()
print(next(g)) # morning
print(next(g)) # hello
print(next(g)) # night 
```

## 内包表記
- あえてメモリを見たりしないから処理が早いと言われる
- 短めのループの時は採用しても良いかも
- nestしたものは何個でも入れられるけどなんかも入れると可読性が下がりバグの温床になる
```py
#### リスト内包表記
t = (1,2,3,4,5)
r = []
for i in t
    r.append(r)

#　やっていることは上記と同じ
r = [1 for i in t]
print(r) # [1,2,3,4,5]

# if文を追加したい場合
r = [1 for i in t if i % 2 == 0]
print(r) # [2,4]

# nestさせたループ
t2 = (5,6,7,8,9)
r = [i * j for i in t for j in t2]
print(r) # 5,6,7,8,9... 

#### ジェネレーター内包表記
def g():
    for i in range(10):
        yield i

g = (i for i in range(10) if i % 2 == 0)
print(type(g)) # generator
for x in g:
    print(x) # 0\n, 2\n,...

# tupleになるときはtupleとつける
g = tuple(i for i in range(10))
print(type(g)) # tuple

```

## 辞書包括表記
```py
array = ['piyo','aaa']
array2 = ['bbb','ccc']
d = {key:value for key,value in zip(array,array2)}
print(d) # {'piyo': 'bbb', 'aaa': 'ccc'}
```

## エラーハンドリング
- exceptでエラーを検知して、なんらかの処理をして処理を終わらせないようにする
- except エラーの種類　という記載をすることでそのエラーの時だけ実行させることも可能
- 他のエラーについては[公式](https://docs.python.org/3/library/exceptions.html#exception-hierarchy)を参照してください
- 独自で例外を発生させることももちろん可能
```py
array = [1,2,3]
num = 5
try:
    array[num]
except:
    print('error')

# エラーの種類を指定
# 変数に入れて出力も可能
# 複数指定も可能
try:
    array[num]
except IndexError as error:
    print(f'index error : {error}')
except NameError as error:
    print(f'name error : {error}')
except Exception as error:
    print(f'other error : {error}')
# 成功時のみ実行される(exceptに引っ掛からなかった場合)
else:
    print('done')
#　最後に必ず実行される
finally:
    print('finally')
```


 
 ## Docstrings
 - 関数の中に記載するのがルール
 - 一番最初にどういった関数なのかを記載する
 - 次にArgsとかき引数のパラメーターがどんな引数なのかを記載
 - 3つ目にReturnsを記載し、どういった値が返却されるのかを記載する
 - `関数.__doc__`：どういった関数なのかを見ることができる


## 今回の学習をしてみて
- 以前触っていた他の言語と似ているようで似ていないような、なんとなく掴めない感じがあるなという感じがする
- 内包表記とかはふれらたからいいか。ふーんって感じでした

## 最後に
- 次回はモジュールとかパッケージについて学んでみようと思います
- あと2回ぐらい書いたら簡単なアプリケーションでも作ってみたいものだ