Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| import pandas as pd | |
| import random | |
| import json | |
| import time | |
| import wandb | |
| from utils import Info | |
| import logging | |
| from typing import Optional | |
| wandb.login(key=os.environ['WANDB_KEY']) | |
| run = wandb.init(project="pokemon-quiz", entity="yoon-gu") | |
| 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] | |
| } | |
| QUESTION_TEMPLATE = {"question": "λ€μ ν¬μΌλͺ¬μ μ΄λ¦μ λκΉμ?", "answer": "{name}"} | |
| def get_question_answer(pokemons_set, user): | |
| chosen = random.choice(pokemons_set) | |
| name = chosen['name'] | |
| image_path = chosen['image_path'] | |
| 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) | |
| candidates = random.choices([poke['name'] for poke in pokemons_set], k=3) | |
| candidates.append(a) | |
| random.shuffle(candidates) | |
| infos[user].candidates = candidates | |
| return q, a | |
| initial_info = {"done" : True, | |
| "score": 0, "count": 0, | |
| "best_score": 0, "best_time": float("inf"), | |
| "time": 0.0, "comment": "", | |
| "history": [], | |
| "candidates": ['1λ²', '2λ²', '3λ²', '4λ²']} | |
| try: | |
| folder = run.use_artifact("settings:latest").download() | |
| with open(os.path.join(folder, "users.json"), "r") as f: | |
| USERS = json.load(f) | |
| with open(os.path.join(folder, "infos.json"), "r") as f: | |
| infos = json.load(f) | |
| for k, v in infos.items(): | |
| infos[k] = Info(**v) | |
| except Exception as e: | |
| logging.error(e) | |
| USERS = ["κΉμν", "κΉμ°μ£Ό", "Anonymous"] | |
| infos = {user: Info(name=user) for user in USERS} | |
| MD = """# ν¬μΌλͺ¬ ν΄μ¦ π¦ | |
| ## κ³΅λΆ λ°©λ² π | |
| μλ ν¬μΌλͺ¬ λκ°μ λ³΄κ³ κ³΅λΆνλ©΄ λμμ΄ λ©λλ€. | |
| - https://huggingface.co/spaces/yoon-gu/pokemon | |
| ## μ¬μ©λ°©λ² π | |
| 1. μ¬μ©μλ₯Ό μ ννμΈμ. | |
| 2. μ΄ ν΄μ¦ κ°μλ₯Ό μ ννμΈμ. | |
| 3. ν¬μΌλͺ¬ μΈλλ₯Ό μ ννμΈμ. | |
| 4. ν¬μΌλͺ¬ νμ μ μ ννμΈμ. | |
| ## μ μν π | |
| """ | |
| with gr.Blocks() as demo: | |
| with gr.Row(): | |
| with gr.Column(): | |
| markdown = gr.Markdown(MD.format(content='')) | |
| leader_board = gr.DataFrame(wrap=True, row_count=10) | |
| with gr.Row(): | |
| gr.LoginButton() | |
| gr.LogoutButton() | |
| # user = gr.Dropdown(USERS, value="Anonymous", label="μ¬μ©μ", info="λΉμ μ λꡬμ κ°μ?", allow_custom_value=True) | |
| quiz_count = gr.Radio([10, 20, 30, 40, 50], value=10, label="μ΄ ν΄μ¦ κ°μ", info="ν΄μ¦λ₯Ό λͺ κ° ν μμ μΈκ°μ?") | |
| with gr.Column(): | |
| with gr.Row(): | |
| with gr.Accordion("See Details", open=False): | |
| generation = gr.CheckboxGroup( | |
| [f"{k}μΈλ" for k in range(1, 10)], | |
| value=[f"{k}μΈλ" for k in range(1, 10)], | |
| label="ν¬μΌλͺ¬ μΈλ", | |
| info="μνλ ν¬μΌλͺ¬ μΈλλ₯Ό μ ννμΈμ." | |
| ) | |
| poke_types = gr.CheckboxGroup( | |
| pokemons_types, value=pokemons_types, | |
| label="ν¬μΌλͺ¬ νμ ", | |
| info="μνλ ν¬μΌλͺ¬ νμ μ μ ννμΈμ." | |
| ) | |
| with gr.Row(): | |
| play = gr.Button(value="ν΄μ¦ μμ", label="ν΄μ¦ μμ") | |
| skip = gr.Button(value="λ¬Έμ λμ΄κ°κΈ°", label="λ¬Έμ μ€ν΅") | |
| chatbot = gr.Chatbot(bubble_full_width=False, | |
| height=600, | |
| 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"]) | |
| with gr.Row(): | |
| button1 = gr.Button(value="1λ²") | |
| button2 = gr.Button(value="2λ²") | |
| with gr.Row(): | |
| button3 = gr.Button(value="3λ²") | |
| button4 = gr.Button(value="4λ²") | |
| def respond(message, chat_history, quiz_count, gen, types, profile: Optional[gr.OAuthProfile]): | |
| if profile: | |
| user = profile.name | |
| else: | |
| raise gr.Error("μ¬μ©μ μ΄λ¦μ μ λ ₯νμΈμ.") | |
| message = message.strip() | |
| done = infos[user].done | |
| dfs = [] | |
| for g in gen: | |
| start, end = GEN_RANGE[g] | |
| dfs.append(df[start-1:end]) | |
| sdf = pd.concat(dfs) | |
| pokemons_set = sdf[sdf['types'].apply(lambda x: any([t in x for t in types]))] | |
| pokemons_set = pokemons_set.to_dict("records") | |
| if done: | |
| infos[user].history = [] | |
| if "ν΄μ¦μμ" == message.replace(" ", ""): | |
| q, a = get_question_answer(pokemons_set, user) | |
| bot_message = f"ν΄μ¦λ₯Ό μμν©λλ€.\n{q}" | |
| infos[user].answer = a | |
| infos[user].done = False | |
| infos[user].score = 0 | |
| infos[user].count = 0 | |
| infos[user].time = time.time() | |
| infos[user].generations = gen | |
| infos[user].types = types | |
| else: | |
| bot_message = "ν΄μ¦λ₯Ό μμνκ³ μΆμΌμλ©΄, **ν΄μ¦ μμ** λ²νΌμ λλ₯΄μΈμ." | |
| else: | |
| if infos[user].answer == message: | |
| q, a = get_question_answer(pokemons_set, user) | |
| infos[user].answer = a | |
| infos[user].score += 10 | |
| infos[user].count += 1 | |
| bot_message = f"πμ λ΅μ λλ€! λ€μ λ¬Έμ μ λλ€.\n{q}\n- νμ¬ μ μ: {infos[user].score:3.1f}μ \n- μμ μκ°: {time.time() - infos[user].time:4.3f}μ΄" | |
| elif "ν¬κΈ°νκΈ°" == message.replace(" ", ""): | |
| bot_message = f"ν΄μ¦λ₯Ό κ°μ μ’ λ£ν©λλ€." | |
| infos[user].done = True | |
| elif "λ¬Έμ λμ΄κ°κΈ°" == message: | |
| infos[user].count += 1 | |
| q, a = get_question_answer(pokemons_set, user) | |
| infos[user].answer = a | |
| bot_message = f"λ¬Έμ λ₯Ό λμ΄κ°λλ€. λ€μλ¬Έμ μ λλ€.\n{q}" | |
| else: | |
| hint1 = "" | |
| for i, y in enumerate(infos[user].answer): | |
| if i < len(message): | |
| if message[i] == y: | |
| hint1 += y | |
| else: | |
| hint1 += "X" | |
| else: | |
| hint1 += "X" | |
| bot_message = f"***{message}***!? π§ λ€μ νλ² μκ°ν΄λ³΄μΈμ.\nννΈ: {hint1}" | |
| infos[user].score -= 1 | |
| # gr.Info(f"{user}λ, μ΄ {quiz_count}κ° λ¬Έμ μ€ {infos[user].count+1}λ²μ§Έ λ¬Έμ μ§ν μ€μ λλ€.") | |
| if quiz_count == infos[user].count: | |
| bot_message = f"λͺ¨λ ν΄μ¦λ₯Ό λ€ νμμ΅λλ€. μ μλ {infos[user].score:3.1f}μ μ λλ€." | |
| infos[user].done = True | |
| if infos[user].score >= infos[user].best_score: | |
| infos[user].best_score = infos[user].score | |
| infos[user].best_time = min(time.time() - infos[user].time, infos[user].best_time) | |
| infos[user].best_time = round(infos[user].best_time, 2) | |
| infos[user].comment = f"{gen}+{types}" | |
| infos[user].history = [] | |
| with open("infos.json", "w") as f: | |
| json.dump({k: v.model_dump() for k, v in infos.items()}, f, indent=4, ensure_ascii=False) | |
| with open("users.json", "w") as f: | |
| json.dump(USERS, f, indent=4, ensure_ascii=False) | |
| artifact = wandb.Artifact("settings", type="History") | |
| artifact.add_file("infos.json") | |
| artifact.add_file("users.json") | |
| run.log_artifact(artifact) | |
| infos[user].history.append((message, bot_message)) | |
| leader_board = sorted(infos.items(), key=lambda x: (x[1].best_score, -x[1].best_time), reverse=True) | |
| lbdf = pd.DataFrame([dict(**a[1].model_dump()) for a in leader_board]) | |
| lbdf.rename(columns={'name': "μ΄λ¦", 'best_score': "μ΅κ³ μ μ", 'best_time': "μκ°κΈ°λ‘", 'comment': "ν΄μ¦μ ν"}, inplace=True) | |
| lbdf.index += 1 | |
| md = lbdf[['μ΄λ¦', 'μ΅κ³ μ μ', 'μκ°κΈ°λ‘', 'ν΄μ¦μ ν']] | |
| if infos[user].done: | |
| btn = gr.Button(value="ν΄μ¦ μμ", label="ν΄μ¦ μμ") | |
| else: | |
| btn = gr.Button(value="ν¬κΈ°νκΈ°", label="ν΄μ¦ μ€λ¨") | |
| random_buttons = [gr.Button(value=c) for c in infos[user].candidates] | |
| return btn, infos[user].history, md, *random_buttons | |
| play.click(respond, | |
| inputs=[play, chatbot, quiz_count, generation, poke_types], | |
| outputs=[play, chatbot, leader_board, button1, button2, button3, button4]) | |
| skip.click(respond, | |
| inputs=[skip, chatbot, quiz_count, generation, poke_types], | |
| outputs=[play, chatbot, leader_board, button1, button2, button3, button4]) | |
| for btn in [button1, button2, button3, button4]: | |
| btn.click(respond, | |
| inputs=[btn, chatbot, quiz_count, generation, poke_types], | |
| outputs=[play, chatbot, leader_board, button1, button2, button3, button4]) | |
| def update_table(profile: Optional[gr.OAuthProfile]): | |
| user = profile.name | |
| global USERS | |
| if user not in USERS: | |
| USERS += [user] | |
| infos[user] = Info(name=user) | |
| leader_board = sorted(infos.items(), key=lambda x: (x[1].best_score, -x[1].best_time), reverse=True) | |
| lbdf = pd.DataFrame([dict(**a[1].model_dump()) for a in leader_board]) | |
| lbdf.rename(columns={'name': "μ΄λ¦", 'best_score': "μ΅κ³ μ μ", 'best_time': "μκ°κΈ°λ‘", 'comment': "ν΄μ¦μ ν"}, inplace=True) | |
| lbdf.index += 1 | |
| md = lbdf[['μ΄λ¦', 'μ΅κ³ μ μ', 'μκ°κΈ°λ‘', 'ν΄μ¦μ ν']] | |
| if infos[user].done: | |
| btn = gr.Button(value="ν΄μ¦ μμ", label="ν΄μ¦ μμ") | |
| else: | |
| btn = gr.Button(value="ν¬κΈ°νκΈ°", label="ν΄μ¦ μ€λ¨") | |
| random_buttons = [gr.Button(value=c) for c in infos[user].candidates] | |
| return new_dropdown, btn, md, infos[user].history, *random_buttons | |
| demo.load(update_table, | |
| inputs=None, | |
| outputs=[play, leader_board, chatbot, button1, button2, button3, button4]) | |
| demo.queue(concurrency_count=3) | |
| demo.launch() |