math-quiz / app.py
Yoon-gu Hwang
avatar μ„€μ •
7f078c2
raw
history blame
No virus
6.38 kB
import os
os.system("pip install gradio==3.46.0")
import gradio as gr
import pandas as pd
import random
import json
import time
with open('pokemon.json', 'r') as f:
pokemons = json.load(f)
pokemons_types = ["λͺ¨λ“  νƒ€μž…"] + sorted(set([t for poke in pokemons for t in poke['types']]))
df = pd.DataFrame(pokemons)
GEN_RANGE = {
"λͺ¨λ“  μ„ΈλŒ€": [1, 1017],
"1μ„ΈλŒ€": [1, 151],
"2μ„ΈλŒ€": [152, 251],
"3μ„ΈλŒ€": [252, 386],
"4μ„ΈλŒ€": [387, 493],
"5μ„ΈλŒ€": [494, 649],
"6μ„ΈλŒ€": [650, 721],
"7μ„ΈλŒ€": [722, 809],
"8μ„ΈλŒ€": [810, 905],
"9μ„ΈλŒ€": [906, 1017]
}
USERS = ["June", "Sean", "Woojoo", "Taejoo", "Dummy"]
QUESTION_TEMPLATE = {"question": "λ‹€μŒ 포켓λͺ¬μ˜ 이름은 λ­˜κΉŒμš”?![]({img_url})", "answer": "{name}"}
def get_question_answer(pokemons_set):
chosen = random.choice(pokemons_set)
name = chosen['name'].replace("♀", "μ•”μ»·").replace("β™‚", "수컷")
image_path = chosen['image_path']
answer.value = QUESTION_TEMPLATE['answer'].format(name=name)
img_url = f"https://huggingface.co/spaces/yoon-gu/pokemon/resolve/main/{image_path}"
q = QUESTION_TEMPLATE["question"].format(img_url=img_url)
a = QUESTION_TEMPLATE['answer'].format(name=name)
return q, a
info = {u: {"done" : True, "score": 0, "count": 0, "best_score": 0, "best_time": float("inf"), "time": 0.0} for u in USERS}
MD = """# 포켓λͺ¬ ν€΄μ¦ˆ
## μ‚¬μš©λ°©λ²•
1. μ‚¬μš©μžλ₯Ό μ„ νƒν•˜μ„Έμš”.
2. 총 ν€΄μ¦ˆ 개수λ₯Ό μ„ νƒν•˜μ„Έμš”.
3. 포켓λͺ¬ μ„ΈλŒ€λ₯Ό μ„ νƒν•˜μ„Έμš”.
4. 포켓λͺ¬ νƒ€μž…μ„ μ„ νƒν•˜μ„Έμš”.
## 점수판
{content}
"""
with gr.Blocks() as demo:
answer = gr.State(value="")
with gr.Row():
with gr.Column():
markdown = gr.Markdown(MD.format(content=''))
user = gr.Radio(USERS, value="Dummy", label="μ‚¬μš©μž", info="당신은 λˆ„κ΅¬μ‹ κ°€μš”?")
quiz_count = gr.Radio([10, 20, 30], value=10, label="총 ν€΄μ¦ˆ 개수", info="ν€΄μ¦ˆλ₯Ό λͺ‡ 개 ν’€ μ˜ˆμ •μΈκ°€μš”?")
with gr.Column():
with gr.Row():
generation = gr.Dropdown(
[f"{k}μ„ΈλŒ€" for k in range(1, 10)] + ["λͺ¨λ“  μ„ΈλŒ€"],
value="λͺ¨λ“  μ„ΈλŒ€",
label="포켓λͺ¬ μ„ΈλŒ€",
info="μ›ν•˜λŠ” 포켓λͺ¬ μ„ΈλŒ€λ₯Ό μ„ νƒν•˜μ„Έμš”."
)
poke_types = gr.Dropdown(
pokemons_types, value="λͺ¨λ“  νƒ€μž…",
label="포켓λͺ¬ νƒ€μž…",
info="μ›ν•˜λŠ” 포켓λͺ¬ νƒ€μž…μ„ μ„ νƒν•˜μ„Έμš”."
)
with gr.Row():
play = gr.Button(value="ν€΄μ¦ˆ μ‹œμž‘", label="ν€΄μ¦ˆ μ‹œμž‘")
stop = gr.Button(value="ν€΄μ¦ˆ μ’…λ£Œ", label="ν€΄μ¦ˆ μ’…λ£Œ")
chatbot = gr.Chatbot(bubble_full_width=False,
avatar_images=["https://huggingface.co/spaces/yoon-gu/pokemon/resolve/main/images/No_0001_이상해씨.png",
"https://huggingface.co/spaces/yoon-gu/pokemon/resolve/main/images/No_0155_λΈŒμΌ€μΈ.png"])
msg = gr.Textbox(placeholder="문제의 닡을 μž…λ ₯ν•˜μ„Έμš”.", label="λ‹΅")
def respond(message, chat_history, user, quiz_count, gen, types, request: gr.Request):
done = info[user]['done']
start, end = GEN_RANGE[gen]
sdf = df[start:end]
pokemons_set = sdf[sdf['types'].apply(lambda x: (types in x)) | (types == "λͺ¨λ“  νƒ€μž…")]
pokemons_set = pokemons_set.to_dict("records")
if done:
if "ν€΄μ¦ˆμ‹œμž‘" == message.replace(" ", ""):
q, a = get_question_answer(pokemons_set)
bot_message = f"ν€΄μ¦ˆλ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€.\n{q}"
answer.value = a
info[user]['done'] = False
info[user]['score'] = 0
info[user]['count'] = 0
info[user]['time'] = time.time()
else:
bot_message = "ν€΄μ¦ˆλ₯Ό μ‹œμž‘ν•˜κ³  μ‹ΆμœΌμ‹œλ©΄, **ν€΄μ¦ˆ μ‹œμž‘**이라고 λ§μ”€ν•΄μ£Όμ„Έμš”."
else:
if answer.value == message:
q, a = get_question_answer(pokemons_set)
answer.value = a
info[user]['score'] += 1
info[user]['count'] += 1
bot_message = f"πŸŽ‰μ •λ‹΅μž…λ‹ˆλ‹€! λ‹€μŒ λ¬Έμ œμž…λ‹ˆλ‹€.\n{q}"
if quiz_count == info[user]['count']:
bot_message = f"λͺ¨λ“  ν€΄μ¦ˆλ₯Ό λ‹€ ν’€μ—ˆμŠ΅λ‹ˆλ‹€. μ μˆ˜λŠ” {info[user]['score']:3.1f}점 μž…λ‹ˆλ‹€."
info[user]['done'] = True
if info[user]['score'] >= info[user]['best_score']:
info[user]['best_score'] = info[user]['score']
info[user]['best_time'] = min(time.time() - info[user]['time'], info[user]['best_time'])
elif "ν€΄μ¦ˆμ’…λ£Œ" == message.replace(" ", ""):
bot_message = f"ν€΄μ¦ˆλ₯Ό κ°•μ œ μ’…λ£Œν•©λ‹ˆλ‹€."
info[user]['done'] = True
else:
hint1 = ""
for x, y in zip(message, answer.value):
if x == y:
hint1 += x
else:
hint1 += "X"
bot_message = f"***{message}***!? 🧐 λ‹€μ‹œ ν•œλ²ˆ μƒκ°ν•΄λ³΄μ„Έμš”.\n힌트: {hint1}"
info[user]['score'] -= 0.1
chat_history.append((message, bot_message))
return "", chat_history, MD.format(content='\n'.join([f"- {u}({v['best_score']:3.1f}점, {v['best_time']:3.1f}초)" for u, v in info.items()]))
play.click(respond,
inputs=[play, chatbot, user, quiz_count, generation, poke_types],
outputs=[msg, chatbot, markdown])
stop.click(respond,
inputs=[stop, chatbot, user, quiz_count, generation, poke_types],
outputs=[msg, chatbot, markdown])
demo.load(lambda : MD.format(content='\n'.join([f"- {u}({v['best_score']:3.1f}점, {v['best_time']:3.1f}초)" for u, v in info.items()])),
inputs=None,
outputs=markdown)
msg.submit(respond, [msg, chatbot, user, quiz_count, generation, poke_types], [msg, chatbot, markdown])
demo.queue(concurrency_count=1)
demo.launch()