UdemyでPythonを勉強した結果を残すブログ。

40歳でプログラミング始めて転職までいけるのかを実録してみます。

python - google colab などでのデータをグラフ化するおおまかな流れまとめ

前回の記事の続きで

成形したグラフをグラフなどで可視化する流れを復習。

 

  • import pandas as pdでpandas  インポート, pdで呼び出せるように
  • df = pd.read_csv('csvファイル', names=["見出し名1","見出し名2","見出し名3"], header=0) で見出し付きの表を作る。トップに必要のない見出しなどある場合はheader=0でなくす
  • データの中に日付がある場合でタイプがstrの場合は、pd.to_datetime("見出し名")で日付の型に変更ができる。途中NaNなどが入っていたりうまくいかなくてエラーになった場合は、pd.to_datetime("見出し名" ,  errors='coerce')をつけると最後まで動いてくれる
  • 現在の表の列を見出しにして表を再成形したい場合は.pivotを使う。
    reshape_df = pd.pivot("見出し名1","見出し名2","見出し名3").fillna(0)
    これで行見出しは見出し名1、列見出しは見出し名2になる。
    NaNはfillna(nanの代わりに入れたい値)でNaNを差し替えできる。
  • 表として出力したい場合は、plotを使う。
    import matplotlib.pyplot as plt でインポートするとpltで呼び出せる。
  • pyplot で出力する時の標準設定は
    plt.figure(figsize=(10,6)) x軸、y軸のサイズを設定(10,6のところ)
    plt.xticks(fontsize=9) x軸に設定されているデータのフォントサイズ
    plt.yticks(fontsize=9)  y軸に設定されているデータのフォントサイズ
    plt.xlabel('Date', fontsize=17) x軸の見出しを作成(Date部分)・文字サイズ設定
    plt.ylabel('Number of Posts', fontsize=17) y軸の見出しを作成(Date部分)・文字サイズ設定
    plt.ylim(0, 35000) y軸数値の最低値・最高値の設定(-も可能)
  • 単一のデータを出力する場合は
    plt.plot(reshaped_df["入手したいデータの見出し"], linewidth=1,)
    できる。linewidthは線の太さを調整できる。

    また、同じ表の複数のデータをグラフ化したい場合は、forで繰り返すと簡単。
    for column in reshaped_df.columns:
      plt.plot(reshaped_df.index, reshaped_df[column], 
                 linewidth=1, label=reshaped_df[column].name)
  • 複数のデータをグラフ化する場合、データごとに色分けは自動的にされるけどどの色がどのデータかがわからない。
    その場合はlegendを使うことでそれぞれの色を label = reshaped_df[column].nameで設定されたもので表示してくれる。
    plt.legend(fontsize=13)フォントサイズも変更できる。

 

f:id:GO-py:20220314162728p:plain

plot



python - google colabs などでのデータ分析の大まかな流れ

  1. pandasをインポート
  2. .read_csvなどでデータをインポート (インポートしたデータをdfとする)
  3. .head(), tail(), .shape, .columsなどを使ってcsvから見出しや大まかな概要を把握する
  4. 数値じゃない値を .findna() で探し、 .dropna()で削除してデータをきれいにする
  5. df['カラム名'], df'カラム名 1', 'カラム名 2'などで全ての行・列のデータを抽出できる
  6. 1つだけのデータを特定したいときは df['カラム名'][行の数値]、またはdf['カラム名'].loc[行の数値]で抽出できる
  7. 調べたい列の最大・最小値やそのタイトルを知りたいときは、 .max(), .min(), .idxmax(), .idxmin()で探す
  8. 昇順・降順などソートしたい場合は .sort_values(['カラム名', (降順にしたい場合はascending='False')]) でできる。
    新しい列を入れたい時は .insert('入れたい列の順番' ,  '見出しの名前', '入れるデータ') で入れられる。先に入れるデータを変数で格納しておく。
  9. 列内のグループごとの数値を取得したい場合は、 .groupby() でできる。
    df.groupby("データ列にあるグループ名").mean()など

 

