feat: 添加学生成绩排行榜功能
- 新增 app.py 和 main.py 文件,实现学生成绩排行榜功能 - 添加 CSV 文件处理逻辑,支持成绩数据导入 - 实现成绩排行榜的图形化展示,包括搜索、重新加载等功能 - 新增成绩统计和可视化功能- 添加 .idea 相关配置文件,配置项目环境和样式
This commit is contained in:
commit
58d6e90c39
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
10
.idea/autopai.iml
generated
Normal file
10
.idea/autopai.iml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.10 (autopai)" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
.idea/encodings.xml
generated
Normal file
6
.idea/encodings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$/score.csv" charset="GBK" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
14
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
14
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="numpy" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
10
.idea/material_theme_project_new.xml
generated
Normal file
10
.idea/material_theme_project_new.xml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="MaterialThemeProjectNewConfig">
|
||||||
|
<option name="metadata">
|
||||||
|
<MTProjectMetadataState>
|
||||||
|
<option name="userId" value="-1a3ed073:19700c566e2:-7ffa" />
|
||||||
|
</MTProjectMetadataState>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.10 (autopai)" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (autopai)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/autopai.iml" filepath="$PROJECT_DIR$/.idea/autopai.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
139
app.py
Normal file
139
app.py
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
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)
|
||||||
42
main.py
Normal file
42
main.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import csv
|
||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk, messagebox
|
||||||
|
def process_csv(filename):
|
||||||
|
with open(filename, 'r') as csvfile:
|
||||||
|
contents = csv.DictReader(csvfile)
|
||||||
|
infos=list(contents)
|
||||||
|
infos=sorted(infos, key=lambda x:int(x['成绩']),reverse=True)
|
||||||
|
return infos
|
||||||
|
|
||||||
|
|
||||||
|
window = tk.Tk()
|
||||||
|
window.title('学生成绩排行榜')
|
||||||
|
window.geometry('500x400')
|
||||||
|
window.configure(bg='#f0f4f7')
|
||||||
|
|
||||||
|
# 设置统一字体
|
||||||
|
style = ttk.Style()
|
||||||
|
style.configure('Treeview', font=('华文行楷', 12), rowheight=28)
|
||||||
|
style.configure('Treeview.Heading', font=('华文行楷', 13, 'bold'))
|
||||||
|
|
||||||
|
# 标题标签
|
||||||
|
title_label = tk.Label(window, text="学生成绩排行榜", bg='#f0f4f7', fg='#336699',font=('华文行楷', 20, 'bold'))
|
||||||
|
title_label.pack(pady=15)
|
||||||
|
|
||||||
|
# 表格
|
||||||
|
columns = ('姓名', '成绩')
|
||||||
|
tree = ttk.Treeview(window, columns=columns, show='headings', height=12)
|
||||||
|
|
||||||
|
tree.heading('姓名', text='姓名')
|
||||||
|
tree.heading('成绩', text='成绩')
|
||||||
|
tree.column('姓名', anchor='center', width=200)
|
||||||
|
tree.column('成绩', anchor='center', width=100)
|
||||||
|
|
||||||
|
infos = process_csv('score.csv')
|
||||||
|
for info in infos:
|
||||||
|
tree.insert('', tk.END, values=(info['姓名'], info['成绩']))
|
||||||
|
|
||||||
|
tree.pack(pady=10)
|
||||||
|
|
||||||
|
# 运行主窗口
|
||||||
|
window.mainloop()
|
||||||
4
score.csv
Normal file
4
score.csv
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
姓名,成绩
|
||||||
|
张三,85
|
||||||
|
李四,90
|
||||||
|
王五,100
|
||||||
|
16
students.csv
Normal file
16
students.csv
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
姓名,成绩
|
||||||
|
张三,85
|
||||||
|
李四,90
|
||||||
|
王五,100
|
||||||
|
赵六,72
|
||||||
|
孙七,59
|
||||||
|
周八,66
|
||||||
|
吴九,88
|
||||||
|
郑十,93
|
||||||
|
冯十一,45
|
||||||
|
陈十二,76
|
||||||
|
褚十三,99
|
||||||
|
卫十四,61
|
||||||
|
蒋十五,38
|
||||||
|
沈十六,82
|
||||||
|
韩十七,91
|
||||||
|
Loading…
x
Reference in New Issue
Block a user