【Python】プログラミング初心者がFlaskでPythonをかじってみた話 コーディング編
カリカリ書いてた時期から1か月経ってしまいました。
環境構築編 の続きです。
あ、ちなみに最近、格安SIMに乗り換えました!
参考程度にソースコードを一番下に張り付けておこうと思いますが、
プログラムを書いたのは、ほぼ初めてなので、その辺りはご容赦願いますm( )m
学び①:辞書型の使い方
下記のように、料金プランの持つ値を辞書型の変数で定義しました。
plan_pattern_a = { "plan_s":{ "charge":1980, "data":2.0, "freetalk":60 }, "plan_m":{ "charge":2980, "data":6.0, "freetalk":120 }, "plan_l":{ "charge":4980, "data":14.0, "freetalk":180 } }
定義した変数をどう使ったかは、下記の通り。
選んだプランに応じてifで分岐させました。
変数名['key']でとってこれます。
階層の場合は['key']['key']すればOKです。
sammary_a = Sammary() sammary_a.plan = plan sammary_a.month = (int)(request.form['month']) if sammary_a.plan == "プランS": month_charge = plan_pattern_a["plan_s"]["charge"] freetalktime = plan_pattern_a["plan_s"]["freetalk"] elif sammary_a.plan == "プランM": month_charge = plan_pattern_a["plan_m"]["charge"] freetalktime = plan_pattern_a["plan_m"]["freetalk"] elif sammary_a.plan == "プランL": month_charge = plan_pattern_a["plan_l"]["charge"] freetalktime = plan_pattern_a["plan_l"]["freetalk"] if 'attention' in locals(): sammary_a.comment.append("※比較対象プランで提供できる最大のデータ容量は21GB※※") else: pass
ちなみに、しれっとSammaryクラスが登場していますが、
彼はこんなクラスです。
class Sammary: def __init__(self): self.plan = "" self.month = 0 self.total = 0 self.comment = []
Webアプリユーザが入力した値(プランや使用期間)を各携帯会社の計算ロジックに投入して、
それぞれの合計金額や、注意事項を出力するためには、
それらの情報をひとまとめにして、オブジェクトとして扱うのがよさげかな、
と思い、クラスを作ってみました。
学び②:HTMLとPythonのデータの受け渡し
HTML(ユーザの入力)→Python
HTML入力部分(templates/index.html)
<form action="/result" method="post"> <p> <input type="radio" name="plan_base" value="tanmatsu" checked>スマホとセットで契約<br> <input type="radio" name="plan_base" value="simonly">SIMカードのみで契約<br> <input type="number" name="data_need" value=3>GB程度使用する<br> <input type="number" name="month" class="testbox01" value=1>ヶ月使用した場合<br> <button type="submit" class="btn btn-default">合計料金を表示</button> </p>
ちなみにUIはこんな感じ
Pythonでどう使うかというと、
以下、data_need(ユーザが普段使用する月々のデータ容量)の例です。
# 使用データ容量からプランを判定 if (int)(request.form['data_need']) <= 3: plan = "プランS" elif (int)(request.form['data_need']) > 3 and (int)(request.form['data_need']) <= 9: plan = "プランM" elif (int)(request.form['data_need']) > 9: plan = "プランL" if (int)(request.form['data_need']) > 21: attention = True
数値として処理に使う場合は、 上記のように(int)(…)で変換しました。
Python→HTML
pythonからHTMLに渡している現場はこちら。
# index.html をレンダリングする return render_template('index.html', plan_pattern_a=plan_pattern_a, sammary_a=sammary_a,sammary_b=sammary_b, title=title)
料金情報(plan_pattern_a)→HTML側のplan_pattern_a 合計情報(sammary_a,sammary_b)→HTML側のsammary_a,sammary_b
上記のように渡しています。
対するHTML側はどうなっているかというと。
(templates/index.html)
<div class= "frame02"> <p>★{{ sammary_uq.plan }}を{{ sammary_uq.month }}ヶ月使用した場合<br></p> {% for comment in sammary_uq.comment %} <p>※{{ comment }}<br></p> {% endfor %} </div> <div class="frame01"> <p> ¥{{ sammary_uq.total }}<br> </p> </div>
UIはこうなります。
可変の部分はpythonで渡したオブジェクトから、
変数を引っぱってきています。
まとめ
何か言語を習得したければ、とにかくコーディングしてみることが大事。
Flaskは作ったものが、形になって見えるし、
これからいっちょPythonやろうかなって人にはFlaskはうってつけかと思います。
この独学のおかげで今、
業務でpythonスクリプト書いたりしてます。
(まだまだ格好悪いコードですが。。)
参考
pythonのコードです。
作った時は携帯会社わかるようにしてましたが、
ブログに載せるとなると、
情報の確実性が怪しいので、A社とかB社にしました。
ただ、割引の名前は何か聞いたことあるかもなので、
推測可能です。
from flask import Flask, render_template, request, redirect, url_for import numpy as np # 自身の名称を app という名前でインスタンス化する app = Flask(__name__) #A社・B社料金 #charge_a = {"plan_s":1980, "plan_m":2980, "plan_l":4980} # データ容量定義 #base_data_a = {"plan_s":2.0, "plan_m:":6.0, "plan_l":14.0} plan_pattern_a = { "plan_s":{ "charge":1980, "data":2.0, "freetalk":60 }, "plan_m":{ "charge":2980, "data":6.0, "freetalk":120 }, "plan_l":{ "charge":4980, "data":14.0, "freetalk":180 } } class Sammary: def __init__(self): self.plan = "" self.month = 0 self.total = 0 self.comment = [] # ここからウェブアプリケーション用のルーティングを記述 # index にアクセスしたときの処理 @app.route('/') def index(): title = "携帯料金シミュレータ" # index.html をレンダリングする return render_template('index.html', plan_pattern_a=plan_pattern_a, title=title) # /result にアクセスしたときの処理 @app.route('/result', methods=['GET', 'POST']) def post(): title = "携帯料金シミュレータ" # 使用データ容量からプランを判定 if (int)(request.form['data_need']) <= 3: plan = "プランS" elif (int)(request.form['data_need']) > 3 and (int)(request.form['data_need']) <= 9: plan = "プランM" elif (int)(request.form['data_need']) > 9: plan = "プランL" if (int)(request.form['data_need']) > 21: attention = True ### A モバイル sammary_a = Sammary() sammary_a.plan = plan sammary_a.month = (int)(request.form['month']) if sammary_a.plan == "プランS": month_charge = plan_pattern_a["plan_s"]["charge"] freetalktime = plan_pattern_a["plan_s"]["freetalk"] elif sammary_a.plan == "プランM": month_charge = plan_pattern_a["plan_m"]["charge"] freetalktime = plan_pattern_a["plan_m"]["freetalk"] elif sammary_a.plan == "プランL": month_charge = plan_pattern_a["plan_l"]["charge"] freetalktime = plan_pattern_a["plan_l"]["freetalk"] if 'attention' in locals(): sammary_a.comment.append("※比較対象プランで提供できる最大のデータ容量は21GB※※") else: pass # 通話プラン if request.form['talking'] == "osyaberi": sammary_a.comment.append("1回5分以内の国内通話無料") elif request.form['talking'] == "pittari": sammary_a.comment.append(f"無料通話{freetalktime}分/月") # 家族割引の適用 if request.form['discount_a'] == "family": month_charge = month_charge - 500 sammary_a.comment.append("家族割で基本料金から500円引き") else: pass # ギガMAX月割の適用 if request.form['discount_a'] == "wifi": month_charge = month_charge -300 sammary_a.comment.append("AWiMAXとセットで300円引き") else: pass # 使用期間によって処理を分岐 if request.method == 'POST': if sammary_a.month < 13: sammary_a.total = month_charge * sammary_a.month elif sammary_a.month >= 13: sammary_a.total = month_charge * 12 month_charge = month_charge +1000 sammary_a.total = sammary_a.total + (month_charge * (sammary_a.month-12)) if request.form['deta_increase_a'] == 'on' and sammary_a.month > 25: sammary_a.total = sammary_a.total + (500 * (sammary_a.month-24)) sammary_a.comment.append("データ容量は3年目以降も変わらない") sammary_a.comment.append("3年目から基本料500円増加") elif request.form['deta_increase_a'] == 'off' and sammary_a.month > 25: sammary_a.comment.append("3年目からデータ容量減少") freetalktime = freetalktime / 2 sammary_a.comment.append(f"3年目からは無料通話{freetalktime}分/月") # 金額が負の値にならないようにする(使用期間0ヶ月で割引にチェックを入れた場合など) if sammary_a.total < 0: sammary_a.total = 0 else: pass # 3桁ごとにカンマを入れる(整形) sammary_a.total = "{:,d}".format(sammary_a.total) ### B モバイル sammary_b = Sammary() sammary_b.plan = plan sammary_b.month = (int)(request.form['month']) sammary_b.comment.append("1回10分以内の国内通話無料") if sammary_b.plan == "プランS": month_charge = plan_pattern_a["plan_s"]["charge"] discount_plice = 500 elif sammary_b.plan == "プランM": month_charge = plan_pattern_a["plan_m"]["charge"] discount_plice = 700 elif sammary_b.plan == "プランL": month_charge = plan_pattern_a["plan_l"]["charge"] discount_plice = 1000 # おうち割 光セット if request.form['discount_b'] == "family": month_charge = month_charge - discount_plice sammary_b.comment.append(f"インターネットとセットで{discount_plice}円引き") # 家族割引の適用 elif request.form['discount_b'] == "wifi": month_charge = month_charge - 500 sammary_b.comment.append("家族割で基本料金から500円引き") else: pass # 使用期間によって処理を分岐 if request.method == 'POST': if sammary_b.month < 13: sammary_b.total = month_charge * sammary_b.month elif sammary_b.month >= 13 and sammary_b.month < 25: sammary_b.total = month_charge * 12 month_charge = month_charge +1000 sammary_b.total = sammary_b.total + (month_charge * (sammary_b.month-12)) if request.form['deta_increase_b'] == 'on' and sammary_b.month >= 25: sammary_b.total = sammary_b.total + (500 * (sammary_b.month-24)) sammary_b.comment.append("データ容量は3年目以降も変わらない") sammary_b.comment.append("3年目から基本料500円増加") elif request.form['deta_increase_b'] == 'off' and sammary_b.month >= 25: sammary_b.comment.append("3年目からデータ容量減少") # 金額が負の値にならないようにする(使用期間0ヶ月で割引にチェックを入れた場合など) if sammary_b.total < 0: sammary_b.total = 0 else: pass # 3桁ごとにカンマを入れる(整形) sammary_b.total = "{:,d}".format(sammary_b.total) # index.html をレンダリングする return render_template('index.html', plan_pattern_a=plan_pattern_a, sammary_a=sammary_a,sammary_b=sammary_b, title=title) else: # エラーなどでリダイレクトしたい場合はこんな感じで return redirect(url_for('index')) if __name__ == '__main__': app.debug = True # デバッグモード有効化 app.run() # どこからでもアクセス可能に