質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Jinja2

Jinja2は、Python用のテンプレートエンジンです。テンプレートファイルの読込や文字列の埋込、分岐/ループの制御文のサポートなどの機能を持ちます。HTMLやXML生成によく使用されますが、どのような文書でも生成することが可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1326閲覧

postで受け取った値がリストに入らない場合がある

mmtt

総合スコア23

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Jinja2

Jinja2は、Python用のテンプレートエンジンです。テンプレートファイルの読込や文字列の埋込、分岐/ループの制御文のサポートなどの機能を持ちます。HTMLやXML生成によく使用されますが、どのような文書でも生成することが可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/29 12:10

編集2021/12/29 12:12

前提・実現したいこと

Flaskを用いてクイズアプリを作っています。ランダムで10問の問題を順に出題し、回答の正誤を判定するというものです。
その際、list_truefalse というリストに1~10問目の正誤結果を格納し表示させたいのですが、上手くリストに格納される時もあれば中身がNoneとなり格納されない時もあり困っています。
1度リンク先より実際にお試しいただければイメージしやすいかもしれません。
![イメージ説明(HTML側にlist_truefalseを渡して表示させており、本来「×」か「○」のどちらかが表示されるはずですが左から2つ目と4つ目は、「?」(中身がNone)が表示されている)

発生している問題・エラーメッセージ

エラーは出ていませんが、listの中身がNoneになる場合があります

該当のソースコード

python

1@app.route('/question') # /questionにルートすると1問目をランダムで指定し出題画面にリダイレクト 2def set(): 3 global q_num 4 global list_truefalse 5 global list_choice 6 q_num = 0 7 list_truefalse = [None] * 10 8 list_choice = [None] * 10 9 first_q = random.randint(0, q_max) 10 return redirect('question/0/'+str(first_q)) 11 12 13@app.route('/question/<int:q_num>/<int:id>', methods=['GET', 'POST']) 14def read(q_num, id): 15 global q_order 16 global list_truefalse 17 global list_choice 18 try: 19 q_num = q_num 20 except NameError: 21 return redirect('/question') 22 q_info = df_all.loc[id] 23 progress = '<div class="progress-bar" role="progressbar" style="width:'+str(q_num/10*100)+'%;" aria-valuenow="' + str(q_num/10*100)+'" aria-valuemin="0" aria-valuemax="100"></div>' 24 if q_num > 0: 25 pass 26 else: 27 q_order = random.sample(range(q_max), k=10) 28 q_order[0] = id # ランダムで指定した1問目を上書き 29 list_truefalse = [None] * 10 30 list_choice = [None] * 10 31 if request.method == 'GET': 32 choice = request.args.get('send', 'None Selected') 33 return render_template('question.html', choice=choice, 34 q_info=q_info, 35 q_num=q_num, 36 q_order=q_order, 37 list_truefalse=list_truefalse, 38 progress=progress) 39 elif request.method == 'POST': 40 choice = request.form.get("send") 41 list_truefalse[q_num] = choice 42 try: 43 list_truefalse[q_num] = choice == q_info.answer 44 except IndexError: 45 list_truefalse[q_num] = "?" 46 q_num += 1 47 48 return render_template('question.html', choice=choice, 49 q_info=q_info, 50 q_num=q_num, 51 q_order=q_order, 52 list_truefalse=list_truefalse, 53 progress=progress)

HTML

1<!-- 正誤結果のリスト --> 2<div class="row justify-content-start" id="truefalse_list"> 3 {% for i in range(10) %} 4 <div class="col-1"> 5 {% if list_truefalse[i] == True %} <!-- 中身がtrueの時は「○」 --> 6 <li class="list-group-item far fa-circle"></li> 7 {% elif list_truefalse[i] == False %}<!-- 中身がfalseの時は「○」 --> 8 <li class="list-group-item fas fa-times"></li> 9 {% elif list_truefalse[i] == None %}<!-- 中身がtrueの時は「?」 --> 10 <li class="list-group-item fas fa-question"></li> 11 {% else %}<!-- その他の時は「!」 --> 12 <li class="list-group-item fas fa-exclamation-circle"></li> 13 {% endif %} 14 </div> 15 {% endfor %} 16 </div> 17 18(中略) 19 20<!-- 回答画面 --> 21 <!--回答前--> 22 {% if choice == "None Selected" %} 23 <div class="box"> 24 <span class="box-title">Q.{{ q_num + 1 }}</span> 25 <p>{{ q_info.question }}</p> 26 </div> 27 28 <form method="POST" action=''> 29 <div class="d-grid gap-2 col-10 mx-auto" id="choices"> 30 <button class="btn btn-success" type="submit" name="send" value="a" >{{ q_info.choice_1 }}</button> 31 <button class="btn btn-success" type="submit" name="send" value="b">{{ q_info.choice_2 }}</button> 32 <button class="btn btn-success" type="submit" name="send" value="c" >{{ q_info.choice_3 }}</button> 33 <button class="btn btn-success" type="submit" name="send" value="d">{{ q_info.choice_4 }}</button> 34 <button class="btn btn-success" type="submit" name="send" value="e">{{ q_info.choice_5 }}</button> 35 </div> 36 </form> 37(以下略) 38

試したこと

list_truefalseをグローバル変数にしましたが、変わらずでした。

補足情報(FW/ツールのバージョンなど)

ローカル環境では正常に動きます。サーバーはHerokuの無料版を利用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以前の質問のようにWebアプリでグローバル変数を使うのはやめましょう。
https://teratail.com/questions/374417

こういうクイズアプリを作るのであれば普通はデータベースを使ってIDごとに回答内容や問題を記録していくことが多いです。
herokuであればPostgresを使うといいかと思います

投稿2021/12/29 12:31

編集2021/12/29 12:32
Supernove

総合スコア1154

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mmtt

2021/12/31 07:44

アドバイスありがとうございます。global変数を使わずデータベースを使った設計を検討します。 ちなみに、現状の設計では質問点を解消する方法はないということでしょうか。 将来的にはアドバイスいただいた設計でやろうと思っていますが、まずはクイックに作りたいなと考えております。
Supernove

2021/12/31 07:53

Flask Chachingを使うのはどうでしょう?IDごとにグローバル変数の値をキャッシュに残しておけば解消できるかもしれません。 https://github.com/pallets-eco/flask-caching あとはPythonのライブラリにtinyDBというものがありまして、これは別途サーバーを立てなくても手軽にデータを保存できるのでおすすめです! 自分も昔ちょっとしたデータの記録につかってました https://office54.net/python/module/python-database-tinydb#section2-1
FiroProchainezo

2021/12/31 15:03

横から失礼します。 ソースは読んでいませんが、とりあえず結果を覚えておきたいだけならsessionを使うのが良いと思います。 クイズの解答を恒久的に保存しておきたいならDB必須ですが、とりあえず覚えておくだけならsession、ブラウザ閉じても覚えておきたいならcookieあたりが選択肢になると思います。
mmtt

2022/01/03 05:51

Supernoveさん、FiroProchainezoさんご教示いただきありがとうございました。 Flask Cjaching,tinyDB,sessionなど知らないことばかりだったので大変助かりました。 今回は取り急ぎ保存ができればOKだったので、sessionに回答等を保存する方法で解決しました。 今後より良くするためにDBを使った設計などを検討していきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問