Yoon-gu Hwang commited on
Commit
f46bcc2
1 Parent(s): 3323684

pydantic 사용

Browse files
Files changed (2) hide show
  1. app.py +50 -53
  2. utils.py +23 -0
app.py CHANGED
@@ -5,8 +5,7 @@ import random
5
  import json
6
  import time
7
  import wandb
8
- from copy import deepcopy
9
- from collections import defaultdict
10
 
11
  wandb.login(key=os.environ['WANDB_KEY'])
12
  run = wandb.init(project="pokemon-quiz", entity="yoon-gu")
@@ -41,7 +40,7 @@ def get_question_answer(pokemons_set, user):
41
  candidates = random.choices([poke['name'] for poke in pokemons_set], k=3)
42
  candidates.append(a)
43
  random.shuffle(candidates)
44
- info[user]['candidates'] = candidates
45
  return q, a
46
 
47
  initial_info = {"done" : True,
@@ -55,13 +54,11 @@ try:
55
  folder = run.use_artifact("settings:latest").download()
56
  with open(os.path.join(folder, "users.json"), "r") as f:
57
  USERS = json.load(f)
58
- with open(os.path.join(folder, "info.json"), "r") as f:
59
- info = json.load(f)
60
  except:
61
- info = defaultdict(lambda : deepcopy(initial_info))
62
  USERS = ["김서현", "김우주", "Anonymous"]
63
- for user in USERS:
64
- print(info[user])
65
 
66
  MD = """# 포켓몬 퀴즈 🦑
67
  ## 공부 방법
@@ -117,43 +114,43 @@ with gr.Blocks() as demo:
117
  if user.strip() == "":
118
  raise gr.Error("사용자 이름을 입력하세요.")
119
  message = message.strip()
120
- done = info[user]['done']
121
  start, end = GEN_RANGE[gen]
122
  sdf = df[start:end]
123
  pokemons_set = sdf[sdf['types'].apply(lambda x: (types in x)) | (types == "모든 타입")]
124
  pokemons_set = pokemons_set.to_dict("records")
125
  global random_buttons
126
  if done:
127
- info[user]['history'] = []
128
  if "퀴즈시작" == message.replace(" ", ""):
129
  q, a = get_question_answer(pokemons_set, user)
130
  bot_message = f"퀴즈를 시작합니다.\n{q}"
131
- info[user]['answer'] = a
132
- info[user]['done'] = False
133
- info[user]['score'] = 0
134
- info[user]['count'] = 0
135
- info[user]['time'] = time.time()
136
  else:
137
  bot_message = "퀴즈를 시작하고 싶으시면, **퀴즈 시작** 버튼을 누르세요."
138
  else:
139
- if info[user]['answer'] == message:
140
  q, a = get_question_answer(pokemons_set, user)
141
- info[user]['answer'] = a
142
- info[user]['score'] += 1
143
- info[user]['count'] += 1
144
- bot_message = f"🎉정답입니다! 다음 문제입니다.\n{q}\n- 현재 점수: {info[user]['score']:3.1f}점\n- 소요 시간: {time.time() - info[user]['time']:4.3f}초"
145
 
146
  elif "포기하기" == message.replace(" ", ""):
147
  bot_message = f"퀴즈를 강제 종료합니다."
148
- info[user]['done'] = True
149
  elif "문제 넘어가기" == message:
150
- info[user]['count'] += 1
151
  q, a = get_question_answer(pokemons_set, user)
152
- info[user]['answer'] = a
153
  bot_message = f"문제를 넘어갑니다. 다음문제입니다.\n{q}"
154
  else:
155
  hint1 = ""
156
- for i, y in enumerate(info[user]['answer']):
157
  if i < len(message):
158
  if message[i] == y:
159
  hint1 += y
@@ -162,41 +159,41 @@ with gr.Blocks() as demo:
162
  else:
163
  hint1 += "X"
164
  bot_message = f"***{message}***!? 🧐 다시 한번 생각해보세요.\n힌트: {hint1}"
165
- info[user]['score'] -= 0.1
166
-
167
- gr.Info(f"{user}님, 총 {quiz_count}개 문제 중 {info[user]['count']+1}번째 문제 진행 중입니다.")
168
-
169
- if quiz_count == info[user]['count']:
170
- bot_message = f"모든 퀴즈를 다 풀었습니다. 점수는 {info[user]['score']:3.1f}점 입니다."
171
- info[user]['done'] = True
172
- if info[user]['score'] >= info[user]['best_score']:
173
- info[user]['best_score'] = info[user]['score']
174
- info[user]['best_time'] = min(time.time() - info[user]['time'], info[user]['best_time'])
175
- info[user]['best_time'] = round(info[user]['best_time'], 2)
176
- info[user]['comment'] = f"{gen.replace(' ', '')}+{types.replace(' ', '')}"
177
- with open("info.json", "w") as f:
178
- json.dump(info, f, indent=4)
179
  with open("users.json", "w") as f:
180
- json.dump(USERS, f, indent=4)
181
- artifact = wandb.Artifact("settings", type="info")
182
- artifact.add_file("info.json")
183
  artifact.add_file("users.json")
184
  run.log_artifact(artifact)
185
- info[user]['history'] = []
186
 
187
- info[user]['history'].append((message, bot_message))
188
- leader_board = sorted(info.items(), key=lambda x: (x[1]['best_score'], -x[1]['best_time']), reverse=True)
189
- lbdf = pd.DataFrame([dict(**a[1], name=a[0]) for a in leader_board])
190
  lbdf.rename(columns={'name': "이름", 'best_score': "최고점수", 'best_time': "시간기록", 'comment': "퀴즈유형"}, inplace=True)
191
  lbdf.index += 1
192
  md = lbdf[['이름', '최고점수', '시간기록', '퀴즈유형']]
193
- if info[user]['done']:
194
  btn = gr.Button(value="퀴즈 시작", label="퀴즈 시작")
195
  else:
196
  btn = gr.Button(value="포기하기", label="퀴즈 중단")
197
 
198
- random_buttons = [gr.Button(value=c) for c in info[user]['candidates']]
199
- return btn, info[user]['history'], md, *random_buttons
200
 
201
  play.click(respond,
202
  inputs=[play, chatbot, user, quiz_count, generation, poke_types],
@@ -215,19 +212,19 @@ with gr.Blocks() as demo:
215
  if user not in USERS:
216
  USERS += [user]
217
  new_dropdown = gr.Dropdown(sorted(USERS), value=user, label="사용자", info="당신은 누구신가요?", allow_custom_value=True)
218
- leader_board = sorted(info.items(), key=lambda x: (x[1]['best_score'], -x[1]['best_time']), reverse=True)
219
- lbdf = pd.DataFrame([dict(**a[1], name=a[0]) for a in leader_board])
220
  lbdf.rename(columns={'name': "이름", 'best_score': "최고점수", 'best_time': "시간기록", 'comment': "퀴즈유형"}, inplace=True)
221
  lbdf.index += 1
222
  md = lbdf[['이름', '최고점수', '시간기록', '퀴즈유형']]
223
 
224
- if info[user]['done']:
225
  btn = gr.Button(value="퀴즈 시작", label="퀴즈 시작")
226
  else:
227
  btn = gr.Button(value="포기하기", label="퀴즈 중단")
228
 
229
- random_buttons = [gr.Button(value=c) for c in info[user]['candidates']]
230
- return new_dropdown, btn, md, gr.Dropdown(USERS, value=user, label="사용자", info="당신은 누구신가요?", allow_custom_value=True), info[user]['history'], *random_buttons
231
 
232
  user.blur(update_table,
233
  inputs=user,
 
5
  import json
6
  import time
7
  import wandb
8
+ from utils import Info
 
9
 
10
  wandb.login(key=os.environ['WANDB_KEY'])
11
  run = wandb.init(project="pokemon-quiz", entity="yoon-gu")
 
40
  candidates = random.choices([poke['name'] for poke in pokemons_set], k=3)
41
  candidates.append(a)
42
  random.shuffle(candidates)
43
+ infos[user].candidates = candidates
44
  return q, a
45
 
46
  initial_info = {"done" : True,
 
54
  folder = run.use_artifact("settings:latest").download()
55
  with open(os.path.join(folder, "users.json"), "r") as f:
56
  USERS = json.load(f)
57
+ with open(os.path.join(folder, "infos.json"), "r") as f:
58
+ infos = json.load(f)
59
  except:
 
60
  USERS = ["김서현", "김우주", "Anonymous"]
61
+ infos = {user: Info(name=user) for user in USERS}
 
62
 
63
  MD = """# 포켓몬 퀴즈 🦑
64
  ## 공부 방법
 
114
  if user.strip() == "":
115
  raise gr.Error("사용자 이름을 입력하세요.")
116
  message = message.strip()
117
+ done = infos[user].done
118
  start, end = GEN_RANGE[gen]
119
  sdf = df[start:end]
120
  pokemons_set = sdf[sdf['types'].apply(lambda x: (types in x)) | (types == "모든 타입")]
121
  pokemons_set = pokemons_set.to_dict("records")
122
  global random_buttons
123
  if done:
124
+ infos[user].history = []
125
  if "퀴즈시작" == message.replace(" ", ""):
126
  q, a = get_question_answer(pokemons_set, user)
127
  bot_message = f"퀴즈를 시작합니다.\n{q}"
128
+ infos[user].answer = a
129
+ infos[user].done = False
130
+ infos[user].score = 0
131
+ infos[user].count = 0
132
+ infos[user].time = time.time()
133
  else:
134
  bot_message = "퀴즈를 시작하고 싶으시면, **퀴즈 시작** 버튼을 누르세요."
135
  else:
136
+ if infos[user].answer == message:
137
  q, a = get_question_answer(pokemons_set, user)
138
+ infos[user].answer = a
139
+ infos[user].score += 1
140
+ infos[user].count += 1
141
+ bot_message = f"🎉정답입니다! 다음 문제입니다.\n{q}\n- 현재 점수: {infos[user].score:3.1f}점\n- 소요 시간: {time.time() - infos[user].time:4.3f}초"
142
 
143
  elif "포기하기" == message.replace(" ", ""):
144
  bot_message = f"퀴즈를 강제 종료합니다."
145
+ infos[user].done = True
146
  elif "문제 넘어가기" == message:
147
+ infos[user].count += 1
148
  q, a = get_question_answer(pokemons_set, user)
149
+ infos[user].answer = a
150
  bot_message = f"문제를 넘어갑니다. 다음문제입니다.\n{q}"
151
  else:
152
  hint1 = ""
153
+ for i, y in enumerate(infos[user].answer):
154
  if i < len(message):
155
  if message[i] == y:
156
  hint1 += y
 
159
  else:
160
  hint1 += "X"
161
  bot_message = f"***{message}***!? 🧐 다시 한번 생각해보세요.\n힌트: {hint1}"
162
+ infos[user].score -= 1
163
+
164
+ gr.Info(f"{user}님, 총 {quiz_count}개 문제 중 {infos[user].count+1}번째 문제 진행 중입니다.")
165
+
166
+ if quiz_count == infos[user].count:
167
+ bot_message = f"모든 퀴즈를 다 풀었습니다. 점수는 {infos[user].score:3.1f}점 입니다."
168
+ infos[user].done = True
169
+ if infos[user].score >= infos[user].best_score:
170
+ infos[user].best_score = infos[user].score
171
+ infos[user].best_time = min(time.time() - infos[user].time, infos[user].best_time)
172
+ infos[user].best_time = round(infos[user].best_time, 2)
173
+ infos[user].comment = f"{gen.replace(' ', '')}+{types.replace(' ', '')}"
174
+ with open("infos.json", "w") as f:
175
+ json.dump({k: v.model_dump() for k, v in infos.items()}, f, indent=4, ensure_ascii=False)
176
  with open("users.json", "w") as f:
177
+ json.dump(USERS, f, indent=4, ensure_ascii=False)
178
+ artifact = wandb.Artifact("settings", type="History")
179
+ artifact.add_file("infos.json")
180
  artifact.add_file("users.json")
181
  run.log_artifact(artifact)
182
+ infos[user].history = []
183
 
184
+ infos[user].history.append((message, bot_message))
185
+ leader_board = sorted(infos.items(), key=lambda x: (x[1].best_score, -x[1].best_time), reverse=True)
186
+ lbdf = pd.DataFrame([dict(**a[1].model_dump()) for a in leader_board])
187
  lbdf.rename(columns={'name': "이름", 'best_score': "최고점수", 'best_time': "시간기록", 'comment': "퀴즈유형"}, inplace=True)
188
  lbdf.index += 1
189
  md = lbdf[['이름', '최고점수', '시간기록', '퀴즈유형']]
190
+ if infos[user].done:
191
  btn = gr.Button(value="퀴즈 시작", label="퀴즈 시작")
192
  else:
193
  btn = gr.Button(value="포기하기", label="퀴즈 중단")
194
 
195
+ random_buttons = [gr.Button(value=c) for c in infos[user].candidates]
196
+ return btn, infos[user].history, md, *random_buttons
197
 
198
  play.click(respond,
199
  inputs=[play, chatbot, user, quiz_count, generation, poke_types],
 
212
  if user not in USERS:
213
  USERS += [user]
214
  new_dropdown = gr.Dropdown(sorted(USERS), value=user, label="사용자", info="당신은 누구신가요?", allow_custom_value=True)
215
+ leader_board = sorted(infos.items(), key=lambda x: (x[1].best_score, -x[1].best_time), reverse=True)
216
+ lbdf = pd.DataFrame([dict(**a[1].model_dump()) for a in leader_board])
217
  lbdf.rename(columns={'name': "이름", 'best_score': "최고점수", 'best_time': "시간기록", 'comment': "퀴즈유형"}, inplace=True)
218
  lbdf.index += 1
219
  md = lbdf[['이름', '최고점수', '시간기록', '퀴즈유형']]
220
 
221
+ if infos[user].done:
222
  btn = gr.Button(value="퀴즈 시작", label="퀴즈 시작")
223
  else:
224
  btn = gr.Button(value="포기하기", label="퀴즈 중단")
225
 
226
+ random_buttons = [gr.Button(value=c) for c in infos[user].candidates]
227
+ return new_dropdown, btn, md, gr.Dropdown(USERS, value=user, label="사용자", info="당신은 누구신가요?", allow_custom_value=True), infos[user].history, *random_buttons
228
 
229
  user.blur(update_table,
230
  inputs=user,
utils.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+ initial_info = {"done" : True,
4
+ "score": 0, "count": 0,
5
+ "best_score": 0, "best_time": float("inf"),
6
+ "time": 0.0, "comment": "",
7
+ "history": [],
8
+ "candidates": ['1번', '2번', '3번', '4번']}
9
+
10
+ class Info(BaseModel):
11
+ done: bool = True
12
+ score: int = 0
13
+ count: int = 0
14
+ answer: str = None
15
+ best_score: int = 0
16
+ best_time: float = float("inf")
17
+ time: float = 0.0
18
+ comment: str = ""
19
+ history: list = []
20
+ candidates: list = ['1번', '2번', '3번', '4번']
21
+ name: str = None
22
+ generations: list = []
23
+ types: list = []