来年のGW、初めてのチェコ旅行を計画中です 🇨🇿
現地で少しでも会話できたら楽しいだろうなと思い、
Pythonの学習を兼ねて、Streamlitで“チェコ語クイズアプリ”を作ってみました。
Streamlitとは
PythonでデータアプリやWebツールを超かんたんに作れるオープンソースのフレームワークです。
通常、Webアプリを作るには「HTML / CSS / JavaScript / Flask / Django」 などが必要ですが、Streamlitでは Pythonのスクリプトを書くだけで、即Webアプリになります。
早速使ってみた
- Streamlitのインストール
pip install streamlit
- 全体的なコード
import streamlit as st
import sqlite3
import random
class LearnCzechWordManager:
def __init__(self):
self.db_path = 'path/to/your/directory/word.db'
def connect_db(self):
return sqlite3.connect(self.db_path)
def fetch_random_question_words(self):
random_id = random.randint(1, 20)
conn = self.connect_db()
cursor = conn.execute('SELECT * FROM phrases WHERE id = ?;', (random_id,))
question_word = cursor.fetchone()
conn.close()
return question_word
def fetch_wrong_choices(self, question_word, count=3):
numbers = [i for i in range(1, 21) if i != question_word]
random_ids = random.sample(numbers, count)
conn = self.connect_db()
cursor = conn.cursor()
placeholders = ','.join(['?'] * len(random_ids))
query = f'SELECT * FROM phrases WHERE id IN ({placeholders});'
cursor.execute(query, random_ids)
wrong_choices = cursor.fetchall()
conn.close()
return wrong_choices
def screen_component(self):
st.title('🇨🇿 チェコ語単語マスター')
if "question_word" not in st.session_state:
st.session_state.question_word = self.fetch_random_question_words()
st.session_state.wrong_choices = self.fetch_wrong_choices(st.session_state.question_word[0])
st.session_state.answered = False
correct_answer = st.session_state.question_word[2]
fetch_wrong_choices = st.session_state.wrong_choices
choices = [correct_answer] + [w[2] for w in fetch_wrong_choices]
random.shuffle(choices)
st.session_state.choices = choices
st.session_state.correct_answer = correct_answer
question_word = st.session_state.question_word
phrase = question_word[1]
correct_answer = st.session_state.correct_answer
choices = st.session_state.choices
answer = st.radio(f'次の単語の意味を回答しなさい : {phrase}', choices)
if st.button("回答する") and not st.session_state.answered:
#st.session_state.answered = True
if answer == correct_answer:
st.success("✅ 正解!")
else:
st.error(f"❌ 不正解。正解は『{correct_answer}』です。")
#if st.session_state.answered:
if st.button('次の問題へ'):
st.session_state.clear()
st.rerun()
def main(self):
self.screen_component()
if __name__ == "__main__":
learn_czech_manager = LearnCzechWordManager()
learn_czech_manager.main()
SQLiteに挿入するデータ
-- DBとテーブル作成
CREATE TABLE IF NOT EXISTS phrases (
id INTEGER PRIMARY KEY,
phrase TEXT NOT NULL,
meaning_ja TEXT NOT NULL
);
-- データ投入
INSERT OR REPLACE INTO phrases (id, phrase, meaning_ja) VALUES
(1, 'Dobrý den', 'こんにちは'),
(2, 'Ahoj', 'やあ/こんにちは'),
(3, 'Děkuji / Díky', 'ありがとう/どうもありがとう'),
(4, 'Prosím', 'どうぞ/すみません/お願いします'),
(5, 'Ano / Ne', 'はい/いいえ'),
(6, 'Promiňte', 'すみません(呼びかけ・謝罪)'),
(7, 'Nerozumím', 'わかりません'),
(8, 'Kolik to stojí?', 'いくらですか?'),
(9, 'Účet, prosím', 'お会計をお願いします'),
(10, 'Kde je toaleta?', 'トイレはどこですか?'),
(11, 'Mluvíte anglicky?', '英語を話せますか?'),
(12, 'Jídelní lístek, prosím', 'メニューをお願いします'),
(13, 'Pivo, prosím', 'ビールをお願いします'),
(14, 'Na zdraví!', '乾杯!'),
(15, 'Pomoc!', '助けて!'),
(16, 'Zavolejte policii!', '警察を呼んでください!'),
(17, 'Mám alergii na …', '私は…にアレルギーがあります'),
(18, 'Můžete to napsat?', '書いてくれますか?'),
(19, 'Můžete to zopakovat?', 'もう一度言ってくれますか?'),
(20, 'Je to daleko?', '遠いですか?');
sqlite3 words.db < init_phrases.sql
sqlite3 words.db "SELECT * FROM phrases;"
使ってみた感想、技術的ポイント
st.session_state.question_word = self.fetch_random_question_words()
st.session_state.wrong_choices = self.fetch_wrong_choices(st.session_state.question_word[0])
st.session_state.answered = False
Streamlitは「イベント駆動」ではなく「再実行モデル」です。
- ページを開いた瞬間、app.py が上から下まで一度実行される
- ボタンを押す、入力を変えるなどすると → スクリプトが最初から再実行される
- そのときに、以前の変数はすべてリセットされる(通常の変数では記憶されない)
という挙動になる為、以前の変数は全て破棄されてしまいます。
そのため、ボタンを押す度に問題の内容が変わってしまうという不具合が発生します。
そこで出てくるのが、そこで登場するのが st.session_stateです。
st.session_state は、Streamlit が提供する「永続的な辞書」みたいなものです。
ページ再描画後も、中身が保持されます。
つまり再実行が起こっても、同じ問題データを保持しておくための初期化処理です。
最後に
Streamlitは、簡単で個人が使用するような軽量Webアプリを作るのには向いているのかなと思いました。
非情に簡単で数行書くだけで、良い感じのWebアプリを作ってくれます。
もしよければ皆さんも使用してみてください!