ProgateでPythonを学習

今まで、PHP(Phalcon)で開発をしてきたのですが、急にPythonに切り替えることになりました。
[ここ](http://www.reachat.jp/)のシステムをPythonに切り替えていくそうです。

ということで、初心者御用達のProgateで学習していきます。

###Pythonとは
シンプルで英語に近いので、理解しやすいプログラミング言語。
Webアプリケーション開発・機械学習・統計処理など、様々な分野で利用できる便利な言語でもあります。
そのため、GoogleやFacebook,NASAなどのトップ企業でも採用されている。

#PythonⅠ　Pythonの基本的な使い方〜お買い物代金を計算する簡単なプログラム

・記号の前後の半角スペースは入れなくても良いが、入れたほうがコードが見やすい。

・おさらいですが、変数名の付け方について

```python
#良い例
data  #◎英単語
user_name  #◎2語以上ならアンダーバーで区切る

#悪い例
6name  #✗数字で開始する
namae  #✗ローマ字
名前  #✗日本語
```

###型変換
データ型の異なる文字列型と数字型を連結するとエラーが出る。

```python
age = 22
print("私は" + age + "歳です")

#出力結果
TypeError:must be str,not int
```

22はint型(integer)なので、str型(string)に変換せなあかんわけですね。

```python
print("私は" + str(age) + "歳です")
```

###演算子が他の言語と異なる

```python
x = 20
if x >=10 and x <=30:  #&&
    print("xは10以上30以下です")

y = 60
if y <10 or y >30:  #||
    print("yは10未満または30より大きいです")


z = 55
if not z == 77:  #!=
    print("zは77ではありません")
```

###入力を受け取る
```input```でコードを実行した際に、コンソールに入力した文字を受け取ってくれる。

```python
input_figure = input("数字を入力してください:")
```


###まとめ｜お買い物代金を計算する簡単なプログラム

```python

apple_price = 200
money=1000

input_count = input('購入するりんごの個数を入力してください：')
count = int(input_count)
total_price = apple_price * count
money_after_shopping = money - total_price

print('購入するりんごの個数は' + str(count) + '個です')
print('支払い金額は' + str(total_price) + '円です')

if money > total_price:
    print("りんごを" + str(count) + "個買いました")
    print("残金は" + str(money_after_shopping) + "円です")   
elif money == total_price:
    print("りんごを" + str(count) + "個買いました")
    print("財布が空になりました")
else:
    print("お金が足りません")
    print("りんごを買えませんでした")
```

<br>

#PythonⅡ　複数のデータ管理と繰り返し処理
###リストと要素

```python
fruits=["apple","banana","orange"]
print("好きな果物は"+fruits[0]+"です")
```

・リストに要素を追加

```python
fruits.append("grape")
```

append：添える、付加する

###for文
リストの要素を順に取り出して処理を行う。
リストの要素の数や```range()```などの**長さ**によって繰り返しの回数が決まる。

```python
for fruit in fruits:
    print("好きな果物は"+fruit+"です")
```

###辞書
リストと同様に複数のデータをまとめて管理できる。
個々の要素をインデックス番号ではなく、「キー」で名前を付けて管理する。
辞書はキーと値がペアになってセットです。

```python
type={'red':'fire','blue':'water','green':'wind'}
#変数名={'キー':'値',...}
```

ちなみに、```[]```ではなく、```{}```で区切ります！
また、辞書内の要素には番号がつかないので、順番がありません。

値の取り出し方はこちら。

```python
print(type["red"])
```

キーは文字列なので、```""```をつける、取り出すときは```[]```を使う、ということに注意です。

・辞書でのfor文の書き方

```python
fruits = {'apple': 'りんご', 'banana': 'バナナ', 'grape': 'ぶどう'}

for fruit in fruits:
    print(fruit+"は"+fruits[fruit]+"という意味です")
```

###while文
条件式の結果がTrueの間、while文内の処理を繰り返す
**無限ループ**はコンピュータに異常な負荷をかけるので避けるべし

```python
x=1
while x <= 100:
    print(x)  #x→∞　✗

while x <=100:
    print(x)
x += 1  #while文の外(インデントしていない) ✗
```

正しい書き方はこちら

```python
x = 10  #初期値
while x > 0:  #条件式
    print(x)  #処理1
    x -= 1  #処理2
```

###break文
繰り返し処理を途中で強制的に終了させる

```python
numbers = [765, 921, 777, 256]
for number in numbers:
    print(number)
    if number == 777:  #777でなかったら戻る
        print("777が見つかったので処理を終了します")
        break  #強制修了
```

###continue文
その周の処理だけスキップする

```python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for number in numbers:
    if number %3 == 0:  #3の倍数なら次の処理をスキップ
        continue
    print(number)  #スキップ
```

#まとめ｜お買い物プログラム改良版

```python

money = 1000
items = {'apple': 100, 'banana': 200, 'orange': 400}
for item_name in items:
    print('--------------------------------------------------')
    print('財布には' + str(money) + '円入っています')
    print(item_name + 'は1個' + str(items[item_name]) + '円です')
    
    input_count = input('購入する' + item_name + 'の個数を入力してください：')  #input_countは文字列
    count = int(input_count)  #数字にする
    print('購入する' + item_name + 'の個数は' + str(count) + '個です')
    
    total_price = items[item_name] * count
    print('支払い金額は' + str(total_price) + '円です')
    
    if money >= total_price:
        print(item_name + 'を' + str(count) + '個買いました')
        money -= total_price
        if money == 0:
            print("財布が空になりました")
            break
        
    else:
        print('お金が足りません')
        print(item_name + 'を買えませんでした')

print("残金は"+str(money)+"円です") #条件の外
```

<br>

#PythonⅢ　関数・モジュール〜じゃんけんゲーム
###関数を作る

```python
def 関数名(仮引数1,仮引数2=初期値,...):
    実行する処理    #インデントを忘れずに！

def print_hand(hand,name):
    print(name+hand+'を出しました')

print_hand("グー","フリーザ")
print_hand("パー","カカロット")
```

＊スコープ
変数が使える範囲のこと

```python
def hello(name):
    print(name)  #変数nameのスコープ内 ◎

print(name)  #変数nameのスコープ外 ✗
```

###戻り値
```return```はどの言語でも出てきますよね。
裏で処理を実行しているイメージですかね。
さらに、関数内の処理を終了させます。

```python
def validate(hand):
    if hand < 0 or hand > 2:
        return False
    return True  #もう1つインデントすると、前のreturnで終了しているので、実行されなくなる。
```

###モジュール
Pythonのファイルが書かれたファイルのこと。
別ファイルをモジュールとして読み込むことで、そこに書かれたコードを利用できる。
関数の定義部分を別ファイルに移すことが多い。
```import```でモジュールを読み込める。

```python
import モジュール名
モジュール名.関数名...
```

また、Pythonには便利なモジュールがいくつか用意されている。
これらのあらかじめ用意されているモジュールは「標準ライブラリ」と呼ばれます。

###まとめ｜じゃんけんゲーム

```python:script.py
import utils
import random

print('じゃんけんをはじめます')
player_name = input('名前を入力してください：')
print('何を出しますか？（0: グー, 1: チョキ, 2: パー）')
player_hand = int(input('数字で入力してください：'))

if utils.validate(player_hand):
    computer_hand = random.randint(0,2)
    
    if player_name == '':
        utils.print_hand(player_hand)
    else:
        utils.print_hand(player_hand, player_name)

    utils.print_hand(computer_hand, 'コンピューター')
    
    result = utils.judge(player_hand, computer_hand)
    print('結果は' + result + 'でした')
else:
    print('正しい数値を入力してください')
```

```python:utils.py
def validate(hand):
    if hand < 0 or hand > 2:
        return False
    return True

def print_hand(hand, name='ゲスト'):
    hands = ['グー', 'チョキ', 'パー']
    print(name + 'は' + hands[hand] + 'を出しました')

def judge(player, computer):
    if player == computer:
        return '引き分け'
    elif player == 0 and computer == 1:
        return '勝ち'
    elif player == 1 and computer == 2:
        return '勝ち'
    elif player == 2 and computer == 0:
        return '勝ち'
    else:
        return '負け'
```

<br>

#PythonⅣ　クラス〜合計金額を計算する
・設計図＝クラス
・もの＝インスタンス(Instance：実例)
のイメージ。

インスタンスを生成するステップには3ステップあります。
①クラス(設計図)を用意する
②クラスからインスタンス(もの)を生成する
③インスタンスに名前・値段などの情報を追加する

①クラスの定義
クラス名は大文字で始める。
単語は大文字で区切る

```python
class MenuItem:
    pass  #「何もしない」という意味
```

②クラスを用いてインスタンスを生成
インスタンスは小文字。

```python

menu_item1 = MenuItem()
```

③インスタンス変数を使って情報を追加

```python
menu_item1.name = "カルパッチョ"
print(menu_item1.name)
```

###クラスの中で関数を定義する
クラスの中で定義した関数は「メソッド(Method：方式)」と言う。
メソッドの定義では、必ず第1引数に```self```を追加します。

ちなみに、インスタンスに対して呼び出すメソッドは「インスタンスメソッド」と呼びます。
ややこしくなってきたぞ、、、
まとめるとこんな感じ。

```python
class MenuItem:
    def info(self):
        print(self.name+": ¥"+str(self.price))


menu_item1 = MenuItem()
menu_item1.name = 'カルパッチョ'
menu_item1.price = 500
print(menu_item1.info())
```

ここで```self```には呼び出したインスタンス自身(ここでは```menu_item1```)が入ります。
そのため、()内は空欄でOK。

もう少し複雑にすると、、、

```python
class MenuItem:
    def info(self):
        return self.name + ': ¥' + str(self.price)
    def get_total_price(self,count):
        total_price = self.price * count
        return total_price

menu_item1 = MenuItem()
menu_item1.name = 'カルパッチョ'
menu_item1.price = 500

print(menu_item1.info())
result = menu_item1.get_total_price(4)
print("合計は"+str(result)+"円です")
```

###特殊なインスタンスメソッド〜```__init__```
インスタンスを生成した直後に処理を実行できます。
initialのinitなのかな？

＊```__init__```のメリット
・クラスからインスタンスを生成する
・インスタンス変数に値を代入する
を同時に処理できる。

これを実例に示すと、、、

```python
class MenuItem:
    def __init__(self,name,price):
        self.name = name
        self.price = price

    def info(self):
        return self.name + ': ¥' + str(self.price)

    def get_total_price(self, count):
        total_price = self.price * count
        return total_price

menu_item1 = MenuItem("サンドイッチ",500)
print(menu_item1.info())
result = menu_item1.get_total_price(4)
print('合計は' + str(result) + '円です')
```

コードがシンプルになりました。
インスタンスが増えて、代入する値が増えるほど、効果を発揮します。

###モジュールでクラスも読み込める

```python
from menu_item import MenuItem
```

とすれば、クラス部分の定義を他のファイルに移しても、クラスを引っ張て来れます。
他の部分を書き換える必要は無し！
ちなみに、ファイル名には拡張子(ここでは```py```)はいりません。

#まとめ｜料理の合計金額を計算

```python:menu_item.py
class MenuItem:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def info(self):
        return self.name + ': ¥' + str(self.price)

    def get_total_price(self, count):
        total_price = self.price * count
        if count >=3:
            total_price *= 0.9
        return round(total_price)
```

```python:script.py
from menu_item import MenuItem

menu_item1 = MenuItem('サンドイッチ', 500)
menu_item2 = MenuItem('チョコケーキ', 400)
menu_item3 = MenuItem('コーヒー', 300)
menu_item4 = MenuItem('オレンジジュース', 200)

menu_items = [menu_item1, menu_item2, menu_item3, menu_item4]
index = 0

for menu_item in menu_items:
    print(str(index) + '. ' + menu_item.info())
    index += 1

print('--------------------')
order = int(input('メニューの番号を入力してください: '))
selected_menu = menu_items[order]
print('選択されたメニュー: ' + selected_menu.name)

count = int(input("個数を入力してください(3つ以上で1割引): "))
result = selected_menu.get_total_price(count)
print("合計は" + str(result) + "円です")
```

ちなみに、ここで学習した内容は**オブジェクト指向**と呼びます。

<br>

#PythonⅤ　クラスの応用的な使い方～クラスの継承～料理注文システム

###クラスの継承
あるクラスをもとにして、新たなクラスを作ることを、「継承」と言います。

```python
class 子クラス(親クラス):
    処理
```

継承すると、子クラスは親クラスのインスタンスメソッドを引き継ぐので、そのまま使えます。
めちゃくちゃ便利ですね。

###オーバーライド(メソッドの上書き)
親クラスにあるメソッドと同じ名前のメソッドを子クラスで定義すると、メソッドを上書きできます。
わざわざ親クラスのメソッドを書き換える必要はありません。
子クラスのメソッドが優先されるわけですね。

###メソッド内の重複をまとめる

```python
class Food(Menuitem):
    def __init__(self,name,price,calorie):
        super().__init__(name,price)
        self.calorie = calorie
```

こうすると、```__init__```メソッドのname,price引数の処理を引っ張ってこれます。

#完成｜料理注文システム

```python:menu_item.py
class MenuItem:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def info(self):
        return self.name + ': ¥' + str(self.price)

    def get_total_price(self, count):
        total_price = self.price * count
        if count >= 3:
            total_price *= 0.9
        return round(total_price)
```

```python:food.py
from menu_item import MenuItem

class Food(MenuItem):
    def __init__(self, name, price, calorie):
        super().__init__(name, price)
        self.calorie = calorie
    
    def info(self):
        return self.name + ': ¥' + str(self.price) + ' (' + str(self.calorie) + 'kcal)'
```

```python:drink:py
from menu_item import MenuItem

class Drink(MenuItem):
    def __init__(self, name, price, amount):
        super().__init__(name, price)
        self.amount = amount

    def info(self):
        return self.name + ': ¥' + str(self.price) + ' (' + str(self.amount) + 'mL)'
```

```python:script.py
from food import Food
from drink import Drink

food1 = Food('サンドイッチ', 500, 330)
food2 = Food('チョコケーキ', 400, 450)
food3 = Food('シュークリーム', 200, 180)

foods = [food1, food2, food3]

drink1 = Drink('コーヒー', 300, 180)
drink2 = Drink('オレンジジュース', 200, 350)
drink3 = Drink('エスプレッソ', 300, 30)

drinks = [drink1, drink2, drink3]

print('食べ物メニュー')
index = 0
for food in foods:
    print(str(index) + '. ' + food.info())
    index += 1

print('飲み物メニュー')
index = 0
for drink in drinks:
    print(str(index) + '. ' + drink.info())
    index += 1

print('--------------------')

food_order = int(input('食べ物の番号を選択してください: '))
selected_food = foods[food_order]

drink_order = int(input('飲み物の番号を選択してください: '))
selected_drink = drinks[drink_order]

count = int(input("何セット買いますか？(3つ以上で1割引): "))

result = selected_food.get_total_price(count) + selected_drink.get_total_price(count)
print("合計は" + str(result) +"円です")
```

<br>

#学習のまとめ
初めは、演算子の使い方や条件分岐の書き方が今まで学んできた言語(php)と違ったので、少し戸惑いました。
でも、シンプルなので、pythonの書き方に慣れちゃえば楽ですね！
後は、クラス・インスタンス・メソッドの概念が分かればいけるかと。
Hacker rankなどでもっと鍛える必要あり、、、
それでは！