ChatGPTで、四字熟語クイズのPython-Flaskアプリを作ってみました。
さすがに一発完成となるコードが出てくる指示文にするのは難しかったので、最初に考えていた機能から削っていき、簡略化してます。本当はセッション機能とか点数計算とかも入れたかったのですが。。。面倒になってきたので諦めました。
事前に問題データを作成してDBに入れてます。DB定義は以下です。
DB名: quiz.db
テーブル名: quiz
カラム :
- question #問題文が入る
- answer #正解が入る
- explanation #解説が入る
- level #問題の難易度が1~3の数字で入る
指示文(プロンプト):
PythonとFlaskで、簡単なクイズアプリを作りたいです。問題はSQLiteのquiz.dbに格納しています。
DBからレコードを1つランダムに取り出して、取り出したレコードの question、answer、explanation、level の内容を表示するFlaskアプリを書いてください。
「Next」ボタンを押すと、再びランダムにレコードを選んで表示するようにしてください。HTMLテンプレートのコードも提示してください。
クイズ画面の表示は以下のようにしてください。
・最初に表示するのはquestionとlevel だけ
・「答えは?」という入力フォームを表示する
・answer 、explanation は最初は非表示にする
・入力フォームの内容と answer が一致していれば「正解」と表示して、非表示にしていたanswer、explanationを表示する
・入力フォームの内容と answer が一致していなければ「不正解」と表示して、非表示にしていたanswer、explanationを表示する
・「わからないので正解を見る」をクリックしても、不正解としてanswer、explanationが表示されるようにする
回答:
以下は、ランダムにquiz.dbから1つのレコードを取り出し、Flaskアプリケーションで表示するコード例です。 "Next"ボタンを押すと、別のランダムなレコードが表示されます。
from flask import Flask, render_template, request
import sqlite3
import random
app = Flask(__name__)
@app.route('/')
def index():
# データベースの接続とカーソルの生成
conn = sqlite3.connect('quiz.db')
c = conn.cursor()
# ランダムに1つのレコードを取得
c.execute('SELECT * FROM quiz ORDER BY RANDOM() LIMIT 1')
row = c.fetchone()
# データベースとの接続を切断
conn.close()
# テンプレートに値を渡してレンダリング
return render_template('quiz.html', question=row[0], answer=row[1], explanation=row[2], level=row[3])
@app.route('/next', methods=['POST'])
def next():
# データベースの接続とカーソルの生成
conn = sqlite3.connect('quiz.db')
c = conn.cursor()
# ランダムに1つのレコードを取得
c.execute('SELECT * FROM quiz ORDER BY RANDOM() LIMIT 1')
row = c.fetchone()
# データベースとの接続を切断
conn.close()
# テンプレートに値を渡してレンダリング
return render_template('quiz.html', question=row[0], answer=row[1], explanation=row[2], level=row[3])
if __name__ == '__main__':
app.run(debug=True)
上記のコードでは、Flaskアプリケーションでルートパスと /next の2つのエンドポイントを作成します。ルートパスでは、データベースからランダムなレコードを取得し、HTMLテンプレートに値を渡してレンダリングします。次へボタンを押すと、/nextエンドポイントが呼び出され、同じランダムなレコードが再び取得されて、テンプレートに値を渡してレンダリングします。また、SQLiteのRANDOM()関数を使用して、ランダムなレコードを取得します。
HTMLテンプレートは、以下のようになります。
<!DOCTYPE html>
<html>
<head>
<title>Quiz</title>
<style>
#answer {
display: none;
}
#result {
font-size:40px;
font-weight: bold;
margin: 50px;
}
</style>
<script>
function showAnswer() {
document.getElementById("answer").style.display = "block";
}
</script>
<script>
function checkAnswer(event) {
event.preventDefault();
const answerInput = document.getElementById("answerInput");
const result = document.getElementById("result");
const answer = "{{ answer }}";
if (answerInput.value === answer) {
result.innerHTML = "正解";
document.getElementById("answer").style.display = "block";
} else {
result.innerHTML = "不正解";
document.getElementById("answer").style.display = "block";
}
}
</script>
</head>
<body>
<h1>Question:</h1>
<p>{{ question }}</p>
<p>Level: {{ level }}</p>
<form onsubmit="checkAnswer(event)">
<label for="answerInput">答えは?</label>
<input type="text" id="answerInput" name="answerInput">
<button type="submit">回答する</button>
<button onclick="showAnswer()">わからないので正解を見る</button>
</form>
<div id="result"></div>
<div id="answer">
<h2>Answer:</h2>
<p>{{ answer }}</p>
<h2>Explanation:</h2>
<p>{{ explanation }}</p>
<form method="POST" action="/next">
<input type="submit" value="Next">
</form>
</div>
</body>
</html>
結果:
一応、動作しました。「正解」「不正解」をわかりやすく表示したりと、見た目は少しだけ手作業でcssを整えています。