DAY16 OOP(オブジェクト指向プログラミング)を勉強してコーヒーメーカーをアップデートする!

OOPとはObject Oriented Programming の略でオブジェクト指向プログラミングという。

 

今までのようにコーディングしていった場合、実務だとコーディングがどんどん煩雑になっていくので

どこにどのコードを書いたのかわかりにくくなってしまう。

 

今回はクラスを使うことで大枠の要素を定義して、

そこから違うオブジェクトをつくれることでコードを綺麗にして効率化ができる。

 

例えばゲームの世界でも同じエルフでも力が強いエルフだったり魔法が強いエルフだったり元は同じ種族でも能力が違うものがいたりする。

元は同じ種族なのに一人一人最初からコード書いてたら大変だし、

アップデート時にエルフの基礎能力を調整するってなった時に

今までだったらエルフ一人一人書き換えないといけない。

 

それならエルフというクラスを作って、

エルフはまずそこから能力を分けていく方が効率がいい。

というような感じだと思う。

 

種族が違っていても、エルフと人間で同じ魔法が使えるのであれば

魔法もそれぞれクラスとして使えるのかもしれない。

 

 

そんな感じでとりあえず前回のコーヒーメーカーのdefで定義したファンクションを

コーヒーメーカーというクラスの中に収納してコードをアップデートしていくと、こんな感じに書き換えられる。

 

CoffeeMachine.py

class CoffeeMachine:

def insert_money(self):
print("お金を入れてください。")
total = int(input("いくらいれますか? ¥"))
print(f"¥{round(total, 2)} 入りました。")
return total

def make_drink(self, order, resources):
for item in order["ingredients"]:
resources[item] -= order["ingredients"][item]
print(f"…\n\n\n☕️できました。ごゆっくり!\n\n\n")

def check_remains(self, order, resources):
for item in order["ingredients"]:
if resources[item] < order["ingredients"][item]:
print("売り切れです。")
return False
else:
return True

 

名前の書き方は、クラスはCoffeeMachineで単語の最初を大文字にして_ は使わない記述の方がいいとのことなので従っていく。

 


MENU = {
"espresso": {
"ingredients": {
"water": 50,
"coffee": 18,
},
"cost": 300,
},
"latte": {
"ingredients": {
"water": 200,
"milk": 150,
"coffee": 24,
},
"cost": 400,
},
"cappuccino": {
"ingredients": {
"water": 250,
"milk": 100,
"coffee": 24,
},
"cost": 350,
}
}

resources = {
"water": 300,
"milk": 200,
"coffee": 100,
}


from coffee_maker_func import CoffeeMachine

coffee_machine = CoffeeMachine()


def coffee_maker():
profit = 0
can_make = True
while can_make:
order = input("何を飲みますか? espresso:300 / latte:400 / cappuccino:350 : ")
if order == "report":
print(f"water : {resources['water']} ml\nmilk : {resources['milk']}ml\ncoffee : {resources['coffee']}g\n売上:¥{profit}")

elif order == "espresso" or "latte" or "cappuccino":
if coffee_machine.check_remains(MENU[order], resources):
paid_money = coffee_machine.insert_money()
cost = MENU[order]["cost"]
if cost <= paid_money:
coffee_machine.make_drink(MENU[order], resources)
profit += cost
else:
print("お金が足りません。")
coffee_maker()
elif order == "off":
print("電源オフ")
can_make = False


 

前はinsert_money()だけでよかったけどクラスを使うことで
coffee_machine.insert_money()とちょっと文字は増える。

でもこれのおかげでこのメソッドはコーヒーマシーンの定義なんだなとわかるし、

もし違う種類のコーヒーマシーンオブジェクトを作る時も基本機能が同じならばこのクラスは使いまわせる。

 

今はだいぶわかってきているつもりだけど

