File size: 10,561 Bytes
4f69797
e444e3b
9227ae5
e444e3b
 
efe5a1a
00166b0
78309aa
 
00166b0
 
 
e444e3b
 
 
9227ae5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e444e3b
9227ae5
 
 
3db7d02
9227ae5
 
 
 
ccdda9e
 
 
 
 
 
9227ae5
78309aa
 
 
4272589
 
78309aa
00166b0
 
78309aa
 
00166b0
 
 
78309aa
 
 
 
385222f
9227ae5
b7ed881
 
 
 
 
59c23dd
 
 
 
 
 
 
 
9227ae5
385222f
e444e3b
9227ae5
 
3db7d02
2d81047
78309aa
59c23dd
9227ae5
 
 
4b5f2cf
 
 
 
9227ae5
 
4b5f2cf
 
 
9227ae5
3db7d02
 
b7ed881
7f078c2
e78b69f
 
ccdda9e
 
 
 
 
9227ae5
3db7d02
716cd4d
59c23dd
9227ae5
 
 
 
59c23dd
6d1bed2
ccdda9e
9227ae5
97b3e3f
59c23dd
3db7d02
59c23dd
efe5a1a
e444e3b
37ab76b
e444e3b
97b3e3f
ccdda9e
97b3e3f
59c23dd
 
9c8b9fe
21ef542
8a477cd
6d1bed2
 
b7ed881
 
 
97b3e3f
b7ed881
e444e3b
920014e
97b3e3f
4c88e5f
 
 
 
 
0195f76
 
920014e
4b5f2cf
e2ea6c4
cd601c3
e2ea6c4
21ef542
 
 
 
 
 
78309aa
8a477cd
00166b0
 
78309aa
 
00166b0
 
78309aa
00166b0
9227ae5
ccdda9e
21ef542
 
 
b7d38a9
21ef542
78309aa
8a477cd
 
 
 
ccdda9e
 
 
3db7d02
 
 
ccdda9e
4272589
b7ed881
ccdda9e
 
 
 
 
 
78309aa
 
 
 
 
8a477cd
 
78309aa
 
 
2d81047
21ef542
 
b7d38a9
21ef542
78309aa
8a477cd
 
 
 
 
 
4272589
21ef542
2d81047
4272589
e444e3b
ccdda9e
55c3782
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import os
import gradio as gr
import pandas as pd
import random
import json
import time
import wandb
from copy import deepcopy
from collections import defaultdict

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": "λ‹€μŒ 포켓λͺ¬μ˜ 이름은 λ­˜κΉŒμš”?![]({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']
    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)
    random_buttons = [gr.Button(value=f"{name}") for name in candidates]
    return q, a, random_buttons

initial_info = {"done" : True,
                "score": 0, "count": 0,
                "best_score": 0, "best_time": float("inf"),
                "time": 0.0, "comment": "",
                "history": []}

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, "info.json"), "r") as f:
        info = json.load(f)
