Python基礎❷

# コメント

+ 複数行のコメント
+ ルール的には1行80文字まで。
+ スペースは4つ（全て合わせる）

```csharp:main.py
# //1行コメント

"""
test
test
test
"""//複数コメント
```
# 1行が長くなるとき

```csharp:main.py
s = 'aaaaaaa' + 'ccccccccc'
print(s)

s = 'aaaaaaaaa'
    + 'ccccccc'//プラスから始まっているため、このプラスが何かわからずエラーになる

s = 'aaaaaaaaa'\　//バックスラッシュを入れることによって、まだ終わりではないこを表す。
    + 'ccccccc'

s = ('aaaaaaaaa'
    + 'ccccccc')//バックスラッシュが嫌であれば、カッコで囲む
```
# if文

```csharp.main.py
x = -12
if x < -13:　//コロンで終わる
   print('正解')//スペースは4つが暗黙の了解
elif x === -12:
   print('正解')
else:
   print('不正解')
```
+ ifの中にifを入れることもできる

```csharp:main.py
a = 50
b = 12

if a > 0:
    print('aは0以上')
    if b > 0:
        print('bは0以上')
```
+ デバッカーとコンソールを駆使して開発効率をあげる（PyCharm）

# 論理演算子
+ `and`と`or`
+ andは**かつ**、orは**または**
```csharp:main.py
a = 10
b = 10
if a > 0 and b > 8:
    print('正解です。')
```
# InとNot

```csharp:main.py
x = [1,2,3,4]
y = 1
if y in x:
    print('1はあります')
if 5 not in x:
    print('5はありません') 

//notはあまり推奨されていない
//notの使いどここ
is_ok = True
if not is_ok://Trueでなければ
   print('Trueではありません')
```
# 値が入っていない時の判定

+ **Trueと判定されるときは変数に値が入っている時(例：リストでもタプルでも集合でも辞書でも値が入っていればTrueとなる。)**
+ 0、0.0、{}、()
+ 変数が1の時はTrueとなる。

```csharp:main.py
is_ok = '最高'
if is_ok:
    print('OK')
else:
    print('no')
//OK

is_ok = 0
if is_ok:
    print('OK')
else:
    print('no')
//no →0もfalseと判定される。

is_ok = '' //[] {}など　→ if len(is_ok) > 0:はしなくて良い
if is_ok:
    print('OK')
else:
    print('no')
//空であれば、flaseとなる。
```
#  Noneを判定する時

+ `is`はNoneオブジェクトを使う
+ `None`→変数は使うけど値に何も入れたくないとき

```csharp:main.py
is_empty = True
if is_empty is not None:
    print('None!!')

print(1 == True)//True
print(1 is True)//1とTrueではオブジェクトが違うためFlaseになる。
print(None is None)//True
```
# while文、continue文、break文

```csharp:main.py
//continue文

count = 0
while True:
    if count >= 6:
       break
    print(count)
    count += 1//0,1,2,3,4,5


count = 0
while True:
    if count >= 5:
       break

    if count == 2:
       count += 1
       continue

    print(count)
    count += 1
```
# while文とelse文
+ `break`を使ったとき、while文から抜け出す。

```csharp:main.py
count = 0
while count < 5:
    print(count)
    count += 1
else:          //while文を抜け出すのではなく、5よりcountが大きくなれば、else内の処理にいく。
    print('OK')//


while count < 5:
    if count == 1:
        break //breakによってwhile文から抜け出す。
    print(count)
    count += 1
else:
    print('done')

0
1
2
3
4
OK
```
# input関数

+ while文よよく使われる`input関数`
+ 相手に入力を促す
+ 文字列で返ってくる

```csharp:main.py
while True:
    word = input('数字を入力してください')
    num = int(word)
   　if num == 100:
        break
    print('next')//100が入力されるまで待つ。100でなければ、コンソールに表示し、100であれば、breakでプログラムを終了する。
```
# for文とbreak文、continue文

```csharp:main.py
some_list = [1,2,3,4,5]

# i = 0
# while i < len(some_list):
#     print(some_list[i])
#     i += 1

for i in some_list://iにsome_listの中のものを1つずつ代入していく。
    print(i)

for word in 'naoki':
    print(word)


for s in ['My', 'name', 'is', 'Naoki']:
    print(s)
/*
My
name
is
Naoki
*/
```
+ break文とcontinue文

