hujunyao commited on
Commit
943d9ab
·
verified ·
1 Parent(s): 67ca19c

Upload 5 files

Browse files
Files changed (5) hide show
  1. app.py +378 -0
  2. src/home.png +0 -0
  3. src/question_1.jpg +0 -0
  4. src/weixin.png +0 -0
  5. src/zanshang.png +0 -0
app.py ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import random
3
+ import time
4
+
5
+ css = '''
6
+ .show img {height: 320px}
7
+ .result img {height: 320px}
8
+ .qrcode img {height: 225px}
9
+ .btn {
10
+ justify-content: normal
11
+ }
12
+ '''
13
+
14
+ def get_new_question_and_options():
15
+ time.sleep(1.5)
16
+ number = random.randint(1,65536)
17
+ return {
18
+ "question_text": f"问题{number}是这样的。",
19
+ "option_A": f"问题{number}给出的选项A,吃饭",
20
+ "option_B": f"问题{number}给出的选项B,睡觉",
21
+ "option_C": f"问题{number}给出的选项C,打豆豆",
22
+ }
23
+
24
+ def get_option_result(question_text, option_text):
25
+ time.sleep(1.5)
26
+ numbers = [
27
+ random.randint(-10,10),
28
+ random.randint(-10,10),
29
+ random.randint(-10,10),
30
+ random.randint(-10,10)
31
+ ]
32
+
33
+ return {
34
+ "result_text": f"问题“{question_text}”执行“{option_text}”选项,结果完成了",
35
+ "score_text": f"导致四个维度增减情况为 {numbers[0]} {numbers[1]} {numbers[2]} {numbers[3]}",
36
+ "deltas": numbers
37
+ }
38
+
39
+ def typePUA(a):
40
+
41
+ x = '0' if a[0] <= 50 else '1'
42
+ y = '0' if a[1] <= 50 else '1'
43
+ z = '0' if a[2] <= 50 else '1'
44
+ w = '0' if a[3] <= 50 else '1'
45
+
46
+ puatype = ''.join([x,y,z,w])
47
+
48
+ pua = {
49
+ "0000": "1 反PUA斗士",
50
+ "0001": "2",
51
+ "0010": "3",
52
+ "0011": "4",
53
+ "0100": "5",
54
+ "0101": "6",
55
+ "0110": "7",
56
+ "0111": "8",
57
+ "1000": "9",
58
+ "1001": "10",
59
+ "1010": "11",
60
+ "1011": "12",
61
+ "1100": "13",
62
+ "1101": "14",
63
+ "1110": "15",
64
+ "1111": "16 天生牛马打工人",
65
+ }
66
+
67
+ return pua[puatype]
68
+
69
+ with gr.Blocks(css=css).queue() as demo:
70
+
71
+ # 0 - 开始页面
72
+ # 1 - 测评页面
73
+ # 2 - 结果页面
74
+ page_index = gr.State(0)
75
+
76
+ # 用户信息
77
+ user_info = gr.State({
78
+ "user_name": ""
79
+ })
80
+
81
+ # 当前轮次评测问答数据
82
+ qa_data = gr.State({
83
+ "total": 3,
84
+ "progress": 1,
85
+ "question_text": "",
86
+ "result_text": "",
87
+ "score_text": "",
88
+ "options": [
89
+ "",
90
+ "",
91
+ "",
92
+ ""
93
+ ],
94
+ "deltas": [0,0,0,0],
95
+ "canOptionA": True,
96
+ "canOptionB": True,
97
+ "canOptionC": True,
98
+ "canOptionD": False,
99
+ "canFillD": True,
100
+ "canRestart": True,
101
+ "canRefresh": True,
102
+ "canNext": False,
103
+ "nextName": "➡️ 下一题",
104
+ })
105
+
106
+ # 评测结果数据
107
+ result_data = gr.State({
108
+ "avdice_text": "",
109
+ "score_text": "",
110
+ "score": [50,50,50,50]
111
+ })
112
+
113
+ gr.Markdown("# 😅别再PUA啦:基于多智能体的被PUA指数心理测评游戏")
114
+ gr.Markdown("### 😋机智选择,远离PUA😈")
115
+
116
+ with gr.Tab("测评"):
117
+
118
+ # 0 - 开始页面
119
+ @gr.render(inputs=[page_index, user_info, qa_data, result_data])
120
+ def show_page_by_index(index, user, qa, result):
121
+
122
+ # 未输入昵称的主页
123
+ if index == 0:
124
+ gr.Image(elem_classes="show", value="./src/home.png", label="首页图", height=400, interactive=False)
125
+ with gr.Group():
126
+ with gr.Row():
127
+ user_name = gr.Textbox(placeholder="输入您的昵称", value=user["user_name"], container=False)
128
+ start = gr.Button(value="▶️ 开始测评", variant="primary")
129
+
130
+ def onStart(user_name, user=user, index=index, qa=qa, result=result):
131
+ if not user_name.strip():
132
+ raise gr.Error("输入您的昵称后才能进行测评!", duration=3)
133
+
134
+ user["user_name"] = user_name
135
+ index = 1
136
+ qa["progress"] = 1
137
+
138
+ res = get_new_question_and_options()
139
+ qa["question_text"] = res["question_text"]
140
+ qa["options"][0] = res["option_A"]
141
+ qa["options"][1] = res["option_B"]
142
+ qa["options"][2] = res["option_C"]
143
+
144
+ qa["canOptionA"] = True
145
+ qa["canOptionB"] = True
146
+ qa["canOptionC"] = True
147
+ qa["canOptionD"] = False
148
+ qa["canFillD"] = True
149
+ qa["canRestart"] = True
150
+ qa["canRefresh"] = True
151
+ qa["canNext"] = False
152
+
153
+ result["score"] = [50,50,50,50]
154
+
155
+ print(qa, result)
156
+ return index, user, qa, result
157
+
158
+ start.click(onStart, [user_name], [page_index, user_info, qa_data, result_data])
159
+
160
+ # 1 - 测评页面
161
+ elif index == 1:
162
+ gr.Markdown(f"您好,{user['user_name']}。请根据如下提示完成测评流程!小心不要被 PUA 到啦 ~")
163
+ with gr.Row():
164
+ with gr.Column():
165
+ gr.Image(elem_classes="show", value=f"./src/question_{qa['progress']}.jpg", label="事件图示", height=400, interactive=False)
166
+ gr.Slider(label=f"测评进度(共{qa['total']}题)", value=qa['progress'], minimum=0, maximum=qa["total"], step=1, interactive=False)
167
+ gr.Markdown("当前分数")
168
+ with gr.Group():
169
+ gr.Slider(label="维度1", value=result["score"][0], minimum=0, maximum=100, step=1, interactive=False)
170
+ gr.Slider(label="维度2", value=result["score"][1], minimum=0, maximum=100, step=1, interactive=False)
171
+ gr.Slider(label="维度3", value=result["score"][2], minimum=0, maximum=100, step=1, interactive=False)
172
+ gr.Slider(label="维度4", value=result["score"][3], minimum=0, maximum=100, step=1, interactive=False)
173
+ with gr.Column():
174
+ question_text = gr.TextArea(label="事件背景", value=qa["question_text"], placeholder="请等待生成", interactive=False, lines=4)
175
+ result_text = gr.TextArea(label="事件结果", value=qa["result_text"], placeholder="请根据事件背景,结合个人实际情况做出选择。注意,选择之间并无对错之分。", interactive=False, lines=4)
176
+ score_text = gr.TextArea(label="分数变更", value=qa["score_text"], placeholder="请根据事件背景,结合个人实际情况做出选择。注意,选择之间并无对错之分。", interactive=False, lines=4)
177
+ option_A_button = gr.Button(value=f"A: {qa['options'][0]}", interactive=qa["canOptionA"], elem_classes="btn")
178
+ option_B_button = gr.Button(value=f"B: {qa['options'][1]}", interactive=qa["canOptionB"], elem_classes="btn")
179
+ option_C_button = gr.Button(value=f"C: {qa['options'][2]}", interactive=qa["canOptionC"], elem_classes="btn")
180
+ with gr.Group():
181
+ option_D_button = gr.Button(value="D: 我选这个", interactive=qa["canOptionD"], elem_classes="btn")
182
+ option_D_text = gr.Textbox(show_label=False, value=qa['options'][3], placeholder="我有独特的主见", interactive=qa["canFillD"], container=False)
183
+
184
+ def onClickABC(question_text, btn, qa=qa, result=result):
185
+ option_text = btn[2:]
186
+ res = get_option_result(question_text, option_text)
187
+
188
+ qa["result_text"] = res["result_text"]
189
+ qa["score_text"] = res["score_text"]
190
+ qa["deltas"] = res["deltas"]
191
+ qa["canOptionA"] = False
192
+ qa["canOptionB"] = False
193
+ qa["canOptionC"] = False
194
+ qa["canOptionD"] = False
195
+ qa["canFillD"] = False
196
+ qa["canRefresh"] = False
197
+ qa["canNext"] = True
198
+
199
+ for i in range(len(result["score"])):
200
+ result["score"][i] = max(min(result["score"][i] + res["deltas"][i], 100), -100)
201
+ if qa["progress"] == qa["total"]:
202
+ qa["nextName"] = "✨查看结果"
203
+
204
+ print(qa["progress"],qa["total"])
205
+ return qa["result_text"], qa["score_text"], qa, result
206
+
207
+ def onClickD(question_text, option_D_text, qa=qa, result=result):
208
+ res = get_option_result(question_text, option_D_text)
209
+
210
+ qa["result_text"] = res["result_text"]
211
+ qa["score_text"] = res["score_text"]
212
+ qa["deltas"] = res["deltas"]
213
+ qa["canOptionA"] = False
214
+ qa["canOptionB"] = False
215
+ qa["canOptionC"] = False
216
+ qa["canOptionD"] = False
217
+ qa["canFillD"] = False
218
+ qa["canRefresh"] = False
219
+ qa["canNext"] = True
220
+
221
+ for i in range(len(result["score"])):
222
+ result["score"][i] = max(min(result["score"][i] + res["deltas"][i], 100), -100)
223
+
224
+ if qa["progress"] == qa["total"]:
225
+ qa["nextName"] = "✨查看结果"
226
+
227
+ print(qa, result)
228
+ return qa["result_text"], qa["score_text"], qa, result
229
+
230
+ def onChangeD(option_D_text, qa=qa):
231
+ qa["options"][3] = option_D_text
232
+ if option_D_text.strip():
233
+ qa["canOptionD"] = True
234
+ else:
235
+ qa["canOptionD"] = False
236
+
237
+ print(qa, result)
238
+ return qa
239
+
240
+ option_A_button.click(onClickABC, [question_text, option_A_button], [result_text, score_text, qa_data, result_data])
241
+ option_B_button.click(onClickABC, [question_text, option_B_button], [result_text, score_text, qa_data, result_data])
242
+ option_C_button.click(onClickABC, [question_text, option_C_button], [result_text, score_text, qa_data, result_data])
243
+ option_D_button.click(onClickD, [question_text, option_D_text], [result_text, score_text, qa_data, result_data])
244
+ option_D_text.blur(onChangeD, option_D_text, qa_data)
245
+
246
+ with gr.Row():
247
+ restart = gr.Button(value="↩️ 重新开始", interactive=qa["canRestart"])
248
+ refresh = gr.Button(value="🔄️ 刷新", interactive=qa["canRefresh"])
249
+ next = gr.Button(value=qa["nextName"], interactive=qa["canNext"])
250
+
251
+ def onRestart(index=index):
252
+ index = 0
253
+ return index
254
+
255
+ def onRefresh(qa=qa, result=result):
256
+ res = get_new_question_and_options()
257
+ qa["question_text"] = res["question_text"]
258
+ qa["result_text"] = ""
259
+ qa["score_text"] = ""
260
+ qa["options"][0] = res["option_A"]
261
+ qa["options"][1] = res["option_B"]
262
+ qa["options"][2] = res["option_C"]
263
+ qa["options"][3] = ""
264
+ qa["canOptionA"] = True
265
+ qa["canOptionB"] = True
266
+ qa["canOptionC"] = True
267
+ qa["canOptionD"] = False
268
+ qa["canFillD"] = True
269
+ qa["canRestart"] = True
270
+ qa["canRefresh"] = True
271
+ qa["canNext"] = False
272
+
273
+ print(qa, result)
274
+ return qa["question_text"] , qa["result_text"], qa["score_text"], qa["options"][3], qa, result
275
+
276
+ def onNext(index=index, qa=qa, result=result):
277
+ if qa["nextName"] == "➡️ 下一题":
278
+ qa["progress"] += 1
279
+
280
+ res = get_new_question_and_options()
281
+ qa["question_text"] = res["question_text"]
282
+ qa["result_text"] = ""
283
+ qa["score_text"] = ""
284
+ qa["options"][0] = res["option_A"]
285
+ qa["options"][1] = res["option_B"]
286
+ qa["options"][2] = res["option_C"]
287
+ qa["options"][3] = ""
288
+ qa["canOptionA"] = True
289
+ qa["canOptionB"] = True
290
+ qa["canOptionC"] = True
291
+ qa["canOptionD"] = False
292
+ qa["canFillD"] = True
293
+ qa["canRestart"] = True
294
+ qa["canRefresh"] = True
295
+ qa["canNext"] = False
296
+
297
+ print(qa, result)
298
+ return qa["question_text"] , qa["result_text"], qa["score_text"], qa["options"][3], index, qa, result
299
+ else:
300
+ qa["question_text"] = ""
301
+ qa["result_text"] = ""
302
+ qa["score_text"] = ""
303
+ qa["options"][0] = ""
304
+ qa["options"][1] = ""
305
+ qa["options"][2] = ""
306
+ qa["options"][3] = ""
307
+ qa["canOptionA"] = True
308
+ qa["canOptionB"] = True
309
+ qa["canOptionC"] = True
310
+ qa["canOptionD"] = False
311
+ qa["canFillD"] = True
312
+ qa["canRestart"] = True
313
+ qa["canRefresh"] = True
314
+ qa["canNext"] = False
315
+ index = 2
316
+ return "", "", "", "", index, qa, result
317
+
318
+ restart.click(onRestart, None, page_index)
319
+ refresh.click(onRefresh, None, [question_text, result_text, score_text, option_D_text, qa_data, result_data])
320
+ next.click(onNext, None, [question_text, result_text, score_text, option_D_text, page_index, qa_data, result_data])
321
+
322
+ # 2 - 结果页面
323
+ else:
324
+ gr.Markdown("### 测评结果")
325
+ with gr.Row():
326
+ with gr.Column():
327
+ gr.Image(elem_classes="result", value="./src/home.png", label="测评结果图示", height=400, interactive=False)
328
+ gr.Markdown("最终分数")
329
+ with gr.Group():
330
+ gr.Slider(label="维度1", value=result["score"][0], minimum=0, maximum=100, step=1, interactive=False)
331
+ gr.Slider(label="维度2", value=result["score"][1], minimum=0, maximum=100, step=1, interactive=False)
332
+ gr.Slider(label="维度3", value=result["score"][2], minimum=0, maximum=100, step=1, interactive=False)
333
+ gr.Slider(label="维度4", value=result["score"][3], minimum=0, maximum=100, step=1, interactive=False)
334
+ with gr.Column():
335
+ with gr.Row():
336
+ gr.Number(label="您的被PUA指数", value=sum(result["score"])/4, interactive=False)
337
+ gr.Textbox(label="您的被PUA类型", value=typePUA(result["score"]), interactive=False, placeholder="测评结束后生成")
338
+ gr.TextArea(label="您的测评结果解释", placeholder="测评结束后生成", interactive=False, lines=6)
339
+ gr.TextArea(label="可能的解决方案", placeholder="测评结束后生成", interactive=False, lines=14)
340
+ restart = gr.Button(value="↩️ 重新开始", interactive=qa["canRestart"])
341
+
342
+ def onRestart(index=index):
343
+ index = 0
344
+ return index
345
+
346
+ restart.click(onRestart, None, page_index)
347
+
348
+ gr.Button(value="如果对您有用,欢迎分享网站与测评结果 🥰", variant="primary")
349
+
350
+ # # 历史测评结果
351
+ # with gr.Tab("历史"):
352
+ # pass
353
+
354
+ # # 测评原理解释
355
+ # with gr.Tab("说明"):
356
+ # pass
357
+
358
+ # 作者声明
359
+ with gr.Tab("关于"):
360
+ gr.Markdown("")
361
+ gr.Markdown("**Datawhale AI夏令营(第四期)x 浪潮信息 “源”大模型应用开发活动**")
362
+ gr.Markdown("---")
363
+ gr.Markdown("**项目名称**:别再PUA啦:基于多智能体的被PUA指数心理测评游戏")
364
+ gr.Markdown("**项目Slogan**:机智选择,远离PUA")
365
+ gr.Markdown("**项目简介**:“别再PUA啦”是一款创新的心理测评游戏,它基于多智能体技术,旨在通过互动游戏的形式,测量个体对PUA策略的抵抗力和识别能力,从而帮助用户提高自我保护意识和社交技巧。")
366
+ gr.Markdown("**项目技术栈**:Yuan 2.0,RAG,Langchain,Muiti-Agent, Gradio")
367
+ gr.Markdown("**项目演示视频**:【TODO】")
368
+ gr.Markdown("**项目构建分析与复盘博客**:【TODO】")
369
+ gr.Markdown("---")
370
+ gr.Markdown("**作者**:胡钧耀(南开大学计算机视觉在读一年级直博生,个人研究兴趣方向为视觉AIGC)")
371
+ gr.Markdown("**联系方式**:微信(LittleDream_hjy),[Bilibili](https://space.bilibili.com/2042113),[GitHub](https://github.com/JunyaoHu),[个人主页](https://junyaohu.github.io)")
372
+ with gr.Row():
373
+ gr.Image(elem_classes="qrcode", value="./src/weixin.png", label="微信", height=250)
374
+ gr.Image(elem_classes="qrcode", value="./src/zanshang.png", label="感谢支持", height=250)
375
+
376
+ if __name__ == "__main__":
377
+ # demo.launch()
378
+ demo.launch(share=True)
src/home.png ADDED
src/question_1.jpg ADDED
src/weixin.png ADDED
src/zanshang.png ADDED