概述

程序思路

源代码

1. 概述

迫切想知道自己有多菜…

能从年级每个人每项成绩的表格中抽取数据并计算出每个人的成绩,同时输出排名,平均分等

如果数据格式改变,在代码中修改信息对应的列号即可(以后如果有数据的话应该还可以用)

2. 程序思路

抽取指定表(或者全部表)中的名字做成集合

根据名字集合初始化学生对象字典

遍历所有项,根据名字找到字典中的对应对象,将分数和学分做成结构体存入学生类,得到学生列表

对所有学生类使用求平均分函数

对学生列表进行排序

已得到所有学生及其对应分数和排名,平均分随便算一下就好了

3. 源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# 数据文件
SCOREFILE = "scores.xlsx"
# 名字列表序号
NAME = "C"
# 分数列表序号
TOTALSCORE = "M"
# 学分列表序号
CREDIT = "K"
# 用于转化非数字分数,需要考虑各种奇形怪状的符号...
SCOREMAP = {
'A+':98,
'A':92,
'A-':87,
'B+':83,
'B':79,
'B-':76,
'C+':73,
'C':70,
'C-':66,
'D':62,
'F':30,
'零分':0,
'A+': 98,
'A-': 87,
'B+': 83,
'B-': 76,
'C+': 73,
'C-': 66,
}

# 用于读取xslx表中的数据
from openpyxl import load_workbook

# 课程结构体
class Course:
def __init__(self,score,credit):
self.score=score
self.credit=credit


# 学生类
class Student:
def __init__(self,name):
self.name=name
self.coursecount = 0
self.average = 0
# 用于存储课程结构体列表
self.course=[]

# 计算本学生的平均成绩
def getAverage(self):
totalcredit = 0
totalscore = 0
for course in self.course:
totalscore = totalscore + course.score*course.credit
totalcredit = totalcredit + course.credit
self.average = totalscore/totalcredit

return self.average



# 读取文件内容
def readFile(filename=SCOREFILE):
scoredata = load_workbook(filename)
return scoredata

# 抽取一个sheet做成字典
def getSheet(scoresheet):
# 抽取名字
namelist=[cell.value for cell in scoresheet[NAME]][1:]
nameset=set(namelist)

# 抽取成绩
scorelist=[cell.value for cell in scoresheet[TOTALSCORE]][1:]

# 抽取学分
creditlist=[cell.value for cell in scoresheet[CREDIT]][1:]


# 用于存放当前sheet的学生表
studentlist={}
for i in nameset:
studentlist[i]=Student(i)


# 对除了类别的项目进行遍历
for index in range(len(namelist)):
# 存放本条信息
if scorelist[index] in SCOREMAP:
course = Course(SCOREMAP[scorelist[index]],float(creditlist[index]))
elif scorelist[index] == "及格":
continue
else:
course = Course(float(scorelist[index]),float(creditlist[index]))
studentlist[namelist[index]].course.append(course)

# 返回学生类对象列表
return studentlist


# 执行入口
if __name__ == "__main__":

# 读取数据并列出专业列表
print("data loading...")
scoredata = readFile()
major = '计算机'
print("ready! \r\n 专业列表:")
print("\r\n".join(scoredata.sheetnames))

# 允许多次操作
while(True):
major = input("请输入要计算的专业,输入all查看总排名,输入\'exit\'退出程序:\t")

if major == "exit":
break

if major == "all":
# 初始化分数列表
scorelist = []

# 对所有专业进行操作
for stumajor in scoredata.sheetnames:
# 抽取专业数据表
studata = scoredata.get_sheet_by_name(stumajor)
# 从专业数据表中抽取学生对象列表
stulist = getSheet(studata)
# 生成(分数,名字)列表 并添加到分数列表中
scorelist += [(stulist[stu].getAverage(),stulist[stu].name) for stu in stulist]

# 计算总分
total = sum([stu[0] for stu in scorelist])

# 将分数列表排序得到排名
scorelist.sort(reverse=True)
for i in range(len(scorelist)):
# 可以输出名字,但是没必要
print("{} \t {:.3f}: \t排名 {}".format(scorelist[i][1],scorelist[i][0],i+1))
# print("{:.3f}: \t排名 {}".format(scorelist[i][0], i + 1))

#平均分
print("平均分:\t%f" % (total/len(scorelist)))

else:
try:
studata = scoredata.get_sheet_by_name(major)
except:
print("没有这个专业,请重新输入")
continue

# 抽取专业数据表
stulist = getSheet(studata)
# 计算(分数,名字)列表
scorelist = [(stulist[stu].getAverage(),stulist[stu].name) for stu in stulist]
# 排序得到排名
scorelist.sort(reverse=True)

# 初始化总分
total = 0

for i in range(len(scorelist)):
# 对每个学生对象操作
total += scorelist[i][0]

# 依然可以输出名字,但同样没必要
# print("{} \t {:.3f}: \t排名 {}".format(scorelist[i][1],scorelist[i][0],i+1))
print("{:.3f}: \t排名 {}".format(scorelist[i][0], i + 1))

# 输出平局分
print("平均分:\t%f" % (total/len(scorelist)))