```csharp:main.py
for word in ['My','name', 'is', 'naoki']:
    if word == 'name':
        break//wordはnameの時、forから抜け出す。continueの時は、namenだけ飛ばして次のisからまたループで表示する。
    print(word)
```

# for、else分

+ ループがbreakなしで実行された後に、else文内の処理を実行する
```csharp:main.py
for fruit in ['apple', 'banana', 'orange']:
    print(fruit)
else:
    print('終了')


for fruit in ['apple', 'banana', 'orange']:
    if fruit == banana:
        print('食べるのを辞めます')
        break
    print(fruit)
else: 
    print('終了')
```
# range関数

```csharp:main.py
for i in range(10)://0から9まで表示
    print(i)

for i in range(3,10)://3から9まで表示

for i in range(3,10,2)://3から9まで＋2ずつで表示→3、5、7、9
print(i)

for _ in range(1,20)://インデックス番号を使わない時はアンダーバーにしておく。
    print('hello')//helloを20個表示
```

# enumerate関数

```csharp:main.py
i = 0
for fruit in ['banana', 'apple', 'orange']:
    print(i, fruit) 
    i += 1//これだとめんどくさい

//enumerate関数を使う
for i, fruit in enumerate(['banana', 'apple', 'orange'])://bananaをfruitに入れて、iに0を代入、次にappleをfruitに入れて、iに1を代入
    print(i,fruit)
```
# zip関数


```csharp:main.py
days = ['Mon', 'Tue', 'Web']
fruits = ['apple', 'banana', 'orange']
drinks = ['coffee', 'tea', 'beer']

for i in range(len(days)):
    print(days[i], fruits[i], drinks[i])

//Mon apple coffee
Tue banana tea
Web orange beer
//
```
+ `zip関数`を使ってもっと簡単に書く。

```csharp:main.py
for day, fruit, drink in zip(days, fruits, drinks):
    print(day, fruit, drink)
```
# 辞書をfor文で処理

+ `d.items()`→dict_items([('x', 100), ('y', 200)])が返ってくる。
+ リストの中にタプルが入っている。

```csharp:main.py
//キーのみ表示
d ={'x':10,'y':2}
for k in d:
    print(k)

//キーとバリューを表示
d = {'x':100, 'y':200}
for k,v in d.items(): //xがkに、100がvに代入される。
    print(k, ':', v)

```
# 関数定義
`def`で関数定義

```csharp:main.py
def say_helllo():
   print('Hello')

say_hello()//Helloと表示される。

//型を見る
print(type(say_hello))//<class 'function'>
```
+ 返り値　→ return

```csharp:main.py
def say_hello():
    d = 'hello'
    return d

result = say_hello()
    print(result)
```
+ 引数
+ 引数colorを設定

```csharp:main.py
def what_is_this(color):
    print(color)

what_is_this('red')

//例
def what_is_this(color):
    if color == 'red':
        return 'tomato'
    elif color == 'green':
        return 'green paper'
    else:
        return 'I don\'t know'
result = what_is_this('yellow')
result = what_is_this('red')
result = what_is_this('green')
print(result)

```
+ 関数の引数と返り値の宣言

```csharp:main.py
def add_num(a:int, b:int) -> int//aはint、bもintと設定する。->intによって返り値もintと設定できる。
    return a + b

r = add_num(10, 20)
print(r)
```

# while True:で無限ループ

+ `while True`でわざと無限ループを作る。

```csharp:main.py
min_length = 4
while True: 
    name = input("アルファベットを５文字以上入力してください：")//アルファベットが5文字未満であれば、再度繰り返し処理を行い、入力を促す。
    if len(name) > min_length and name.isalpha():
        break
print("あなたは、{0} と入力しました。".format(name))
```
# 位置引数、キーワード引数、デフォルト引数

+ 引数複数の時（位置引数）

```csharp:main.py
def sport(ball,'water', 'running')
    print(ball) 
    print(water)
    print(running)

sport('soccer', 'swim', 'baseball')
```
+ キーワードアーギュメント
+ 順序を変えてもキーワードを指定しておけば大丈夫
+ 位置引数とキーワード引数を混ぜる時は順序は必要


