Python基本文法note（1）

Pythonを勉強しています。
メモとして作成しましたので、多少の誤字脱字があるかもしれません。


#変数の宣言

type関数を使うと何の型なのかがわかる

~~~python

num = 1
name = 'maki'
is_ok = True

print(num,type(num))
print(name,type(name))
print(is_ok,type(is_ok))

#出力結果
#(1, <type 'int'>)
#('maki', <type 'str'>)
#(True, <type 'bool'>)

#pythonはint型,str型を識別してくれる
#boolean型とは、true(トゥルー) またfalse(フォールス)のどちらかのデータが必ず入ることが決まっているデータ型。



#文字列のインデックスとスライス
#文字列の最初だけを出力したい場合、[]で指定する0始まりで一番最後の文字を出力した場合[-1]とする
word = 'python'
print(word[0])
print(word[-1])

#スライス機能
print(word[0:2])


#出力結果
p
n
py


#len関数(レングス)インデックスの長さを求められる
n = len(word)
print(n)

#出力結果
6

#文字メソッド

s = 'My name is Mike.Hi Mike '
print(s)

#s.startswithは初めの文字を検索してくれるメソッド
is_start = s.startswith('My')
print(is_start)
is_start = s.startswith('x')
print(is_start)

#出力結果
True
False

#文字列の代入(ターミナル上でテストした記述)
#{}の中にフォーマットで代入した値が入る
>>>'a is {}'.format('a')
'a is a'

>>> 'a is {}{}{}'.format('a','b','c')
'a is abc'
#インデックスを指定できる
>>> 'a is {0}{1}{2}'.format('a','b','c')
'a is abc'
>>> 'a is {2}{1}{0}'.format('a','b','c')
'a is cba'



>>> 'my name is {0}{1}'.format('shunsuke','kaneko')
'my name is shunsukekaneko'

#文字を代入できる
>>> 'My name is {name}{family}. Watashiha ha {family} {name}'.format(name='shunsuke',family='kaneko')
'My name is shunsukekaneko. Watashiha ha kaneko shunsuke'

~~~

###リスト型


~~~python

>>> l = [1, 23, 42, 23, 22, 64]
>>> l
[1, 23, 42, 23, 22, 64]

#インデックスで番号指定できる
>>> l[0]
1
>>> l[2]
42
#最後から数えて1番目の値が出力される
>>> l[-1]
64
#0~2番目まで出力したい時
>>> l[0:2]
[1, 23]
#2~5番目まで出力したい時
>>> l[2:5]
[42, 23, 22]
#初めから最後まで省略すると全てのリストが返ってくる
>>> l[:]
[1, 23, 42, 23, 22, 64]
#「length」関数を使って配列の中にいくつデータが入っているか
>>> len(l)
6
#typeで型を調べる
>>> type(l)
<type 'list'>
#文字列からリストに変換する
>>> list('kjshfkf')
['k', 'j', 's', 'h', 'f', 'k', 'f']
#例えばlの１００番目を指定するとエラーが返ってくる
>>> l[100]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range


