import gradio as gr import random import time css = ''' .show img {height: 320px} .result img {height: 320px} .qrcode img {height: 225px} .btn { justify-content: normal } ''' def get_new_question_and_options(): time.sleep(1.5) number = random.randint(1,65536) return { "question_text": f"问题{number}是这样的。", "option_A": f"问题{number}给出的选项A,吃饭", "option_B": f"问题{number}给出的选项B,睡觉", "option_C": f"问题{number}给出的选项C,打豆豆", } def get_option_result(question_text, option_text): time.sleep(1.5) numbers = [ random.randint(-10,10), random.randint(-10,10), random.randint(-10,10), random.randint(-10,10) ] return { "result_text": f"问题“{question_text}”执行“{option_text}”选项,结果完成了", "score_text": f"导致四个维度增减情况为 {numbers[0]} {numbers[1]} {numbers[2]} {numbers[3]}", "deltas": numbers } def typePUA(a): x = '0' if a[0] <= 50 else '1' y = '0' if a[1] <= 50 else '1' z = '0' if a[2] <= 50 else '1' w = '0' if a[3] <= 50 else '1' puatype = ''.join([x,y,z,w]) pua = { "0000": "1 反PUA斗士", "0001": "2", "0010": "3", "0011": "4", "0100": "5", "0101": "6", "0110": "7", "0111": "8", "1000": "9", "1001": "10", "1010": "11", "1011": "12", "1100": "13", "1101": "14", "1110": "15", "1111": "16 天生牛马打工人", } return pua[puatype] with gr.Blocks(css=css).queue() as demo: # 0 - 开始页面 # 1 - 测评页面 # 2 - 结果页面 page_index = gr.State(0) # 用户信息 user_info = gr.State({ "user_name": "" }) # 当前轮次评测问答数据 qa_data = gr.State({ "total": 3, "progress": 1, "question_text": "", "result_text": "", "score_text": "", "options": [ "", "", "", "" ], "deltas": [0,0,0,0], "canOptionA": True, "canOptionB": True, "canOptionC": True, "canOptionD": False, "canFillD": True, "canRestart": True, "canRefresh": True, "canNext": False, "nextName": "➡️ 下一题", }) # 评测结果数据 result_data = gr.State({ "avdice_text": "", "score_text": "", "score": [50,50,50,50] }) gr.Markdown("# 😅别再PUA啦:基于多智能体的被PUA指数心理测评游戏") gr.Markdown("### 😋机智选择,远离PUA😈") with gr.Tab("测评"): # 0 - 开始页面 @gr.render(inputs=[page_index, user_info, qa_data, result_data]) def show_page_by_index(index, user, qa, result): # 未输入昵称的主页 if index == 0: gr.Image(elem_classes="show", value="./src/home.png", label="首页图", height=400, interactive=False) with gr.Group(): with gr.Row(): user_name = gr.Textbox(placeholder="输入您的昵称", value=user["user_name"], container=False) start = gr.Button(value="▶️ 开始测评", variant="primary") def onStart(user_name, user=user, index=index, qa=qa, result=result): if not user_name.strip(): raise gr.Error("输入您的昵称后才能进行测评!", duration=3) user["user_name"] = user_name index = 1 qa["progress"] = 1 res = get_new_question_and_options() qa["question_text"] = res["question_text"] qa["options"][0] = res["option_A"] qa["options"][1] = res["option_B"] qa["options"][2] = res["option_C"] qa["canOptionA"] = True qa["canOptionB"] = True qa["canOptionC"] = True qa["canOptionD"] = False qa["canFillD"] = True qa["canRestart"] = True qa["canRefresh"] = True qa["canNext"] = False result["score"] = [50,50,50,50] print(qa, result) return index, user, qa, result start.click(onStart, [user_name], [page_index, user_info, qa_data, result_data]) # 1 - 测评页面 elif index == 1: gr.Markdown(f"您好,{user['user_name']}。请根据如下提示完成测评流程!小心不要被 PUA 到啦 ~") with gr.Row(): with gr.Column(): gr.Image(elem_classes="show", value=f"./src/question_{qa['progress']}.jpg", label="事件图示", height=400, interactive=False) gr.Slider(label=f"测评进度(共{qa['total']}题)", value=qa['progress'], minimum=0, maximum=qa["total"], step=1, interactive=False) gr.Markdown("当前分数") with gr.Group(): gr.Slider(label="维度1", value=result["score"][0], minimum=0, maximum=100, step=1, interactive=False) gr.Slider(label="维度2", value=result["score"][1], minimum=0, maximum=100, step=1, interactive=False) gr.Slider(label="维度3", value=result["score"][2], minimum=0, maximum=100, step=1, interactive=False) gr.Slider(label="维度4", value=result["score"][3], minimum=0, maximum=100, step=1, interactive=False) with gr.Column(): question_text = gr.TextArea(label="事件背景", value=qa["question_text"], placeholder="请等待生成", interactive=False, lines=4) result_text = gr.TextArea(label="事件结果", value=qa["result_text"], placeholder="请根据事件背景,结合个人实际情况做出选择。注意,选择之间并无对错之分。", interactive=False, lines=4) score_text = gr.TextArea(label="分数变更", value=qa["score_text"], placeholder="请根据事件背景,结合个人实际情况做出选择。注意,选择之间并无对错之分。", interactive=False, lines=4) option_A_button = gr.Button(value=f"A: {qa['options'][0]}", interactive=qa["canOptionA"], elem_classes="btn") option_B_button = gr.Button(value=f"B: {qa['options'][1]}", interactive=qa["canOptionB"], elem_classes="btn") option_C_button = gr.Button(value=f"C: {qa['options'][2]}", interactive=qa["canOptionC"], elem_classes="btn") with gr.Group(): option_D_button = gr.Button(value="D: 我选这个", interactive=qa["canOptionD"], elem_classes="btn") option_D_text = gr.Textbox(show_label=False, value=qa['options'][3], placeholder="我有独特的主见", interactive=qa["canFillD"], container=False) def onClickABC(question_text, btn, qa=qa, result=result): option_text = btn[2:] res = get_option_result(question_text, option_text) qa["result_text"] = res["result_text"] qa["score_text"] = res["score_text"] qa["deltas"] = res["deltas"] qa["canOptionA"] = False qa["canOptionB"] = False qa["canOptionC"] = False qa["canOptionD"] = False qa["canFillD"] = False qa["canRefresh"] = False qa["canNext"] = True for i in range(len(result["score"])): result["score"][i] = max(min(result["score"][i] + res["deltas"][i], 100), -100) if qa["progress"] == qa["total"]: qa["nextName"] = "✨查看结果" print(qa["progress"],qa["total"]) return qa["result_text"], qa["score_text"], qa, result def onClickD(question_text, option_D_text, qa=qa, result=result): res = get_option_result(question_text, option_D_text) qa["result_text"] = res["result_text"] qa["score_text"] = res["score_text"] qa["deltas"] = res["deltas"] qa["canOptionA"] = False qa["canOptionB"] = False qa["canOptionC"] = False qa["canOptionD"] = False qa["canFillD"] = False qa["canRefresh"] = False qa["canNext"] = True for i in range(len(result["score"])): result["score"][i] = max(min(result["score"][i] + res["deltas"][i], 100), -100) if qa["progress"] == qa["total"]: qa["nextName"] = "✨查看结果" print(qa, result) return qa["result_text"], qa["score_text"], qa, result def onChangeD(option_D_text, qa=qa): qa["options"][3] = option_D_text if option_D_text.strip(): qa["canOptionD"] = True else: qa["canOptionD"] = False print(qa, result) return qa option_A_button.click(onClickABC, [question_text, option_A_button], [result_text, score_text, qa_data, result_data]) option_B_button.click(onClickABC, [question_text, option_B_button], [result_text, score_text, qa_data, result_data]) option_C_button.click(onClickABC, [question_text, option_C_button], [result_text, score_text, qa_data, result_data]) option_D_button.click(onClickD, [question_text, option_D_text], [result_text, score_text, qa_data, result_data]) option_D_text.blur(onChangeD, option_D_text, qa_data) with gr.Row(): restart = gr.Button(value="↩️ 重新开始", interactive=qa["canRestart"]) refresh = gr.Button(value="🔄️ 刷新", interactive=qa["canRefresh"]) next = gr.Button(value=qa["nextName"], interactive=qa["canNext"]) def onRestart(index=index): index = 0 return index def onRefresh(qa=qa, result=result): res = get_new_question_and_options() qa["question_text"] = res["question_text"] qa["result_text"] = "" qa["score_text"] = "" qa["options"][0] = res["option_A"] qa["options"][1] = res["option_B"] qa["options"][2] = res["option_C"] qa["options"][3] = "" qa["canOptionA"] = True qa["canOptionB"] = True qa["canOptionC"] = True qa["canOptionD"] = False qa["canFillD"] = True qa["canRestart"] = True qa["canRefresh"] = True qa["canNext"] = False print(qa, result) return qa["question_text"] , qa["result_text"], qa["score_text"], qa["options"][3], qa, result def onNext(index=index, qa=qa, result=result): if qa["nextName"] == "➡️ 下一题": qa["progress"] += 1 res = get_new_question_and_options() qa["question_text"] = res["question_text"] qa["result_text"] = "" qa["score_text"] = "" qa["options"][0] = res["option_A"] qa["options"][1] = res["option_B"] qa["options"][2] = res["option_C"] qa["options"][3] = "" qa["canOptionA"] = True qa["canOptionB"] = True qa["canOptionC"] = True qa["canOptionD"] = False qa["canFillD"] = True qa["canRestart"] = True qa["canRefresh"] = True qa["canNext"] = False print(qa, result) return qa["question_text"] , qa["result_text"], qa["score_text"], qa["options"][3], index, qa, result else: qa["question_text"] = "" qa["result_text"] = "" qa["score_text"] = "" qa["options"][0] = "" qa["options"][1] = "" qa["options"][2] = "" qa["options"][3] = "" qa["canOptionA"] = True qa["canOptionB"] = True qa["canOptionC"] = True qa["canOptionD"] = False qa["canFillD"] = True qa["canRestart"] = True qa["canRefresh"] = True qa["canNext"] = False index = 2 return "", "", "", "", index, qa, result restart.click(onRestart, None, page_index) refresh.click(onRefresh, None, [question_text, result_text, score_text, option_D_text, qa_data, result_data]) next.click(onNext, None, [question_text, result_text, score_text, option_D_text, page_index, qa_data, result_data]) # 2 - 结果页面 else: gr.Markdown("### 测评结果") with gr.Row(): with gr.Column(): gr.Image(elem_classes="result", value="./src/home.png", label="测评结果图示", height=400, interactive=False) gr.Markdown("最终分数") with gr.Group(): gr.Slider(label="维度1", value=result["score"][0], minimum=0, maximum=100, step=1, interactive=False) gr.Slider(label="维度2", value=result["score"][1], minimum=0, maximum=100, step=1, interactive=False) gr.Slider(label="维度3", value=result["score"][2], minimum=0, maximum=100, step=1, interactive=False) gr.Slider(label="维度4", value=result["score"][3], minimum=0, maximum=100, step=1, interactive=False) with gr.Column(): with gr.Row(): gr.Number(label="您的被PUA指数", value=sum(result["score"])/4, interactive=False) gr.Textbox(label="您的被PUA类型", value=typePUA(result["score"]), interactive=False, placeholder="测评结束后生成") gr.TextArea(label="您的测评结果解释", placeholder="测评结束后生成", interactive=False, lines=6) gr.TextArea(label="可能的解决方案", placeholder="测评结束后生成", interactive=False, lines=14) restart = gr.Button(value="↩️ 重新开始", interactive=qa["canRestart"]) def onRestart(index=index): index = 0 return index restart.click(onRestart, None, page_index) gr.Button(value="如果对您有用,欢迎分享网站与测评结果 🥰", variant="primary") # # 历史测评结果 # with gr.Tab("历史"): # pass # # 测评原理解释 # with gr.Tab("说明"): # pass # 作者声明 with gr.Tab("关于"): gr.Markdown("") gr.Markdown("**Datawhale AI夏令营(第四期)x 浪潮信息 “源”大模型应用开发活动**") gr.Markdown("---") gr.Markdown("**项目名称**:别再PUA啦:基于多智能体的被PUA指数心理测评游戏") gr.Markdown("**项目Slogan**:机智选择,远离PUA") gr.Markdown("**项目简介**:“别再PUA啦”是一款创新的心理测评游戏,它基于多智能体技术,旨在通过互动游戏的形式,测量个体对PUA策略的抵抗力和识别能力,从而帮助用户提高自我保护意识和社交技巧。") gr.Markdown("**项目技术栈**:Yuan 2.0,RAG,Langchain,Muiti-Agent, Gradio") gr.Markdown("**项目演示视频**:【TODO】") gr.Markdown("**项目构建分析与复盘博客**:【TODO】") gr.Markdown("---") gr.Markdown("**作者**:胡钧耀(南开大学计算机视觉在读一年级直博生,个人研究兴趣方向为视觉AIGC)") gr.Markdown("**联系方式**:微信(LittleDream_hjy),[Bilibili](https://space.bilibili.com/2042113),[GitHub](https://github.com/JunyaoHu),[个人主页](https://junyaohu.github.io)") with gr.Row(): gr.Image(elem_classes="qrcode", value="./src/weixin.png", label="微信", height=250) gr.Image(elem_classes="qrcode", value="./src/zanshang.png", label="感谢支持", height=250) if __name__ == "__main__": # demo.launch() demo.launch(share=True)