```csharp:main.py
def sport(ball,'water', 'running')
    print(ball) 
    print(water)
    print(running)

sport(ball='soccer', water='swim', running='baseball')//キーワード引数
```
+ デフォルト引数

```csharp:main.py
def sport(ball='soccer',water='swim', running='baseball')
    print(ball) 
    print(water)
    print(running)

sport()//デフォルト引数が表示される。
```

+ デフォルト引数で注意すべきこと

```csharp:main.py
def test_func(x, l =[])
    i.append(x)
    return l

y =[1,2,3]
r = test_func(100 ,y)
print(r)
```
+ デフォルト引数にリストや辞書を渡すのはダメという暗黙の了解

```csharp:main.py
def test_func(x, l=None):
    if l is None:
        l =[]  # 引数として何かが渡されたときは、appendを使う。自分で空のリストを作成する。
    l.append(x)
    return l

r = test_func(100)//[100]
print(r)

r = test_func(100)//[100]
print(r)
```
# 位置引数のタプル化

```csharp:main.py
//めんどくさいやり方
def say_hello(word, word2, word3):
    print(word)
    print(word2)
    print(word3)

say_hello('Hi', 'Mike', 'nance')
```

+ `*args`を使うやり方

```csharp:main.py
def say_hello(*args)://argsにすべて入る
    //print(args)→まとめてタプルに入れてくれる。（'Hi', 'Mike', 'nance'）
　　　for arg in args:
         print(arg)

say_hello('Hi', 'Mike', 'nance')
```
位置引数と*args
+ 下記の場合、第1引数は固定（Hi）で、その後に引数がいくつ入るかわからないときは、*argsでまとめる。

```csharp:main.py
def say_hello(word, *args)://argsにすべて入る
     print(word)//Hi
　　　for arg in args:
         print(arg)

say_hello('Hi', 'Mike', 'nance')
```
+ 自分でタプルを作って展開する。

```csharp:main.py
def say_hello(word, *args)://argsにすべて入る
     print(word)//Hi
　　　for arg in args:
         print(arg)

t＝('Mike', 'Nancy')
say_hello('Hi', *t)//自分で*をつけることによってタプル化する。
```
+ キーワード引数の辞書化

```csharp:main.py
def menu(**kwargs): # キーとバリューが入る　{'entree': 'beef', 'drink': 'coffee'}
    print(kwargs)//{'entree': 'beef', 'drink': 'coffee'}
    for k , v in kwargs.items()://dict_items([('entree', 'beef'), ( 'drink': 'coffee'})])が返ってくる
        print(k, v)//entree beef
                   //drink coffee

menu(entree='beef', drink='coffee')
```
+ 自分で辞書を作る

```csharp:main.py
def menu(**kwargs): 
    print(kwargs)
    for k , v in kwargs.items()://dict_items([('entree', 'beef'), ( 'drink': 'coffee'})])が返ってくる
        print(k, v)

d = {
    'entree': 'beef',
    'drink':'ice coffee',
    'dessert':'ice'
    }
 //辞書で書いていて見やすい

menu(**d)//fanctionの引数に値を渡す際に、キーワード引数として展開される。
```
+ 位置引数、*args、**kwardgsまとめて処理

```csharp:main.py
def menu(food, *args, **kwargs)://**kwargsを第2引数に設定し、*argsを最後の引数にするとエラーになる。
    print(food)
    print(args)
    print(kwargs)

menu('beef', 'apple', 'banana', entree='beef', drink='juice')//**kwargsはキーとバリューが必要

//出力結果
beef
('apple', 'banana')
{'entree': 'beef', 'drink': 'juice'}
```
# Docstrings

+ ダブルクオート3つで行う。
+ `docstring`は、関数などの仕様（例えば、何をして何を戻り値とするのか、呼び出すのに必要なパラメーターは何かなど）をその利用者に対して説明するために、その定義に埋め込んだ形で記述する。
+ `__doc__属性`とは、関数（やクラス、モジュールなど）が持つ属性の一つで、その仕様を説明するdocstringを保持するもの

```csharp:main.py
example_func.__doc__//関数の説明を出力する。

```
# 関数内関数

+ `関数内関数`→その関数内でしか使わない関数は関数内関数として中に書く。

