import tkinter as tk from tkinter import ttk, messagebox, scrolledtext import numpy as np from collections import defaultdict class AutoArtRatingSystem: """全自动艺术评分系统核心逻辑""" def __init__(self): self.scores = {} # {作品ID: [评分1, 评分2, ...]} self.effective_scores = {} # {作品ID: 有效得分} self.ranked_works = [] # [(作品ID, 得分), ...] 按得分降序排列 self.judge_stats = {} # {评委ID: {'平均打分':..., '得分范围':..., '离散程度':..., '异常评分':...}} def auto_calculate(self): """自动执行所有统计分析""" if not self.scores: return # 1. 计算有效得分(自动去掉最高最低分) self.effective_scores = { pid: round( sum(sorted(score_list)[1:-1]) / max(1, len(score_list) - 2), 2 ) for pid, score_list in self.scores.items() } # 2. 自动生成作品排名 self.ranked_works = sorted( self.effective_scores.items(), key=lambda x: x[1], reverse=True ) # 3. 自动分析评委打分 judge_scores = defaultdict(list) for pid, score_list in self.scores.items(): for judge_idx, score in enumerate(score_list): judge_id = f"评委{judge_idx + 1}" judge_scores[judge_id].append(score) self.judge_stats = {} for judge_id, score_list in judge_scores.items(): avg = round(np.mean(score_list), 2) score_range = f"{min(score_list)}-{max(score_list)}" std_dev = round(np.std(score_list), 2) # 自动识别异常评分(超出均值±1.5标准差) threshold = 1.5 * std_dev outliers = [ s for s in score_list if not (avg - threshold <= s <= avg + threshold) ] self.judge_stats[judge_id] = { '平均打分': avg, '得分范围': score_range, '离散程度': std_dev, '异常评分': outliers if outliers else "无" } def get_report(self): """获取完整统计报告""" self.auto_calculate() report = "=== 自动艺术评分统计报告 ===\n\n" # 1. 有效得分详情 report += "【有效得分计算】\n" for pid, score in self.effective_scores.items(): raw_scores = self.scores[pid] report += f"作品 {pid}: 原始评分[{', '.join(map(str, raw_scores))}] " report += f"→ 有效得分{score}\n" report += "\n" # 2. 作品排名 report += "【作品最终排名】\n" for rank, (pid, score) in enumerate(self.ranked_works, 1): report += f"第{rank}名: 作品{pid} ({score}分)\n" report += "\n" # 3. 评委分析 report += "【评委评分分析】\n" for judge_id, stats in self.judge_stats.items(): report += f"{judge_id}:\n" report += f" • 平均打分: {stats['平均打分']}\n" report += f" • 得分范围: {stats['得分范围']}\n" report += f" • 离散程度: {stats['离散程度']}\n" outliers = stats['异常评分'] outliers_str = ', '.join(map(str, outliers)) if isinstance(outliers, list) else outliers report += f" • 异常评分: {outliers_str}\n\n" return report class AutoRatingApp: """全自动艺术评分系统GUI界面""" def __init__(self, root): self.root = root self.root.title("全自动艺术评分系统") self.root.geometry("900x700") self.rating_system = AutoArtRatingSystem() # 输入区域 input_frame = ttk.LabelFrame(root, text="评分数据输入") input_frame.pack(fill="x", padx=10, pady=5) # 作品ID输入 ttk.Label(input_frame, text="作品ID:").grid(row=0, column=0, padx=5, sticky="e") self.piece_id = tk.StringVar() ttk.Entry(input_frame, textvariable=self.piece_id, width=10).grid(row=0, column=1, padx=5) # 评委评分输入 ttk.Label(input_frame, text="评委评分(空格分隔):").grid(row=0, column=2, padx=5, sticky="e") self.scores_input = tk.StringVar() ttk.Entry(input_frame, textvariable=self.scores_input, width=40).grid(row=0, column=3, padx=5) # 添加按钮 ttk.Button(input_frame, text="添加评分", command=self.add_score).grid(row=0, column=4, padx=10) # 数据展示区 data_frame = ttk.LabelFrame(root, text="当前评分数据") data_frame.pack(fill="both", expand=True, padx=10, pady=5) # 数据表格 columns = ("作品ID", "评委评分", "有效得分") self.tree = ttk.Treeview(data_frame, columns=columns, show="headings") for col in columns: self.tree.heading(col, text=col) self.tree.column(col, width=150 if col == "评委评分" else 100) self.tree.pack(fill="both", expand=True) # 报告区域 report_frame = ttk.LabelFrame(root, text="自动统计报告") report_frame.pack(fill="both", expand=True, padx=10, pady=5) self.report_text = scrolledtext.ScrolledText(report_frame, wrap=tk.WORD, width=80, height=15) self.report_text.pack(fill="both", expand=True) # 底部按钮 btn_frame = tk.Frame(root) btn_frame.pack(fill="x", padx=10, pady=5) ttk.Button(btn_frame, text="清除所有数据", command=self.clear_data).pack(side="left", padx=5) ttk.Button(btn_frame, text="刷新报告", command=self.update_report).pack(side="right", padx=5) def validate_input(self): """自动验证输入数据""" piece_id = self.piece_id.get().strip() score_str = self.scores_input.get().strip() if not piece_id: messagebox.showerror("错误", "作品ID不能为空") return None if piece_id in self.rating_system.scores: messagebox.showerror("错误", f"作品 {piece_id} 已存在") return None try: scores = list(map(float, score_str.split())) if len(scores) < 3: messagebox.showerror("错误", "至少需要3个评委评分") return None if any(s < 0 or s > 100 for s in scores): messagebox.showerror("错误", "评分必须在0-100之间") return None return piece_id, scores except ValueError: messagebox.showerror("错误", "评分必须是数字,用空格分隔") return None def add_score(self): """添加评分数据并自动更新统计""" data = self.validate_input() if not data: return piece_id, scores = data self.rating_system.scores[piece_id] = scores # 更新表格显示 self.tree.insert( "", "end", values=( piece_id, ", ".join(map(str, scores)), self.rating_system.effective_scores.get(piece_id, "计算中...") ) ) # 清空输入框 self.piece_id.set("") self.scores_input.set("") # 自动更新报告 self.update_report() def update_report(self): """自动更新统计报告""" self.report_text.delete(1.0, tk.END) self.report_text.insert(tk.END, self.rating_system.get_report()) def clear_data(self): """清除所有数据并重置界面""" self.rating_system = AutoArtRatingSystem() self.tree.delete(*self.tree.get_children()) self.report_text.delete(1.0, tk.END) messagebox.showinfo("提示", "所有数据已清除") if __name__ == "__main__": root = tk.Tk() app = AutoRatingApp(root) root.mainloop()