最初は全然わからなかったしクラスを追加することで

coffee_machine.make_drink(MENU[order], resources)

とかのresourcesみたいに入れる部分が増えることでこんがらがったりするけど

 

やっていくうちになれる。はず。

 

 

 

 

スクレイピングをする時にAmazonとかでうまくできない場合の設定テンプレ

myhttpheader.com

 

アマゾンで普通にrequestで思ったエレメントがとれない場合は

上のhttpheader.comとかでuser-agentとaccept-languageのデータをとって

headerに追加してrequestsすると思い通りのものがとれる。

 

それでもできなかった場合はBS4のparserをhtml.parserからlxmlにする。

 

 

import requests
from bs4 import BeautifulSoup
URL = "https://www.amazon.com/Enhanced-Splashproof-Portable-Bluetooth-Radiator/dp/B010OYASRG/"
response = requests.get(url=URL, headers={"Accept-Language":"ja,en-US;q=0.9,en;q=0.8r",
'User-Agent':"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36"})
soup = BeautifulSoup(response.text, "lxml")

price = float(soup.select_one(".a-price span:nth-of-type(2)").getText().replace("$", ""))
print(price)

$を抜かした値段だけ出力されます。$もいるならreplaceを消す

Python : smtplibを使ったメール送信テンプレ(gmail)

gmail側もセキュリティを低くする設定が必要。

他サーバーの場合もいるのかも。

 

import smtplib

MY_EMAIL = "YOUR EMAIL"
MY_PASSWORD = "YOUR PASSWORD"

contents = "..."

with smtplib.SMTP("YOUR EMAIL PROVIDER SMTP SERVER ADDRESS") as connection:
connection.starttls()
connection.login(MY_EMAIL, MY_PASSWORD)
connection.sendmail(
from_addr=MY_EMAIL,
to_addrs=["somebody_to_send_email"],
msg=f"Subject:HELLO!\n\n{contents}"
)

 

これは全部で1セットとしてコピペすると早いはず。

 

 

 

 

 

DAY:15 PyCharmを使って簡易擬似コーヒーメーカーをプログラミングする!

今までの学習はreplit.comでの作業だったのだけど、
これからはpythonのコーディング用ツールを使っての作業に。

 

 

replit.com

 

先生のおすすめはPyCharm。

Pythonに特化したツール(IDEというらしい)で環境構築もしやすくて、みやすそうな感じ。

 

ちょっと前までのコードのコピーもこちらからしているので、

復習分はPyCharmからコードを書いています。

 

今回はコーヒーメーカーをプログラミング。

 

システムの流れ。

 

コーヒーメーカーの仕様。

  • reportを入力するとコーヒー、ミルク、水の残量がわかる。
  • 作れるメニューはエスプレッソ、ラテ、カプチーノ
  • offを入力すると電源オフ

コーヒーメーカーが出てくる流れ。

  • 3つのうちどれを頼むかを聞く。
  • 材料の残量を確認する。作れない場合は「売り切れ」とする。
  • 作れるならお金を支払いを聞く。
  • 金額を確認して、代金以上なら作る。
  • 材料を保管分から減らし売上を計上する。

 

こんな感じ。

 

ではコーディングに。

 

材料とメニューはこんな感じ。

 

MENU = {
"espresso": {
"ingredients": {
"water": 50,
"coffee": 18,
},
"cost": 300,
},
"latte": {
"ingredients": {
"water": 200,
"milk": 150,
"coffee": 24,
},
"cost": 400,
},
"cappuccino": {
"ingredients": {
"water": 250,
"milk": 100,
"coffee": 24,
},
"cost": 350,
}
}

profit = 0
resources = {
"water": 300,
"milk": 200,
"coffee": 100,
}

 

コーヒーメーカーの機能を、

・支払う金額を要求する機能

・材料を使ってコーヒーを作る機能

・売り切れかどうかを確認する機能