```csharp:main.py
def outer(a,b):
    def plus(c,d):
        return c + d
    r1 = plus(a,b)
    r2 = plus(b,a)
    print(r1 + r2)

outer(1,2)
```
# デコレーター

`デコレーター`→関数を受け取り、関数を戻り値とする関数のこと。
+ デコレータは関数やクラスの前後に特定の処理を追加できる機能
+ `gu`というデコレーターをnum関数に適用させるためには下記のように設定する。
+myloderデコレーターを作成する。

```csharp:main.py
@gu
def num():
    pass

num()

import datetime

def my_logger(func):
    def wrapper(*args, **keywords):
        # 前処理
        print(func'{func.__name__}の実行')
        print(func'開始: {datetime.datetime.now()}')

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

        # 後処理
        print(func'終了: {datetime.datetime.now()}')
        print(func'実行結果: {v}')

        return v
    return wrapper

@my_logger
def return_one():
    return 1

return_one()
# return_oneの実行
# 開始: 2021-02-16 09:31:40.616712
# 終了: 2021-02-16 09:31:40.616742
# 実行結果: 1
```
https://zenn.dev/ryo_kawamata/articles/learn_decorator_in_python
上記のサイトを参考にしました。ありがとうございます。

# ラムダ
+ `lambda 引数: 返り値`という形で書く。下記とおなじ。
+ def func(引数):
    return 返り値
https://aiacademy.jp/media/?p=1597
上記のサイトを参考にしました。ありがとうございます。


```csharp:main.py
l = ['Mon', 'Tue', 'Wed', 'Thu','fri', 'sat', 'Sun']

def change_words(words, func):# 第2引数は、ファンクションの引数を持ってくる。
    for word in words:
        print(func(word))# funcの定義にしたがって、wordを変える。

# def sample_func(word):# wordに文字列として入ってくる。
#     return word.capitalize()



sample_func = lambda word: word.capitalize()# lambdaは、returnを書かずに書ける。

change_words(l, sample_func)# 第1引数にリストを入れる。第2引数にオブジェクトを入れる。

```
下記のジェネラータからジェネレータ内包表記までまとめていたのですが、更新しないまま、画面遷移をしてしまい消えてしまったので、他の方が書いたQiitaの記事を参考にしました。ありがとうございます。

# ジェネレータ
イテレーターとジェネレーター
https://qiita.com/tomotaka_ito/items/35f3eb108f587022fa09

# リスト内包表記

```cshap:main.php
t= (1,2,3,4)
t2 = (5,6,7,8,9)

r = []
for i in t:
    if i % 2 == 0:
        r.append(i)

print(r)

r = [i for i in t if i % 2 == 0 ]
print(r)

r = []
for i in t:
    for j in t2:
        r.append(i*j)
print(r)

r = [i * j for i in t for j in t2]
print(r)
```

# 辞書内包表記

```cshap:main.php
w = ['apple', 'grape', 'orange']
f = ['Tue' , 'Wed', 'Thu']

d = {}
for x, y in zip(w,f):
    d[x] = xをキーに、yをバリューにして辞書にする。

print(d)

d ={x:y for x,y in zip(w,f)}
print(d)
```
# 集合内包表記
https://note.nkmk.me/python-set/　を参照しました。ありがとうございます。

```cshap:main.php
```
# 名前空間とスコープ


# 例外処理
https://note.nkmk.me/python-try-except-else-finally/　
を参照しました。ありがとうございます。
https://docs.python.org/ja/3/library/exceptions.html //例外エラー

# 独自例外の作成

+ `raise`を用いる
https://www.delftstack.com/ja/howto/python/python-custom-exception/
https://www.delftstack.com/ja/howto/python/manually-raise-exceptions-in-python/

```csharp:main.py　
class UppercaseError(Exception)://独自エラーを作成
    pass

def check():
    words = ['Apple', 'orange', 'banana']
    for word in words:
        if word.isupper():
            raise UppercaseError(word)//自分が作成したエラーで表示できる。

try:
    check()
except UppercaseError as exc:
    print('this is my fault. Go next')

```

# コマンドライン引数

`コマンドライン引数`→Pythonでプログラムを実行する際に指定する引数のことで、プログラムに引数の情報を渡す役割を持つ。