>>> n = [1,2,3,4,5,6,7,8,9,10]
>>> n
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> 
#２つ飛ばして出力したい場合
>>> n[::2]
[1, 3, 5, 7, 9]
#後ろから摘出したい場合
>>> n[::-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

##ネスト化した配列
>>> a = ['a','b','c']
>>> n = [1,2,3]
>>> x = [a,n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]

#ネスト化した配列を出力してみる
>>> x[0]
['a', 'b', 'c']
#1にすると後ろのリストが出力される
>>> x[1]
[1, 2, 3]

#'b'を出力したい時
>>> X[0][1]
'b'

~~~

###リストの操作

~~~python

#リストの操作
>>> s = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> s
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> s[0]
'a'
#s[0]番目の'a'を書き換える(配列の場合は書き換え可能)
>>> s[0] = 'x'
>>> s
['x', 'b', 'c', 'd', 'e', 'f', 'g']
#スライスで入っているデータを書き換える
>>> s[2:5]
['c', 'd', 'e']
#配列をそのまま用意して代入する
>>> s[2:5] = ['C', 'D', 'E']
>>> s
['x', 'b', 'C', 'D', 'E', 'f', 'g']

#2~5番目を空にしたい場合、空の配列を用意する
>>> s[2:5] = []
>>> s
['x', 'b', 'f', 'g']

#[:]で全体を指定して空を代入すると空が表示される
>>> s[:] = []
>>> s
[]

#リストのメソッドを使って操作する
>>> n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> n
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#最後にデータを付け加えたい場合
>>> n.append(100)
>>> n
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100]
#一番初めに入れたい場合
>>> n.insert(0,200)
>>> n
[200, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100]
#一番最後を取り除きたい場合
>>> n.pop()
100
>>> n
[200, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#一番初めを取り出したい場合にはインデックスを指定する
>>> n.pop(0)
200
>>> n
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#削除したい場合
>>> del n[0]
>>> n
[2, 3, 4, 5, 6, 7, 8, 9, 10]
#delは強力で以下文を実行するとnが定義されていないことになる（気をつけて使わないといけない）
>>> del n
>>> n
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined
#removeメソッドを使って消す
>>> n = [1, 3, 3, 2, 4]
>>> n
[1, 3, 3, 2, 4]
#仮に２を消す
>>> n.remove(2)
>>> n
[1, 3, 3, 4]
#リストにないものを削除しようとするとエラーが出る
>>> n.remove(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
#リストの結合
>>> a = [1, 2, 3, 4, 5]
>>> b = [6, 7, 8, 9, 10]
>>> a
[1, 2, 3, 4, 5]
>>> b
[6, 7, 8, 9, 10]
#新しいリストを作って結合する
>>> x = a + b 
>>> x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#aのデータにbのデータを付け加えたい場合
>>> a += b
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#メソッドを使って結合したい場合
>>> x = [1 ,2, 3, 4, 5]
>>> y = [6, 7, 8, 9, 10]
>>> x.extend(y)
>>> x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
~~~

##リストのメソッド

~~~python
#()の中の数字がどのインデックスにあるか
r = [1, 2, 3, 4, 5, 5, 1, 2, 3]
print(r.index(3))
>>>2
#インデックスの３番目から3を探して欲しい場合
>>> print(r.index(3,3))
8
#3が何個あるかカウントしたい場合
>>> print(r.count(3))
2
#リスト(r)の中に5があった場合existを出力する
if 5 in r:
  print('exist')
>>>exist
#ソートしたい場合（ソートとはデータを一定の基準に従って並べかえること）
r.sort()
print(r)
>>>[1, 1, 2, 2, 3, 3, 4, 5, 5]
#逆にソートしたい場合
r.sort(reverse=True)
print(r)
>>>[5, 5, 4, 3, 3, 2, 2, 1, 1]
#別のメソッドを使って元に戻す
r.reverse()
print(r)
>>>[1, 1, 2, 2, 3, 3, 4, 5, 5]
#ある規則に基づいて文字列を分割するためのメソッド
s = 'My name is Mike'
to_split = s.split(' ')
print(to_split)
>>>['My', 'name', 'is', 'Mike']

#存在しない文字列で実行するとただリストに入る（区別してくれるわけではない）
to_split = s.split('!!!')
print(to_split)
>>>['My name is Mike']

#元に戻す場合(joinメソッドは結合してくださいというメソッド)
x = ' '.join(to_split)
print(x)
>>>My name is Mike
#わかりやすく別の文字でやる
x = '!!!!!!!!!!!!!!'.join(to_split)
print(x)
>>>My!!!!!!!!!!!!!!name!!!!!!!!!!!!!!is!!!!!!!!!!!!!!Mike

~~~

##リストのコピー
整数や数字の場合は値渡し
リストや辞書の場合は参照渡し


~~~python

#jにもiにも書き変わってしまう
i = [1, 2, 3, 4, 5]
j = i
j[0] = 100
print('j =', j)
print('i =', i)
>>>('j =', [100, 2, 3, 4, 5])
>>>('i =', [100, 2, 3, 4, 5])

#copyを使う
x = [1, 2, 3, 4, 5]
y = x.copy()
y[0] = 100
print('y=', y)
print('x=', x)
>>>('y =', [1, 2, 3, 4, 5])
>>>('x =', [100, 2, 3, 4, 5])
~~~

#リストの使い所

例えばタクシードライバーがある目的地まで乗客を連れて行くといったゲームの場合
座席の数をリストで表現する

~~~python
#誰も乗っていないので空のリストにする
>>> seat = []
#最大で5人乗りにする
>>> min = 0
>>> max = 5
#シートの数を「length関数」を使って出す
>>> min <= len(seat) < max
True
#乗れるかどうか判定する
>>> min <= len(seat) < max
True
#人を追加乗ってくる
>>> seat.append('p')
>>> min <= len(seat) < max
True
>>> len(seat)
1
#人を追加して行く
>>> seat.append('p')
>>> seat.append('p')
>>> min <= len(seat) < max
True
>>> seat.append('p')
>>> seat.append('p')
#判定をすると乗れない
>>> min <= len(seat) < max
False
#人数を調べると5人乗っている
>>> len(seat)
5
#人が降りて行った
>>> seat.pop(0)
'p'
>>> min <= len(seat) < max
True
#現在４人乗っている
>>> len(seat)
4
~~~

#タプル型
リストとよく似ている

~~~python
#タプル型の場合パレンティスの（）括弧で指定する
>>> t = (1, 2, 3, 4, 1, 2)
>>> t
(1, 2, 3, 4, 1, 2)
>>> type(t)
<type 'tuple'>

#タプルは新しく値を代入することをサポートしていない
>>> t[0] = 100
#リストの場合にインデックスを指定して代入できたがエラーが返ってくる
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> 
#リストの時同様にメソッドを使うことができる
>>> t[0]
1
>>> t[-1]
2
>>> t[2:5]
(3, 4, 1)
>>> t.index(1)
0
>>> t.index(1,1)
4
>>> t.count(1)
2
#メソッド自体そこまで用意されていないので、値を入れたら読み込むような形のケースに使用することが多い


#タプルにリストを入れることはできる
>>> t = ([1, 2, 3 ], [4, 5, 6])
>>> t
([1, 2, 3], [4, 5, 6])
#タプルの値を書き換えようとするとエラーが起こる
>>> t[0] = [1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
#ただしインデックスを指定すると書き換えられる
>>> t[0][0] = 2
>>> t
([2, 2, 3], [4, 5, 6])
#タプルの宣言
>>> t = 1,2,3
>>> t
(1, 2, 3)
#パレンティスの()括弧でなくても宣言できる
>>> type(t)
<type 'tuple'>
#カンマなしだとint型になる
>>> t = 1
>>> type(t)
<type 'int'>
#カンマありだとタプル型になる（タプルはカンマをつける）
>>> t = 1,
>>> type(t)
<type 'tuple'>
~~~
##タプルのアンパッキング

~~~python
#変数の入れ替え
>>> a = 100
>>> b = 200
>>> print(a, b)
(100, 200)
>>> a, b = b ,a 
>>> print(a, b)
(200, 100)

~~~

#タプルの使い所
質問をユーザーに投げかけて、その選択肢の中から２つ回答を選ぶアプリケーション
中身を書き換えられることがない

~~~python
#回答の選択肢
>>> chose_from_two = ('A', 'B', 'C')
#回答のリストを作成
>>> answer = []
>>> answer.append('A')
>>> answer.append('C')
>>> 
>>> print(chose_from_two)
('A', 'B', 'C')
>>> print(answer)
['A', 'C']
>>> 
~~~


#辞書型

~~~python
#基本文法
>>> d = {'x': 10, 'y':20}
>>> d
{'y': 20, 'x': 10}
>>> type(d)
<type 'dict'>
>>> 
#値を出力したい場合
>>> d['x']
10
>>> d['y']
20
#値を代入したい場合
>>> d['x'] = 100
>>> d
{'y': 20, 'x': 100}
#文字列の場合
>>> d['x'] = 'xxxx'
>>> d
{'y': 20, 'x': 'xxxx'}
#新しく追加する場合
>>> d['z'] = 100
#キーとバリューが追加されている
>>> d
{'y': 20, 'x': 'xxxx', 'z': 100}
#キーが文字列以外でも入る
>>> d[1] = 1000000
>>> d
{'y': 20, 'x': 'xxxx', 'z': 100, 1: 1000000}
#別の生成の仕方
>>> dict(a=10, b=20)
{'a': 10, 'b': 20}
~~~

#辞書型メソッド


~~~python
#代表的なメソッド
>>> d = {'x': 10, 'y':20}
>>> d
{'y': 20, 'x': 10}
#キーだけ取り出したい場合
>>> d.keys()
['y', 'x']
#バリューだけ取り出したい場合
>>> d.values()
[20, 10]
#辞書をアップデートしたい場合
>>> d = {'x': 10, 'y':20}
>>> d2 = {'x':1000, 'j':500}
>>> d
{'y': 20, 'x': 10}
>>> d2
{'y': 500, 'j': 1000}
#d2をdに上書きしてくださいという記述
>>> d.update(d2)
>>> d
{'y': 20, 'x': 1000, 'j': 500}
#メソッドを使って呼び出したい場合
>>> d.get('x')
1000
#辞書にないキーを指定した場合
>>> d['a']
#エラーが返ってくる
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'a'
#取り出したい場合（削除）
>>> d
{'y': 20, 'x': 1000, 'j': 500}
#popメソッドを使う
>>> d.pop('x')
1000
>>> d
{'y': 20, 'j': 500}
#delメソッドでも消える
>>> del d['y']
>>> d
{'j': 500}
#delで辞書ごと消すとエラーが返ってくる
>>> del d
>>> d
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'd' is not defined
#clearメソッドを使えば空の辞書を残しておける
>>> d.clear()
>>> d
{}
#'y'のキーがあるが探すメソッド
>>> 'y' in d
True

~~~

#辞書型のコピー

~~~python
#リスト同様に参照渡しになる
x = {'a':1}
y = x
y['a'] = 1000
print(x)
print(y)
>>>{'a': 1000}
>>>{'a': 1000}

#copyメソッドを使う
x = {'a':1}
y = x.copy()
y['a'] = 1000
print(x)
print(y)
>>>{'a': 1}
>>>{'a': 1000}
~~~

##辞書型の使い所
オンラインサイトに果物を売るサイトがある

~~~python
#リストより辞書の方が検索が早い
fruits = {
  'apple':100,
  'banana':200,
  'orenge':100,
}
print(fruits['apple'])
>>>100


~~~

#集合型

~~~python
#重複しているものはなく全てユニークとして出力される
>>> a = {1, 2, 3, 3, 4, 5, 5, 6}
>>> a
#辞書型が返ってきていない
set([1, 2, 3, 4, 5, 6])
aに入っているものからbを取り除いた
>>> a - b
set([1, 4, 5])
>>> b - a
set([7])
#aにもありbにもあるもの
>>> a & b
set([2, 3, 6])
#aまたはbにあるもの
>>> a | b
set([1, 2, 3, 4, 5, 6, 7])
#aかbにあり重複していないもの
>>> a ^ b
set([1, 4, 5, 7])

~~~

#集合のメソッド

~~~python
>>> s = {1, 2, 3, 4, 5}
>>> s
set([1, 2, 3, 4, 5])
#集合には並びは存在しない
>>> s[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing
#追加するメソッドはある
>>> s.add(6)
>>> s
set([1, 2, 3, 4, 5, 6])
#消す場合はremoveメソッド
>>> s.remove(6)
>>> s
set([1, 2, 3, 4, 5])
#clearメソッドを使えば全て消すことができる
>>> s.clear()
>>> s
set([])
~~~

#集合の使い所
共通点を探し出す時に使える


~~~python
#友達を宣言する
my_friends = {'A', 'C','D'}
A_friends = {'B', 'D', 'E', 'F'}
#共通の友達は誰か出力する
print(my_friends & A_friends)
>>>set(['D'])

#購入したリストから購入したものだけ摘出する
f = {'apple', 'banana', 'apple', 'banana'}
#リストから集合に変換する
kind = set(f)
print(kind)
>>>set(['apple', 'banana'])
~~~

#コメントの書き方

~~~python
# コメント
"""
複数のコメントを書く場合はこちら
"""

#一行が長くなる場合はバックスラッシュを使う（option + ¥）
x = 1 + 1 + 1 + 1 + 1 + 1 \
    + 1 + 1 + 1 + 1 + 1 + 1
print(x)
#パレンティスの（）でも大丈夫
x = (1 + 1 + 1 + 1 + 1 + 1 
    + 1 + 1 + 1 + 1 + 1 + 1)
print(x)
>>>12

~~~

#if文
・上から順に処理が行われて、引っかかったところが実行される


~~~python
x = -10
#if文を書く場合はインデントがスペース4つ
if x < 10:
    print('nagative')
#elseを使う
x = 10
if x < 10:
    print('nagative')
else:
    print('positive')
>>>positive
#elseifの略が elif
x = 0
if x < 0:
    print('nagative')
elif x == 0:
    print('zero')
else:
    print('positive')
>>>zero
#他のif文の例
a = 5
b = 10
#インデントに気をつける
if a > 0:
    print('a is positive')
    if b > 0:
        print('b is positive')

~~~

#比較演算子と理論演算子

~~~python

a = 2
b = 2

# a が b と等しい
a == b

# a が b と異なる
a != b

# a が b よりも小さい
a < b 

# a が b よりも大きい
a > b

# a が b 以下である
a <= b

# a が b 以上である
a >= b

# a も b も真であれば真
a > 0 and b > 0

# a または b が真であれば真
a > 0 or b > 0

~~~

In と　Notの使い所


~~~python
y = [1, 2, 3]
x = 1
#リストの中にあるかのメソッド
if x in y:
    print('in')
>>>in
if 100 not in y:
    print('not in')
>>>not in

#Boolean型を否定する場合Notを使う
is_ok = True
if not is_ok:
    print('hello)

~~~

#値が入っていない判定をするテクニック

~~~python
#python場合値が入っていない場合はFalseが返ってくる
is_ok = [1, 2, 3, 4]
#False, 0, 0.0, {}, (), set() 

if is_ok:
    print('OK!')
else:
    print('NO')
#NOと出る
~~~

Noneを判定する場合
pythonでは何も値が入っていない場合にはNoneと表示される
isはNoneを判定するときに使う

~~~python
is_empty = None
print(is_empty)
>>>None

#この変数はNoneですかという使い方
if is_empty is None:
    print('None!!!!')
>>>None!!!!

#真と真なのでTrueが返ってくる
print(1 == True)
>>>True
#オブジェクト同士が同じものであるか
print(1 is True)
>>>False
print(True is True)
>>>True

~~~

#while文とcontinue文とbreak文

~~~python
#whilke文
count = 0

while count < 5:
    print(count)
    count += 1

>>>0
>>>1
>>>2
>>>3
>>>4

#break文
count = 0
while True:
    if count >= 5:
        break
    print(count)
    count += 1

>>>0
>>>1
>>>2
>>>3
>>>4

#continue文（次のループにいってくださいという意味）

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

    if count == 2:
        count += 1
        continue
      
    print(count)
    count += 1

>>>0
>>>1
>>>3
>>>4

~~~

#while else文

~~~python
#while文の中でbreakを使うとelse文が実行されずに出力される
count = 0

while count < 5:
    if count == 1:
        break
    print(count)
        
    count += 1
else:
    print('done')

>>>0
~~~

input関数

~~~python
#str型の場合
while True:
    word = input('Enter:')
    if word == 'ok':
        break
    print('next')

#int型にしたい場合
while True:
    word = input('Enter:')
    num = int(word)
    if num == 100:
        break
    print('next')
~~~


for文とbreak文とcontinue文
while文と同様にbreakとcontinueが使える
elseもwhile文と同じ使い方

~~~python

some_list = [1, 2, 3, 4, 5]

for i in some_list:
    print(i)
>>>1
>>>2
>>>3
>>>4
>>>5
    
~~~

#renge関数

~~~python
#
for i in range(5):
  print(i)
>>>0
>>>1
>>>2
>>>3
>>>4

#1から5までを2つ飛ばしで出力してくださいという意味
for i in range(1, 5, 2):
  print(i)
>>>1
>>>3

#インデックスがいらない場合には_(アンダーバー)で書いても良い
for _ in range(1, 5, 2):
  print('hello')
>>>hello
>>>hello

~~~

enumerate関数
インデックスの番号が知りたい場合

~~~python
for i, fruit in enumerate(['apple', 'banana', 'orange']):
    print(i, fruit)

>>>(0, 'apple')
>>>(1, 'banana')
>>>(2, 'orange')

~~~

zip関数
インデックスを指定しなくてもfor文で出力できる

~~~python
days   = ['Mon', 'Tue', 'wed']
fruits = ['apple', 'banana', 'orenge']
drinks = ['coffee', 'tea', 'beer']

for day, fruit, drink in zip(days, fruits, days):
    print(day, fruit, drink)

>>>('Mon', 'apple', 'Mon')
>>>('Tue', 'banana', 'Tue')
>>>('wed', 'orenge', 'wed')

~~~

#辞書をfor文で処理する
itemメソッドを使う

~~~python

d = {'x':100, 'y':200}

for k ,v in d.items():
    print(k, '*' ,v)
>>>('y', '*', 200)
>>>('x', '*', 100)

#ちなみでデバックしてみる
print(d.items())
#タプルで入っている
>>>[('y', 200), ('x', 100)]
~~~

#関数定義

~~~python
#関数の定義
def say_something():
    print('hi')

say_something()
>>hi

#戻り値
def say_something():
    s ='hi'
    return s

resule = say_something()
print(resule)
>>>hi

#引数
def what_is_this(color):
    if color == 'red':
        return 'tomato'
    elif color == 'green':
        return 'green pepper'
    else:
        return "I don't know"

result = what_is_this('yellow')
print(result)

>>>I don't know
~~~

#位置引数とキーワード引数、デフォルト引数

~~~python
#関数宣言して引数に渡す
def menu(entree, drink, dessrt):
    print(entree)
    print(drink)
    print(dessrt)

menu('beef', 'cora', 'ice')
>>>beef
>>>cora
>>>ice

#キーワード引数
def menu(entree, drink, dessrt):
    print('entree = ',entree)
    print('drink = ', drink)
    print('dessrt = ', dessrt )

menu(entree='beef', drink='cora', dessrt='ice')

>>>('entree = ', 'beef')
>>>('drink = ', 'cora')
>>>('dessrt = ', 'ice')

#デフォルト引数
def menu(entree='beef', drink='wine', dessrt='ice'):
    print('entree = ',entree)
    print('drink = ', drink)
    print('dessrt = ', dessrt )

menu()
>>>('entree = ', 'beef')
>>>('drink = ', 'wine')
>>>('dessrt = ', 'ice')

#関数を呼び出す時に引数に値を渡してみる
def menu(entree='beef', drink='wine', dessrt='ice'):
    print('entree = ',entree)
    print('drink = ', drink)
    print('dessrt = ', dessrt )

menu(entree='chicken')
#位置引数とデフォルト引数を併用して使える
>>>('entree = ', 'chicken')
>>>('drink = ', 'wine')
>>>('dessrt = ', 'ice')

~~~

#デフォルト引数で気をつけること

~~~python
#デフォルト引数にリストや辞書を用意してしまうと初めに作ったものに追加してしまう
def test_func(x, l=[]):
    l.append(x)
    return l

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

r = test_func(100)
print(r)
>>>[100, 100]

#解決方法
def test_func(x, l=None):
    #Noneの時だけ初期化する記述をする
    if l is None:
        l = []
    l.append(x)
    return l

r = test_func(100)
print(r)
>>>[100]
r = test_func(100)
print(r)
>>>[100]
~~~


#位置引数のタプル化

~~~python
#*argsで引数をまとめてタプル化してくれる
def say_something(word, *args):
    print('word =', word)
    for arg in args:
        print(arg)

say_something('Mike', 'Mika', 'Nance')
>>>('word =', 'Mike')
>>>Mika
>>>Nance

~~~

#キーワード引数の辞書化

~~~python
#簡単なプログラム
def menu(entree='beef', drink='wine'):
    print(entree,drink)

menu(entree='beef', drink='coffce')
>>>('beef', 'coffce')

#どんどん追加したい場合
def menu(**kwargs):
    #キーワードアーギュメントの略
    print(kwargs)

menu(entree='beef', drink='coffee')
#辞書の型で出力される
>>>{'entree': 'beef', 'drink': 'coffee'}

#別のやり方
def menu(**kwargs):
    for k, v in kwargs.items():
        print(k, v)
d = {
    'entree' : 'beef',
    'drink'  : 'ice coffee',
    'dessert': 'ice'
}
#辞書に**を付けて渡してやる
menu(**d)
>>>('dessert', 'ice')
>>>('entree', 'beef')
>>>('drink', 'ice coffee')

#引数の種類をまとめて使うこともできる（順序が大切）
def menu(food, *args, **kwargs):
    print(food)
    print(args)
    print(kwargs)

menu('banana', 'apple', 'orange', entree='beef',drink='coffee')
>>>banana
>>>('apple', 'orange')
>>>{'entree': 'beef', 'drink': 'coffee'}

~~~

#Docstrings
pythonではコメントをfunction内に書く

~~~python
def example_func(param1, param2):
    """
    コメントコメント
    コメントコメント
    コメントコメント
    コメントコメント
    コメントコメント

    """

    print(param1)
    print(param2)
    return True
#__doc__でコメント内が見れる
print(example_func.__doc__)
#helpでも良い
help(example_func.__doc__)

~~~

#関数内関数

~~~python
#インナー関数とも言う
def outer(a, b):
    def plus(c, d):
        return c + d
    
    r = plus(a, b)
    print(r)

outer(1, 2)
>>>3
~~~

#クロージャー
初めに設定した引数を元にのちのち用途によって使い分けたい場合

~~~python
#関数内関数を呼び出しても実行されない
def outer(a, b):
    def inner():
        return a + b
    return inner

print(outer(1, 2))
>>><function inner at 0x10ebec2a8>
#fに変数でいれて
def outer(a, b):
    def inner():
        return a + b
    return inner

f = outer(1 , 2)
#rに返り値をいれると実行される
r = f()
print(r)

>>>3

~~~

#デコレーター
＠関数名で書く
関数を実行したい時に、@関数名で呼ばれる


~~~python
#これだとわかりづらい
def print_into(func):
    def wapper(*args, **kwags):
        print('start')
        result = func(*args, **kwags)
        print('end')
        return result
    return wapper

def add_num(a, b):
    return a + b

f = print_into(add_num)
r = f(10, 20)
print(r)
>>>start
>>>end
>>>30

#デコレーターの書き方
def print_into(func):
# *argsは仮の引数　**kwagsは仮の辞書
    def wapper(*args, **kwrags):
        print('start')
        result = func(*args, **kwrags)
        print('end')
        return result
    return wapper

@print_into
def add_num(a, b):
    return a + b

r = add_num(10, 20)
print(r)
>>>start
>>>end
>>>30
~~~

#ラムダ


~~~python
#ラムダを使わない場合
l = ['Mon', 'tue', 'Wed', 'Thu', 'fri', 'sat', 'Sun']

def change_words(words, func):
    for word in words:
        print(func(word))

def sample_func(word):
    return word.capitalize()

change_words(l, sample_func)

>>>Mon
>>>Tue
>>>Wed
>>>Thu
>>>Fri
>>>Sat
>>>Sun

#ラムダを使った場合
l = ['Mon', 'tue', 'Wed', 'Thu', 'fri', 'sat', 'Sun']

def change_words(words, func):
    for word in words:
        print(func(word))

change_words(l, lambda word: word.capitalize())

>>>Mon
>>>Tue
>>>Wed
>>>Thu
>>>Fri
>>>Sat
>>>Sun
~~~

#ジェネレーター
いち要素を取り出して生成する

~~~python
#普通のfor文
l = ['Good morning', 'Good afternoon', 'Good night']

for i in l:
    print(i)

print("##############")
#ジェネレーターを使った場合
def greeting():
    yield 'Good morning'
    yield 'Good afternoon'
    yield 'Good night'

g = greeting()
print(next(g))

print('************')

print(next(g))

print('************')

print(next(g))
~~~

#リスト内包表記

~~~python
t = (1, 2, 3, 4, 5)
#リスト内包表記を使わない場合
r = []
for i in t:
    r.append(i)

print(r)
>>>[1, 2, 3, 4, 5]

#リスト内包表記を使った場合
r = [i for i in t]
print(r)
>>>[1, 2, 3, 4, 5]

#リスト内のfor表記で書けるが以下文以上に記述してしまうとわかりづらくなる
t = (1, 2, 3, 4, 5)

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)

>>>[2, 4]
>>>[2, 4]

~~~

#辞書包括表記

~~~python
w = ['mon', 'tue', 'wed']
f = ['coffee', 'milk', 'water']

#辞書包括表記なし
d = {}
for x, y in zip(w, f):
    d[x] = y

print(d)
>>>{'wed': 'water', 'mon': 'coffee', 'tue': 'milk'}

#辞書内包括表記
d = {x: y for x, y in zip(w, f)}
print(d)

>>>{'wed': 'water', 'mon': 'coffee', 'tue': 'milk'}
~~~

集合内包表記
(リストとほとんど一緒)

~~~python
#集合内包表記なし
s = set()

for i in range(10):
    if i % 2 == 0:
        s.add(i)

print(s)
>>>set([0, 8, 2, 4, 6])

#集合内包表記した場合
s = {i for i in range(10) if i % 2 == 0}
print(s)
>>>set([0, 8, 2, 4, 6])

~~~

#ジェネレーター内包表記

~~~python
#通常のジェネレーター
def g():
    for i in range(10):
        yield i

g = g()
#タイプを出力してみる
print(type(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

>>><type 'generator'>
>>>0
>>>1
>>>2
>>>3

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

print(next(g))
print(next(g))
print(next(g))

>>>0
>>>1
>>>2

#タプルにする場合
g = tuple(i for i in range(10))

~~~

#名前空間とスコープ

~~~python
#グローバル変数を出力できる
animal = 'cat'

def f():
#関数内でローカル変数に値を宣言する前にprintするとエラーがおこる
    print(animal)
    animal = 'dog'
    print('after',animal)

f()

>>>UnboundLocalError: local variable 'animal' referenced before assignment

#関数内で変数を書き換えたい場合
animal = 'cat'

def f():
    global animal
    animal = 'dog'
    print('after',animal)

f()

>>>('after', 'dog')

~~~

#例外処理

~~~python
l = [1, 2, 3]
i = 5
#エラーをキャッチして次のコードを実行する
try:
    l[i]
except:
    print("Don't worry")
>>>"Don't worry"

#Indexエラーの場合は飛ばして実行する場合
try:
    l[i]
except IndexError as ex:
    print("Don't worry: {}".format(ex))
>>>"Don't worry: list index out of range"

#try exceptでいろんなエラーを飛ばして実行できる
try:
    l[i]
except IndexError as ex:
    print("Don't worry: {}".format(ex))
except NameError as ex:
    print(ex)
#この記述があまりよくない
except Exception as ex:
    print(ex)
#この記述で必ず最後に実行される
finally:
    print('clean up')
>>>"Don't worry: list index out of range"
>>>clean up

#elseを記述し、こちらのエラーにかからずプログラムが実行された場合Doneを表示する
try:
    l[0]
except IndexError as ex:
    print("Don't worry: {}".format(ex))
except NameError as ex:
    print(ex)
except Exception as ex:
    print(ex)
else:
    print('Done')
finally:
    print('clean up')

>>>Done
>>>clean up

~~~

#独自例外の作成

~~~python
#自分で例外のエラーを作成する
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')
>>>This is my fault. Go next
~~~

##参考
Python 3入門 + 応用 +アメリカのシリコンバレー流コードスタイルを学び、実践的なアプリ開発の準備をする
https://www.udemy.com/course/python-beginner/?couponCode=SPECIALOFFER