日々吸っているたばこの本数を管理し、そこから日々のコストを算出。また、週及び月のコスト予測を算出。それらを1画面で管理、可視化しているガジェットです。電子タバコと紙巻きたばこ併用に対応可能で、それぞれのたばこの値段、紙巻きと電子の比率をスライダーで設定できます。
例えばこんな状況で
今回のガジェットは、こういう声に対応
「タバコも高くなってきたし、日々吸っている本数を管理して、月に一体どれくらいの費用がかかるのか把握したい。電子タバコも普及してきたので、併用なんだけど、それぞれ値段も違うからいざ、費用予測を計算しようとすると面倒なんだよな。」
このガジェットでできることはこちら
- タバコを吸った時間を表テーブルで確認できます。
- 1日の本数の比較、またその本数を費用に落とした場合の1日のコストをグラフで確認できます。
- たばこの値段はだんだん変化していますが、自分のたばこの値段を設定できます。
- 電子と紙巻き併用をしている場合でもその比率を設定できます。
- これから1ヶ月のコスト予測を出します。
注意点はこちら
現在の設定ではたばこの値段を変えるとグラフ上のコストも全て変わってしまいます。(ただし、1ヶ月のコスト予測は新しいもので反映します)
評価(自己)
役立ち度 ★★★★(良し)
効率化 ★★★(平均)
ミス防止 ★★★(平均)
楽しさ ★★★★(良し)
操作性 ★★★★(良し)
実行環境
使用環境 streamlit
使用言語 Python
使用ライブラリ pandas、 gspread、oauth2client.service_account、altair、
math、streamlit
コード
import pandas as pd
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import altair as alt
import math
import streamlit as st
st.title('たばこ本数可視化アプリ')
def get_worksheet():
SP_CREDENTIAL_FILE = 'secret.json'
SP_SCOPE = [
'https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive'
]
SP_SHEET_KEY = 'スプレッドシートのI D'
SP_SHEET = 'シート名'
credentials = ServiceAccountCredentials.from_json_keyfile_name(SP_CREDENTIAL_FILE, SP_SCOPE)
gc = gspread.authorize(credentials)
sh = gc.open_by_key(SP_SHEET_KEY)
worksheet = sh.worksheet(SP_SHEET)
return worksheet
def get_chart(kamimaki, denshi, month, week, kami_rate):
worksheet = get_worksheet()
data = worksheet.get_all_values()
df = pd.DataFrame(data[1:], columns=data[0])
daily_num = {}
for day in df.columns:
num = len(df[day][df[day]!=''])
if num != 0:
daily_num[day] = num
agg = pd.DataFrame(daily_num, index=['本数'])
agg = agg.T.reset_index()
agg = agg.rename(columns={'index': 'Date'})
daily_prices = []
for i in range(agg.shape[0]):
d_price = math.floor(agg.iloc[i, 1] * (1-kami_rate/10)) * denshi
k_price = math.ceil(agg.iloc[i, 1] * kami_rate/10) * kamimaki
daily_price = d_price + k_price
daily_prices.append(daily_price)
agg['費用'] = daily_prices
ymin1 = 0
ymax1 = 20
ymin2 = agg['費用'].min() - 10
ymax2 = agg['費用'].max() + 10
base = alt.Chart(agg).encode(
alt.X('Date:T', axis=alt.Axis(title=None))
)
line1 = base.mark_line(opacity=0.3, color='#57A44C').encode(
alt.Y('本数',
axis=alt.Axis(title='本数', titleColor='#57A44C'),
scale=alt.Scale(domain=[ymin1, ymax1])
)
)
line2 = base.mark_line(stroke='#5276A7', interpolate='monotone').encode(
alt.Y('費用',
axis=alt.Axis(title='費用', titleColor='#5276A7'),
scale=alt.Scale(domain=[ymin2, ymax2])
)
)
chart = alt.layer(line1, line2).resolve_scale(
y = 'independent'
)
monthly_cost = agg['費用'].values.mean()*month
weekly_cost = agg['費用'].values.mean()*week
return chart, monthly_cost, weekly_cost
st.sidebar.write('### 紙巻きたばこ値段')
kami = st.sidebar.slider(label='紙巻きたばこ',min_value=400,max_value=600, value=430)
st.sidebar.write('### 電子たばこ値段')
den = st.sidebar.slider(label='電子たばこ',min_value=400,max_value=600, value=430)
st.sidebar.write('### 紙巻き:電子比率')
kami_rate = st.sidebar.slider(label='紙巻きの割合',min_value=0,max_value=10, value=6)
kamimaki = kami / 20
denshi = den / 20
week = 7
month = 30
chart, monthly_cost, weekly_cost = get_chart(kamimaki, denshi, month, week, kami_rate)
st.sidebar.write('### 月額費用')
st.sidebar.write(f'#### {int(monthly_cost)}円')
st.sidebar.write('### 週間費用')
st.sidebar.write(f'#### {int(weekly_cost)}円')
st.write('### 喫煙時間一覧表')
worksheet = get_worksheet()
data = worksheet.get_all_values()
df = pd.DataFrame(data[1:], columns=data[0])
st.dataframe(df)
st.write('### 喫煙本数&費用グラフ')
st.altair_chart(chart, use_container_width=True)