Python始めました。（その２）

　前回の続きになります。
　[Python始めました。(その1)] (https://qiita.com/K-Ohgata/items/4a79f0e618590c3b5116)
　相変わらずコードばかりで読みづらいですが、ご容赦ください...。

# if文
　pythonはインデントでif文などの範囲(ブロック)を判別する。

```python:sample.py
fruits = ['apple', 'orange', 'grape', 'peach']
if 'apple' in fruits:
    print('apple is.')
    if 'orange' in fruits:
        print('orange is too.')
else:
    print('apple is not.')
print('I want to eat apple.')

if fruits:   # 値ある場合はTrueとして処理される
    print(fruits[0])



color='yellow'
if color=='red':
    print('color is red.')
elif color=='blue':   # 上の条件式に当てはまらなかった場合の条件式。else if。
    print('color is blue.')
else:
    print('color is neither red nor blue.')



nums=[1,2,3,4,5]
if 1 in nums and 2 in nums:
    print('nums have 1 and 2')
if 1 in nums or 100 in nums:
    print('nums have 1 or 100')
if not 200 in nums:
    print('nums don\'t have 200')
```

# for文
```python:sample.py
fruits = ['apple', 'orange', 'grape', 'peach']
for fluit in fruits:    # JavascriptのforEachみたい
    print(fruit)
    for char in fluit:
      print(char)



member = {'guitar': 'Sato', 'base': 'Kato'}
for part in member:    # partにはkey名が入る
    name = member[part]
    message = '{0} is {1}'.format(part, name)
    print(message)

for name in member.values():
    print(name)

for key, value in member.items():
    message = '{0} is {1}'.format(key, value)
    print(message)



for i in range(100):    # 0~99
    print(i)

for i in range(1,101):    # 1~100
    print(i)

for i in range(1,101,2):    # 1~100で2つ置き
    print(i)



# indexと要素どっちも取得したい時、enumerate()使う
for index, fluit in enumerate(fluits):
    message = 'No.{0} is {1}'.format(index, fluit)
    print(message)



# 2つのシーケンス(listなど)を並列で処理するzip()
# 短い方のシーケンスの要素数分しか処理しないので注意
fluits = ['apple', 'orange', 'grape', 'peach']
nums = [1, 2, 3, 4]
for fluit,num in zip(fluits,nums):
    print(num,fluit)
```

### FizzBuzz問題
```python:fizzbuzz.py
'''
Fizz Buzz
1からnまでの数字で
・3の倍数はFizz
・5の倍数はBuzz
・15の倍数はFizz Buzz
・それ以外は数字
を出力する
'''

for i in range(1,101):
    if i%15==0:
        print('Fizz Buzz')
    elif i%5==0:
        print('Buzz')
    elif i%3==0:
        print('Fizz')
    else:
        print(str(i))
```

#While文
```python:sample.py
while True:
    userInput=input()    # ユーザーからの入力を受け取る関数
    if userInput == 'exit':
        break #ループ処理を終わらせる
    elif userInput == 'skip':
        continue    # 下の処理を行わないで次のループ処理をする
    message='you inputed "{0}"'.format(userInput) 
    print(message)
```

#内包表記
　[]内でfor文を扱うことができ、シーケンスの要素1つ1つに処理を加えて格納できる。

```python:sample.py
numbers=[1,3,5,2,4,7,6]
squares=[num**2 for num in numbers]
print(squares)

fluits = ['apple', 'orange', 'grape', 'peach']
bigFluit=[fluit.upper() for fluit in fluits]    # upper()は大文字表記にするメソッド
alphabet=[char for fluit in fluits for char in fluit]
print(bigFluit)
print(alphabet)



# 1~10の偶数奇数を判別
even=[x for x in range(1,11) if x%2==0]
print(even)
odd=[x for x in range(1,11) if x%2==1]
print(odd)

#9×9
kuku=[[x*y for x in range(1,9)] for y in range(1,9)]
print(kuku)



# dict型の場合
score={'math':80, 'eng':90}
newScore={value:key for key,value in score.items()}
print(newScore)
```

#ファイルへの書き込み
```python:sample.py
text='''おはよう
こんにちは
こんばんは'''
text2='追記'

# ファイルへの書き込み ('w'はwriteの頭文字)
file=open('hello.txt','w',encoding="utf-8")    #ファイルを開く
file.write(text)    # ファイルに書き込む
file.close()    # ファイルを閉じる

# withを用いることで、withを抜けると自動でファイル閉じてくれる
with open('hello.txt','w',encoding="utf-8") as file:
    file.write(text)

#末尾に追記 ('a'はaddの頭文字)
file=open('hello.txt','a',encoding="utf-8")
file.write(text2)
file.close()

'''
#'x':ファイルがすでにある場合はエラーが出る（無い場合は新規作成）
file=open('hello.txt','x',encoding="utf-8")
'''

#ファイルの読み込み ('r'はreadの頭文字)
with open('hello.txt','r',encoding="utf-8") as file:
    for line in file:
        print(line,end='')
```

#関数
```python:sample.py
def hello(name='Mike'):    # 引数の初期値を設定できる
    message='Hi! {0}'.format(name)
    print(message)

hello()
hello('Taro')    # 位置引数
hello(name='Taro')    # キーワード引数



def yeah(text,name='John'):    # textは必須項目
    print(text,name)

yeah('hahaha')



# *つけると複数の位置引数をタプル型で格納する
# **つけると複数のキーワード引数を辞書型で格納する
def wow(*args,**kwargs):
    print(args,kwargs)

wow()
wow('a',a=1)
wow('a','b','c',a=1,b=2,c=3)



def goodbye(text,*,name='Jiro'):    # キーワード引数の前に*指定すると必ずキーワード引数でなければ受け取らないようになる
    print(text,name)

goodbye('おやすみ','Taro')    # Taroはキーワード引数で指定していないため、エラーになる
goodbye('おやすみ',name='Taro')



#引数のnumbers=[]とすると、appendで初期値に追加されてしまうので要注意
def createList(numbers = None):
    if numbers is None:    # Noneは一意なので、'=='ではなくisを用いる
        numbers = []
    for i in range(10):
        numbers.append(i)
    return numbers

numbers=createList()
print(numbers)
```

#グローバル変数とローカル変数
```python:sample.py
num=1

def test():
    global num    # globalつけることで関数外のnumを操作できる
    num=100
    print(num)

print(num)
test()
print(num)
```

#デコレータ
```python:sample.py
def decorator(func):
    print('decorator')
    return func

@decorator    #  decoratorにhello()を引数として渡す
def hello():
    print('hello')
```

#ジェネレータ関数(yield)
　ジェネレータ関数は値を生成する度に返す。listの値を生成してfor文で取り出す処理などで便利。

```python:sample.py
def makeSquare(n):
    for i in range (1,n+1):
        yield i**2

squares = makeSquare(10)
for i in squares:
    print(i)



def myRange(start,end,step):
    currentNumber = start
    while currentNumber < end:
        yield currentNumber    # += stepする前のcurrentNumber返す
        currentNumber += step

# 1~9の間で0.1ずつ値をprintする
for i in myRange(1,10,0.1):
    print(i)
```

#ラムダ関数
　シーケンス型のメソッドで有効。シーケンスの要素を参照したり、処理を行う。

```python:sample.py
myList=[('Apple',100),('orange',70),('Peach',150),('cherry',40)]
myList.sort(key=lambda tpl:tpl[1])    # lambda 引数:返す値
print(myList)



numbers=[1,2,3,4,5]
for num in map(lambda num:num**2,numbers):
    print(num)
# squares=[x**2 for x in numbers]

for num in filter(lambda num:num%2==0,numbers):
    print(num)
```

# クラス
```python:sample.py
members = {}

class Student:    # classは1文字目大文字
  # __init__でconstructorやstateの役割する(入れ物作り)
    def __init__(self, name):
        self.name = name
        self.score = {}

    def add_score(self, subject, point):
        self.score[subject] = point

    def get_score(self, subject):
        return self.score.get(subject, 'this subject is none.')

members['Sato'] = Student('Sato')
members['Ito'] = Student('Ito')
members['Kato'] = Student('Kato')
print(members)



class Character:
    def __init__(self, name):
        self.name = name

    def show_profile(self):
        profile = 'name:{0} race:Character'.format(self.name)
        print(profile)

# 継承
class Monster(Character):
    def __init__(self, name):
        super().__init__(name)    # superで親(Character)の__init__呼ぶ
        self.hp = 20

    def show_profile(self):
        profile = 'name:{0} race:Monster HP:{1}'.format(self.name, self.hp)
        print(profile)

monster1 = Monster('monster A')
monster1.show_profile()



class A:
    def __init__(self):
        self._value=1    # _つけるとprivateな属性(エンジニア間のマナー)

class B:
    def __init__(self):
        self.__value=1    # __つけると外部から変更やアクセスできなくなる

class C(B):
    def __init__(self,name):
        super().__init__()
        self.name=name

class D(C):
    def __init__(self,name):
        super().__init__(name)
        self.value=10

b=B()
print(b._B__value)    # 一応アクセスする方法もある
d=D('Taro')
print(d.value)



class Person:
    def __init__(self, name):
        self.origin_name = name
        self.name = name    # setter呼び出し。real_nameに格納

    @property    # 外部から.nameで呼ばれる
    def name(self):
        return self.real_name

    @name.setter
    def name(self, value):
        if not value:
            value = 'No Name'
        self.real_name = value
```

# まとめ
　if文やclassなどはJavascriptで扱ったことがあったので書き方が少し変わったくらいでしたが、ファイルの読み込みやデコレータといった部分ははじめましてだったので使いこなすのに時間がかかりそうだなと思いました。