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