except:
    info = defaultdict(lambda : deepcopy(initial_info))
    USERS = ["κΉ€μ„œν˜„", "κΉ€μš°μ£Ό", "Anonymous"]
    for user in USERS:
        print(info[user])

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)
            user = gr.Dropdown(USERS, value="Anonymous", label="μ‚¬μš©μž", info="당신은 λˆ„κ΅¬μ‹ κ°€μš”?", allow_custom_value=True)
            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="ν€΄μ¦ˆ μ‹œμž‘")
                skip = 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"])
            with gr.Row():
                button1 = gr.Button(value="1번")
                button2 = gr.Button(value="2번")
                button3 = gr.Button(value="3번")
                button4 = gr.Button(value="4번")

    def respond(message, chat_history, user, quiz_count, gen, types, request: gr.Request):
        message = message.strip()
        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, random_buttons = get_question_answer(pokemons_set)
                bot_message = f"ν€΄μ¦ˆλ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€.\n{q}"
                info[user]['answer'] = a
                info[user]['done'] = False
                info[user]['score'] = 0
                info[user]['count'] = 0
                info[user]['time'] = time.time()
            else:
                bot_message = "ν€΄μ¦ˆλ₯Ό μ‹œμž‘ν•˜κ³  μ‹ΆμœΌμ‹œλ©΄, **ν€΄μ¦ˆ μ‹œμž‘** λ²„νŠΌμ„ λˆ„λ₯΄μ„Έμš”."
        else:
            if info[user]['answer'] == message:
                q, a, random_buttons = get_question_answer(pokemons_set)
                info[user]['answer'] = a
                info[user]['score'] += 1
                info[user]['count'] += 1
                bot_message = f"πŸŽ‰μ •λ‹΅μž…λ‹ˆλ‹€! λ‹€μŒ λ¬Έμ œμž…λ‹ˆλ‹€.\n{q}\n- ν˜„μž¬ 점수: {info[user]['score']}점\n- μ†Œμš” μ‹œκ°„: {time.time() - info[user]['time']:4.3f}초"

            elif "ν¬κΈ°ν•˜κΈ°" == message.replace(" ", ""):
                bot_message = f"ν€΄μ¦ˆλ₯Ό κ°•μ œ μ’…λ£Œν•©λ‹ˆλ‹€."
                info[user]['done'] = True
            elif "문제 λ„˜μ–΄κ°€κΈ°" == message:
                info[user]['count'] += 1
                q, a = get_question_answer(pokemons_set)
                info[user]['answer'] = a
                bot_message = f"문제λ₯Ό λ„˜μ–΄κ°‘λ‹ˆλ‹€. λ‹€μŒλ¬Έμ œμž…λ‹ˆλ‹€.\n{q}"
            else:
                hint1 = ""
                for i, y in enumerate(info[user]['answer']):
                    if i < len(message):
                        if message[i] == y:
                            hint1 += y
                        else:
                            hint1 += "X"
                    else:
                        hint1 += "X"
                bot_message = f"***{message}***!? 🧐 λ‹€μ‹œ ν•œλ²ˆ μƒκ°ν•΄λ³΄μ„Έμš”.\n힌트: {hint1}"
                info[user]['score'] -= 0.1

            bot_message += f"\n\n총 {quiz_count}개 문제 쀑 {info[user]['count']+1}번째 문제 진행 μ€‘μž…λ‹ˆλ‹€."

            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'])
                    info[user]['best_time'] = round(info[user]['best_time'], 2)
                    info[user]['comment'] = f"{gen.replace(' ', '')}+{types.replace(' ', '')}"
                with open("info.json", "w") as f:
                    json.dump(info, f, indent=4)
                with open("users.json", "w") as f:
                    json.dump(USERS, f, indent=4)
                artifact = wandb.Artifact("settings", type="info")
                artifact.add_file("info.json")
                artifact.add_file("users.json")
                run.log_artifact(artifact)

        info[user]['history'].append((message, bot_message))

        leader_board = sorted(info.items(), key=lambda x: (x[1]['best_score'], -x[1]['best_time']), reverse=True)
        lbdf = pd.DataFrame([dict(**a[1], name=a[0]) for a in leader_board])
        lbdf.rename(columns={'name': "이름", 'best_score': "졜고점수", 'best_time': "μ‹œκ°„κΈ°λ‘", 'comment': "ν€΄μ¦ˆμœ ν˜•"}, inplace=True)
        lbdf.index += 1
        md = lbdf[['이름', '졜고점수', 'μ‹œκ°„κΈ°λ‘', 'ν€΄μ¦ˆμœ ν˜•']]
        if info[user]['done']:
            btn = gr.Button(value="ν€΄μ¦ˆ μ‹œμž‘", label="ν€΄μ¦ˆ μ‹œμž‘")
        else:
            btn = gr.Button(value="ν¬κΈ°ν•˜κΈ°", label="ν€΄μ¦ˆ 쀑단")

        
        return btn, info[user]['history'], md, *random_buttons

    play.click(respond, 
               inputs=[play, chatbot, user, quiz_count, generation, poke_types],
               outputs=[play, chatbot, leader_board, button1, button2, button3, button4])
    skip.click(respond,
               inputs=[skip, chatbot, user, 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, user, quiz_count, generation, poke_types],
                outputs=[play, chatbot, leader_board, button1, button2, button3, button4])
    
    def rs_change(rs):
        global USERS
        if rs not in USERS:
            USERS += [rs]
        new_dropdown = gr.Dropdown(sorted(USERS), value=rs, label="μ‚¬μš©μž", info="당신은 λˆ„κ΅¬μ‹ κ°€μš”?", allow_custom_value=True)
        return new_dropdown

    user.blur(rs_change, user, user)

    def update_table(user):
        leader_board = sorted(info.items(), key=lambda x: (x[1]['best_score'], -x[1]['best_time']), reverse=True)
        lbdf = pd.DataFrame([dict(**a[1], name=a[0]) for a in leader_board])
        lbdf.rename(columns={'name': "이름", 'best_score': "졜고점수", 'best_time': "μ‹œκ°„κΈ°λ‘", 'comment': "ν€΄μ¦ˆμœ ν˜•"}, inplace=True)
        lbdf.index += 1
        md = lbdf[['이름', '졜고점수', 'μ‹œκ°„κΈ°λ‘', 'ν€΄μ¦ˆμœ ν˜•']]

        if info[user]['done']:
            btn = gr.Button(value="ν€΄μ¦ˆ μ‹œμž‘", label="ν€΄μ¦ˆ μ‹œμž‘")
        else:
            btn = gr.Button(value="ν¬κΈ°ν•˜κΈ°", label="ν€΄μ¦ˆ 쀑단")

        return btn, md, gr.Dropdown(USERS, value=user, label="μ‚¬μš©μž", info="당신은 λˆ„κ΅¬μ‹ κ°€μš”?", allow_custom_value=True), info[user]['history']
    demo.load(update_table,
              inputs=user,
              outputs=[play, leader_board, user, chatbot])

demo.queue(concurrency_count=3)
demo.launch()