Spaces:
Runtime error
Runtime error
import random | |
from copy import deepcopy | |
import gradio as gr | |
from romkan import to_hiragana, to_katakana, to_roma | |
a_base = ["a", "k", "s", "t", "n", "h", "m", "y", "r", "w"] | |
a_ext1 = ["g", "z", "d", "b"] | |
a_ext2 = ["p"] | |
b_base = ["a", "i", "u", "e", "o"] | |
b_ext = ["ya", "yo", "yu"] | |
invalid = ["yi", "ye", "wi", "wu", "we"] | |
def next_question(hira, kata, c, quiz_list): | |
if not quiz_list: | |
quiz_list = init_question(hira, kata, c) | |
return quiz_list.pop(), quiz_list | |
def init_question(hira, kata, c): | |
curr_hira = deepcopy(hira) | |
curr_hira += deepcopy(a_ext1) if "濁音" in c else [] | |
curr_hira += deepcopy(a_ext2) if "半濁音" in c else [] | |
curr_kata = deepcopy(kata) | |
if curr_kata: | |
curr_kata += deepcopy(a_ext1) if "濁音" in c else [] | |
curr_kata += deepcopy(a_ext2) if "半濁音" in c else [] | |
curr_b = deepcopy(b_base) | |
curr_b += deepcopy(b_ext) if "拗音" in c else [] | |
hira_list = [to_hira(a, b) for a in curr_hira for b in curr_b if is_valid(a, b)] | |
kata_list = [to_kata(a, b) for a in curr_kata for b in curr_b if is_valid(a, b)] | |
quiz_list = hira_list + kata_list | |
random.shuffle(quiz_list) | |
return quiz_list | |
def is_valid(aa: str, bb: str): | |
if f"{aa}{bb}" in invalid: | |
return False | |
if aa == "y": | |
if bb[0] == "y": | |
return False | |
if bb[0] == "w": | |
return False | |
if bb == "": | |
return False | |
return True | |
def to_hira(a, b): | |
return to_hiragana(combine(a, b)) | |
def to_kata(a, b): | |
return to_katakana(combine(a, b)) | |
def combine(a, b): | |
if a == "a": | |
a = "" | |
return f"{a}{b}" | |
def check(kana: str, roma: str, correct, total): | |
kana_roma = to_roma(kana) | |
ans_correct = kana_roma == roma.lower() | |
correct += ans_correct | |
total += 1 | |
info = "正確" if ans_correct else f"錯誤 - {kana} ({kana_roma})" | |
msg = f"{correct}/{total} - " + info | |
return correct, total, msg, "" | |
def reset_score(): | |
return 0, 0, "0/0", "" | |
font = gr.themes.GoogleFont("NotoSans CJK") | |
theme = gr.themes.Soft(font=font) | |
with gr.Blocks(theme=theme, title="假名小測驗") as app: | |
correct = gr.State(0) | |
total = gr.State(0) | |
quiz_list = gr.State(init_question(a_base[:5], [], [])) | |
with gr.Row(): | |
with gr.Column(): | |
with gr.Tab("測驗"): | |
with gr.Row(): | |
question = gr.Textbox(label="題目") | |
score = gr.Textbox("0/0", label="分數") | |
answer = gr.Textbox(label="作答") | |
with gr.Column(): | |
with gr.Tab("設定"): | |
setting_hira = gr.CheckboxGroup(a_base, value=a_base[:5], label="平假名") | |
setting_kata = gr.CheckboxGroup(a_base, label="片假名") | |
setting_c = gr.CheckboxGroup(["濁音", "半濁音", "拗音"], label="延伸") | |
apply_btn = gr.Button("開始測驗") | |
chk_inn = [question, answer, correct, total] | |
chk_out = [correct, total, score, answer] | |
chk_arg = dict(fn=check, inputs=chk_inn, outputs=chk_out, show_progress="hidden") | |
nq_inn = [setting_hira, setting_kata, setting_c, quiz_list] | |
nq_out = [question, quiz_list] | |
nq_arg = dict(fn=next_question, inputs=nq_inn, outputs=nq_out, show_progress="hidden") | |
ini_inn = [setting_hira, setting_kata, setting_c] | |
ini_out = [quiz_list] | |
ini_arg = dict(fn=init_question, inputs=ini_inn, outputs=ini_out, show_progress="hidden") | |
reset_arg = dict(fn=reset_score, outputs=chk_out, show_progress="hidden") | |
answer.submit(**chk_arg).then(**nq_arg) | |
apply_btn.click(**ini_arg).then(**reset_arg).then(**nq_arg) | |
app.launch() | |