と分けて、全てをコーヒーメーカーというプロダクトに入れるようなイメージにする。

 

 

 

 

3つのうちどれを頼むかを聞く。reportを入力すると原材料と売上がわかる。

 

def coffee_machine():
profit = 0
can_make = True
while can_make:
order = input("何を飲みますか? espresso:300 / latte:400 / cappuccino:350 : ")
if order == "report":
print(f"water : {resources['water']} ml\nmilk : {resources['milk']}ml\ncoffee : {resources['coffee']}g\n売上:¥{profit}")

 

繰り返すように最初からwhileで囲っています。

3つのメニューのうちどれかを入力したら、check_remains()をいう残量確認機能を作り、return Trueであれば支払い=insert_money()へと行く。

costは選んだメニューの価格をセットしています。

 

elif order == "espresso" or "latte" or "cappuccino":
if check_remains(MENU[order]):
paid_money = insert_money()
cost = MENU[order]["cost"]

insert_money()で支払い金額が代金より多かったら return Trueを出して、

make_drink()で頼んだコーヒーを作る。その時に材料も減らす機能を盛り込む。

作ったので売上を計上する。

 

お金が足りない場合は足りませんと表示する。

 

if cost <= paid_money:
make_drink(MENU[order])
profit += cost
else:
print("お金が足りません。")
insert_money()

 

最後にoffをした場合に電源を切る。

        elif order == "off":
print("電源オフ")
can_make = False

coffee_machine()

 

本体の流れとしてはこんな感じ。

あとは分割した機能

残量確認機能 = check_remains()

支払い機能 = insert_money()

コーヒーを作る機能 = make_drink()

を作る。

 

残量確認機能 = check_remains()

def check_remains(order):
for item in order["ingredients"]:
if resources[item] < order["ingredients"][item]:
print("売り切れです。")
return False
else:
return True

check_remains(order)のorder部分にinputで入力したメニューを保存して、

そのメニューの中の材料部分のリストをforで回して、

残量より多かったら売り切れですと表示して、Falseを返す。

作れるならTrue  を返す仕様です。

 

 

 

支払い機能 = insert_money()

def insert_money():
print("お金を入れてください。")
total = int(input("いくらいれますか? ¥"))
print(f"¥{round(total, 2)} 入りました。")
return total

 

これは簡単ですね。

 

 

コーヒーを作る機能 = make_drink()

 

def make_drink(order):
for item in order["ingredients"]:
resources[item] -= order["ingredients"][item]
print(f"…\n\n\n☕️できました。ごゆっくり!\n\n\n")

 

これもオーダーしたメニューを保存して、

そのリストをforで残量分から材料を引いて、完成。

 

 

コーディング部分全てはこちら。

こちらも自分で描いたものなので粗いかもしれません。

 


def insert_money():
print("お金を入れてください。")
total = int(input("いくらいれますか? ¥"))
print(f"¥{round(total, 2)} 入りました。")
return total

def make_drink(order):
for item in order["ingredients"]:
resources[item] -= order["ingredients"][item]
print(f"…\n\n\n☕️できました。ごゆっくり!\n\n\n")

def check_remains(order):
for item in order["ingredients"]:
if resources[item] < order["ingredients"][item]:
print("売り切れです。")
return False
else:
return True


def coffee_machine():
profit = 0
can_make = True
while can_make:
order = input("何を飲みますか? espresso:300 / latte:400 / cappuccino:350 : ")
if order == "report":
print(f"water : {resources['water']} ml\nmilk : {resources['milk']}ml\ncoffee : {resources['coffee']}g\n売上:¥{profit}")

elif order == "espresso" or "latte" or "cappuccino":
if check_remains(MENU[order]):
paid_money = insert_money()
cost = MENU[order]["cost"]
if cost <= paid_money:
make_drink(MENU[order])
profit += cost
else:
print("お金が足りません。")
insert_money()
elif order == "off":
print("電源オフ")
can_make = False

coffee_machine()