+ コマンドライン引数の渡し方
+　0番目はスクリプトのファイル名が渡されて、1番目以降は、コマンドライン引数が設定される。

```csharp:main.py
Python main.py 引数1 引数2 引数3

import sys

args = sys.argv

print(args)
print("第1引数：" + args[1])//0番目は実行ファイルがあるため、1番目から書く。
print("第2引数：" + args[2])
print("第3引数：" + args[3])

//下記コマンドで実行
python test.py a b c

//実行結果['test.py', 'a', 'b', 'c']
第1引数：a
第2引数：b
第3引数：c
```
# import文とAs

他のファイルから読み込む（lesson_packageディレクトリ内のutils.py）

```csharp:lesson_package/utils.py
def say_hello(word)
    print(word + '!') * 3
```
上記のコードをmain.pyに読み込む

```csharp:main.py
import lesson_package.utils.py//ディレクトリ/ファイル名→ドットでモジュールまでたどりつく。
r = lesson_package.utils.say_hello('hello')

print(r)//hello! hello! hello!
```
違う読み込み方

```csharp:main.py
form lesson_package import utils//読み込みたいファイル名の前にimportを書く。フォルダが増えればドットで繋いでいく

r = utils.say_hello('hello')//ディレトリを省略できる。


//ファンクションだけをimportすることもできる
form lesson_package import say_hello//どこのファンクションかわからないため、この書き方は好まれていない。
```
フルパスで読み込むか、fromで読み込むか

# 絶対パスと相対パス

```csharp:main.py
//相対パスの書き方
from ..tools import utils//ドット2つで一個上に上がる。あまりおすすめされていない。
```
# アスタリスクとインポートと__init__/pyと__all__の意味

+ talkディレクトリ内のanimal.pyとhuman.py

```csharp:animal.py
from lesson_package.tools import utils
def sing():
    return '####nknesgr'

def cry():
    return utils.say_hello('#knksnlknlknsklnskf')

```

```csharp:human.py
from lesson_package.tools import utils
def sing():
    return 'sing'

def cry():
    return utils.say_hello('cry')
```

+ human.pyとanimal.pyを読み込む

```csharp:main.py
from lesson_package.talk import human
from lesson_package.talk import animal

print(animal.sing())
print(animal.cry())
# print(human.sing())
# print(human.cry())

```
`アスタリスク`→__init__ファイルが読み込まれる。

```csharp:main.py
form lesson_package.talk import *//__init__.pyファイル内で__all__
```
+ アスタリスクにより、__init__ファイル内の__all__ = ['']の[]内を読み込む

```csharp:__init__.py
__all__ = ['animal', 'human']
```
# ImportErrorの使い所

```csharp:main.py
try:
    from lesson_package import utils #　古いパッケージ
except ImportError:
    from lesson_package.tools import utils # 新しいパッケージ
utils.say_hello('word')
```
# 組み込み関数

+ 今までのprintやnext(ジェネレータ)は組み込み関数で`builtins`に入っている。

```main.py
import builtins 
builtins.print
```
# sorted(組み込み関数)

```main.py
ranking = {
    'A':100,
    'B':85,
    'C':95
}

# ranking.get('A')//バリューで比べる
print(sorted(ranking, key=ranking.get, reverse = True))//第3引数にkeyの並べ替え処理を書く。
```
# python標準ライブラリ

https://docs.python.org/ja/3/library/index.html

例→defaultdict

```main.py
t = "nknknohsoghs@ghsuhsut"
d = {}
for i in t:
    if i not in d://すべて最初は個数0にしないと始まらない。
        d[i] = 0
    d[i] += 1

print(d)

//setdefault
d = {}
for i in t:
    d.setdefault(i, 0)#キーがなかったら0を入れる処理
    d[i] += 1

print(d)

print(d['f'])//→fの個数を表示


//defaultdict
from collections import defaultdict

d = defaultdict(int)

for i in t:
    d[i] += 1

print(d)

print(d['n'])
```
# サードパーティのパッケージ

# importする際の記述の注意

❶1行ずるアルファベット順に並べる
❷標準ライブラリとサードパーティの間は1行空ける。

```main.py
import collections
import os
import sys

import termcolor

import lesson_package

import config //ローカルのファイル
```