AutoRS/app.py
sairate 58d6e90c39 feat: 添加学生成绩排行榜功能
- 新增 app.py 和 main.py 文件,实现学生成绩排行榜功能
- 添加 CSV 文件处理逻辑,支持成绩数据导入
- 实现成绩排行榜的图形化展示,包括搜索、重新加载等功能
- 新增成绩统计和可视化功能- 添加 .idea 相关配置文件,配置项目环境和样式
2025-05-24 14:33:59 +08:00

140 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import csv
import tkinter as tk
from tkinter import ttk, messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
def process_csv(filename):
try:
with open(filename, 'r', encoding='utf-8-sig') as csvfile:
reader = csv.DictReader(csvfile)
data = list(reader)
data = sorted(data, key=lambda x: int(x['成绩']), reverse=True)
return data
except FileNotFoundError:
messagebox.showerror("错误", f"文件未找到: {filename}")
return []
except ValueError:
messagebox.showerror("错误", "成绩格式错误,请确保为整数")
return []
except Exception as e:
messagebox.showerror("错误", f"处理CSV时出错{e}")
return []
def show_chart(infos, parent):
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 支持中文
matplotlib.rcParams['axes.unicode_minus'] = False
names = [i['姓名'] for i in infos]
scores = [int(i['成绩']) for i in infos]
fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(names, scores, color='#66b3ff')
ax.set_title('学生成绩柱状图')
ax.set_ylabel('成绩')
ax.set_xlabel('姓名')
plt.xticks(rotation=45)
canvas = FigureCanvasTkAgg(fig, master=parent)
canvas.draw()
canvas.get_tk_widget().pack(pady=10)
def display_scores(infos):
window = tk.Tk()
window.title('学生成绩排行榜')
window.geometry('650x700')
window.configure(bg='#f0f4f7')
# 标题
tk.Label(window, text="学生成绩排行榜", bg='#f0f4f7', fg='#336699',
font=('Arial', 20, 'bold')).pack(pady=10)
# 搜索框
search_frame = tk.Frame(window, bg='#f0f4f7')
search_frame.pack()
tk.Label(search_frame, text="搜索姓名:", bg='#f0f4f7').pack(side=tk.LEFT)
search_entry = tk.Entry(search_frame)
search_entry.pack(side=tk.LEFT)
# 表格
columns = ('姓名', '成绩')
tree = ttk.Treeview(window, columns=columns, show='headings', height=10)
tree.heading('姓名', text='姓名')
tree.heading('成绩', text='成绩')
tree.column('姓名', anchor='center', width=200)
tree.column('成绩', anchor='center', width=100)
style = ttk.Style()
style.configure('Treeview', font=('Arial', 12), rowheight=28)
style.configure('Treeview.Heading', font=('Arial', 13, 'bold'))
def populate_table(data):
for item in tree.get_children():
tree.delete(item)
for info in data:
score = int(info['成绩'])
tag = 'normal'
if score >= 90:
tag = 'excellent'
elif score < 60:
tag = 'fail'
tree.insert('', tk.END, values=(info['姓名'], info['成绩']), tags=(tag,))
# 打标签上色
tree.tag_configure('excellent', background='#d4edda') # 绿色
tree.tag_configure('fail', background='#f8d7da') # 红色
populate_table(infos)
tree.pack(pady=10)
# 成绩统计
def show_stats(data):
if not data:
return
scores = [int(i['成绩']) for i in data]
avg = sum(scores) / len(scores)
highest = max(scores)
count = len(scores)
stats_label.config(text=f"平均分:{avg:.2f},最高分:{highest},总人数:{count}")
stats_label = tk.Label(window, bg='#f0f4f7', font=('Arial', 12))
stats_label.pack(pady=5)
show_stats(infos)
# 搜索功能
def search():
name = search_entry.get().strip()
if not name:
populate_table(infos)
show_stats(infos)
return
filtered = [i for i in infos if name in i['姓名']]
populate_table(filtered)
show_stats(filtered)
tk.Button(search_frame, text="搜索", command=search).pack(side=tk.LEFT, padx=5)
# 重新加载按钮
def reload():
new_data = process_csv('score.csv')
if new_data:
nonlocal infos
infos = new_data
populate_table(infos)
show_stats(infos)
tk.Button(window, text="重新加载成绩", command=reload).pack(pady=10)
# 可视化柱状图
show_chart(infos, window)
window.mainloop()
if __name__ == "__main__":
score_data = process_csv('students.csv')
if score_data:
display_scores(score_data)