あなたの身長、適正ですか?
皆さんはダイエットと聞くと何を思い浮かべるでしょうか。
糖質制限?有酸素運動?色々あると思います。
おそらく共通しているのは「体重を減らすこと」ではないでしょうか。しかし、それはダイエットの本質ではありません。
ダイエットの本質、それは、体重と身長がバランスの取れた健康な体になることです。
つまり、ダイエットのアプローチには大きく2つあります。
今回私は「身長を変える」にフォーカスしたWEBアプリを作りました。
適正身長がすぐ分かるアプリ「せたけん」
こちらのリンクから無料で使うことができます。
ソースコードはGithubにアップロードされています
使い方
直感的なUI
オプション入力で専門家っぽい人からアドバイスもらえる
現在の身長を入力することで、専門家っぽい人からあなたにぴったりなアドバイスをもらえます!
ヘルスケアアプリで唯一!?干支入力機能搭載
今後の展望
現在はリリース初期ということもあり、ターゲットを絞ったシンプルなサービスにとどめています。
今後はAIとかDXとかメタバースとか使って、サスティナブルな世界を目指していきたいと思います。
過去のクソアプリたち
- おもしろいダジャレを入力すると布団が吹っ飛ぶ装置を作った
- 【待ってました】ラーメンにコショウをかけるためのアプリを作りました!
- ダーツが命中するかどうか、刺さる直前に教えてくれる装置を作った
- RaspberryPiと異常検知を使って、ボケたらツッコんでくれるAIスピーカーを作った
実装面の解説
概要
今回はなるべく手間をかけ無いことを優先し、streamlit を使いました。
streamlitとはhtmlやjavascriptなどをいっさい書かず、pythonだけでwebアプリを作れてしまうオープンソースのPythonライブラリです。
さらにすごいのは、Streamlitのアカウントを作り、ソースコードGithubにpushしてリポジトリを連携することで、なんとWebアプリの公開まで自動でやってくれるのです。レンタルサーバ、gcp、aws、herokuを利用する必要はありません。
コード解説
Github
ディレクトリ構成
.
├── LICENSE
├── .streamlit
│ └── config.toml -- 設定ファイル
├── app.py -- 実装スクリプト
├── eiyoshi.png -- 専門家っぽい人の画像
└── requirements.txt -- 必要なpythonライブラリ一覧
設定ファイル
リポジトリのトップに.stremlit/config.toml
というファイルに設定を書くことで、自動的に読み込んでアプリに反映されます。
設定は以下のとおりです。
[theme]
primaryColor="#809C51" # 基本カラー(スライダーなどの色)
backgroundColor="#FFFFFF" # 背景色
secondaryBackgroundColor="#E4FFB7" #サイドバーなどの背景色
textColor="#262730" # 文字の色
実装スクリプト
基本の書き方
strealitはpythonスクリプトの中で定義したそのままの順で画面に表示されます。
解説も画面の上から順に説明していきます。
スライダーで利用する関数
スライダーが更新されたときに、値をsession_stateに格納する関数を定義します。
値を表示する場所がスライダーよりも下の場合は必要ないのですが、今回は適正身長を上に大きく見せて、スライダーは下に置きたかったためこのような実装になっています。
import math
import streamlit as st
def weight_slider_change():
"""体重スライダーが更新されるたびに体重と適正身長を更新
"""
st.session_state.weight = st.session_state.weight_slider # スライダーから値を取得。スライダーのkeyと対応
st.session_state.best_height = calc_appropriate_height(st.session_state.weight) # 適正身長を計算する関数
def height_slider_change():
"""身長スライダーが更新されるたびに現在身長を更新
"""
st.session_state.now_height = st.session_state.height_slider # スライダーから値を取得。スライダーのkeyと対応
初期化
体重や身長の値を初期化します。
# 初期化
if 'weight' not in st.session_state:
st.session_state.weight = 0
if 'best_height' not in st.session_state:
st.session_state.best_height = 0
if 'now_height' not in st.session_state:
st.session_state.now_height = None
適正身長の表示
stremlitの機能では中央寄せが無いため、マークダウンの中でhtmlを書くという荒業で対処しています。
また、フォントの色やサイズもここで調整しています。
# 身長
st.markdown(
f"<h1 style='text-align: center; color: #809C51;'> \
あなたの適正身長は\
</h1>", unsafe_allow_html=True)
st.markdown(
f"<h1 style='text-align: center; color: #528540; font-size: 7em;'> \
{st.session_state.best_height}\
</h1>", unsafe_allow_html=True)
st.markdown(
f"<h1 style='text-align: center; color: #809C51;'> \
cm\
</h1>", unsafe_allow_html=True)
体重スライダー
画面には表示されない部分ですが、ロジックを定義する関数を先にきさいしています。
スライダーは最小値最大値の設定のほか、スライダーのkeyやスライダーに変更を加えたときに動く関数を定義しています。
# 体重
st.slider(
'体重を入力してね',
min_value=0,
max_value=150,
on_change=weight_slider_change,
key="weight_slider")
アドバイス
アドバイスは自分の身長が入力されたときだけ出したいので、now_heightに値が入っているかどうかで表示を制御しています。
# アドバイス
if st.session_state.now_height:
advice_text = get_advice(
now_height=st.session_state.now_height,
best_height=st.session_state.best_height)
st.text(advice_text)
st.image("./eiyoshi.png", width=100)
オプション
オプションはst.expanderを使って、必要なとき以外デフォルトで閉じるようにしています。
性別と干支の入力にはラジオボタンを使っています。他にもたくさんのボタンがあるので、公式ドキュメントを眺めてみると楽しいと思います。
# オプション
with st.expander("オプション"):
st.slider(
'現在の身長を入力してね',
min_value=50,
max_value=220,
on_change=height_slider_change,
key="height_slider")
# 性別
gender = st.radio("性別", ("未回答", "男性", "女性"))
st.text("※性別は適正体重と無関係です")
# 干支
gender = st.radio("干支", ("未回答", "子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"))
st.text("※干支は適正体重と無関係です")
作者と参考
マークダウンで記載しています。
st.markdown("作者: [@fujitako](https://twitter.com/fujitako03)")
st.markdown("参考: [日本医師会](https://www.med.or.jp/forest/health/eat/11.html)")
デプロイの方法
アカウント作成
公式のサイトの「Get started」からポチポチ行けば作れます。私はComminuty Freeアカウントを作りました。GitHubアカウント認証で作成すると後々のGitHub連携も楽になると思います。
https://streamlit.io/cloud
Githubとの連携
こちらも特に説明するほどのこともなく、ログインしたあとに
New appからリポジトリ名、ブランチ名、実行ファイル名を入力するだけです。
Advanced settingsからPythonのバージョン(3.6, 3.7, 3.8)や環境変数の入力ができます。
最後に
いかがだったでしょうか。非常にかんたんにWebアプリの作成から公開まで行うことができました。
見た目にこだわらず、小さなアプリであれば1時間程度で作成できてしまうのではないでしょうか。