From d624a5879d08b4066fa670b44e37b276657ff932 Mon Sep 17 00:00:00 2001 From: pioc37juv <1245880206@qq.com> Date: Sat, 12 Oct 2024 16:02:45 +0800 Subject: [PATCH] ADD file via upload --- main.py | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..0f3a5e1 --- /dev/null +++ b/main.py @@ -0,0 +1,159 @@ +from fastapi import FastAPI, File, UploadFile, HTTPException, Body +from fastapi.responses import HTMLResponse +from starlette.middleware.cors import CORSMiddleware +from starlette.staticfiles import StaticFiles +from typing import Union, Dict, List +from io import BytesIO +import pandas as pd +import random + +app = FastAPI() + +# 假设你的静态文件存放在名为 'static' 的文件夹中 +app.mount("/static", StaticFiles(directory="static"), name="static") + +data: List[Dict[str, Union[str, int]]] = [] +students_scores = {} + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +@app.get("/", response_class=HTMLResponse) +async def read_root(): + # 返回 stu_roll.html 页面 + with open("stu_roll.html", "r", encoding="utf-8") as f: + return f.read() + + +@app.post("/upload") +async def list_upload(file: UploadFile = File(...)): + global data, students_scores + if file.content_type != "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": + return {"message": "错误的文件格式,请重新上传!"} + file_content = await file.read() + + # 使用 openpyxl 作为引擎读取 .xlsx 文件 + df = pd.read_excel(BytesIO(file_content), engine='openpyxl') + + if "学号" not in df.columns or "姓名" not in df.columns: + return {"message": "文件中缺少学号或姓名列!"} + data = [{"学号": str(row["学号"]).strip(), "姓名": row["姓名"], "积分": 0, "被点名次数": 0} for row in + df.to_dict(orient='records')] + students_scores = {student["学号"]: 0 for student in data} + print(f"Uploaded students: {students_scores}") + return {"message": "名单上传成功!", "students": data} # 返回学生数据 + + +@app.get("/roll") +def list_roll(enable_random_events: bool = False): + if not data: + return {"message": "还未上传学生名单,暂无任何数据!"} + total_score = sum(students_scores.values()) # 计算所有学生的总积分 + # 如果总积分为零,给所有学生相同的权重 + if total_score <= 0: + weights = [1] * len(data) # 所有学生的权重相同 + else: + # 计算权重 + weights = [total_score - students_scores[student["学号"]] for student in data] + # 使用权重进行随机选择 + chosen_student = random.choices(data, weights=weights, k=1)[0] + # 更新被点名次数 + chosen_student["被点名次数"] += 1 + print(f"Chosen student: {chosen_student['姓名']} - 被点名次数: {chosen_student['被点名次数']}") + # 打印调试信息 + print(f"Chosen student: {chosen_student}") + # 检查是否有转移权 + if chosen_student["被点名次数"] >= 3: + chosen_student["被点名次数"] = 0 + return {"学号": chosen_student["学号"], "姓名": chosen_student["姓名"], "转移权": True} + # 处理随机事件 + if enable_random_events: + random_event_result = handle_random_events(chosen_student) + return {"学号": chosen_student["学号"], "姓名": chosen_student["姓名"], "转移权": False, + "随机事件": random_event_result} + return {"学号": chosen_student["学号"], "姓名": chosen_student["姓名"], "转移权": False} + + +@app.get("/rank") +def list_rank(): + if not data: + return {"message": "请先上传学生名单!"} + sorted_data = sorted(data, key=lambda x: x["积分"], reverse=True) + return sorted_data + + +@app.post("/evaluate-answer") +async def evaluate_answer( + student_id: str = Body(...), + is_come: bool = Body(...), + can_repeat: bool = Body(...), + answer_correct: str = Body(...) +): + global students_scores, data + score_delta = 0 + print( + f"Received student_id: {student_id}, is_come: {is_come}, can_repeat: {can_repeat}, answer_correct: {answer_correct}") + # 检查学生 ID 是否存在 + if student_id not in students_scores: + print(f"Student ID {student_id} not found in scores.") + raise HTTPException(status_code=404, detail="Student not found.") + # 根据回答情况计算积分变化 + if is_come: + score_delta += 1 + if can_repeat: + score_delta += 0.5 + else: + score_delta -= 0.5 + if answer_correct == "完全正确": + score_delta += 3 + elif answer_correct == "部分正确": + score_delta += 1.5 + else: + score_delta -= 1 + # 更新 students_scores 字典 + students_scores[student_id] += score_delta + # 更新 data 列表中的积分 + for student in data: + if student["学号"] == student_id: + student["积分"] += score_delta + break + print(f"Score updated for student_id: {student_id}, new score: {students_scores[student_id]}") + return {"success": True} + + +def handle_random_events(chosen_student): + event = random.choice(["mdfucker", "士多啤梨", "吖食啦嘞", "abandon", "疯狂星期四V你50"]) + event_description = "" + if event == "surprise mdfucker": + print(f"{chosen_student['姓名']} surprise mdfucker!") + students_scores[chosen_student["学号"]] += 2 + chosen_student["积分"] += 2 + event_description = "surprise mdfucker" + elif event == "士多啤梨": + print(f"{chosen_student['姓名']} 士多啤梨!") + students_scores[chosen_student["学号"]] += 1 + chosen_student["积分"] += 1 + event_description = "士多啤梨" + if event == "吖食啦嘞": + print(f"{chosen_student['姓名']} 吖食啦嘞!") + students_scores[chosen_student["学号"]] -= 2 + chosen_student["积分"] -= 2 + event_description = "吖食啦嘞" + if event == "abandon": + print(f"{chosen_student['姓名']} abandon!") + students_scores[chosen_student["学号"]] -= 1 + chosen_student["积分"] -= 1 + event_description = "abandon" + elif event == "疯狂星期四V你50": + if chosen_student["积分"] % 50 == 0: # 积分是50的因数 + print(f"{chosen_student['姓名']} 疯狂星期四V你50!") + students_scores[chosen_student["学号"]] += 1.5 + chosen_student["积分"] += 1.5 + event_description = "疯狂星期四V你50" + return event_description