夜光序言:
时间好奇怪,有时候你想对自己喜欢的人轻声微笑,却禁不住低头掩面哭泣。总是在街头闲逛时,最熟悉的背影却出现在最陌生的人身上。
正文:写了几百行~~程序就是多而简
案例 3 学生成绩管理
3.1 需求分析
学生成绩的登记、存储、统计等式教学中常规的业务,学生成绩程序主要以学生的语文、数学、英语的成绩为蓝本,对这些成绩进行处理。
3.1.1 系统概述
学生成绩管理程序主要对学生的语文、数学、英语成绩进行存储、排序、统计等操作,方便教师完成学生成绩的管理与分析工作。
3.1.2 系统运行环境
一、硬件环境【皮一下~~】
处理器:i7或更高
内存:32GB
硬盘空间:10TB
显卡:液晶 显示适配器
二、软件环境
操作系统:Windows 10/8/2000/XP+Python3.7
3.1.3 功能需求描述
学生成绩管理程序采用面向对象的程序设计方法设计,维护学生的成绩表:
学号 姓名 语文 数学 英语
1001 AAA … … …
1002 BBB
主要的功能有:
1、增加成绩
从键盘中录入每个学生的成绩,增加学生成绩记录,执行命令 insert,例如:
>insert
学号:1001
姓名:xxx
语文:78
数学:67
英语:78
2、修改成绩
重新录入成绩,修改学生的成绩,录入的过程中如果某个字段不录入新的值就不更新该字段,执行命令 update,例如:
>update
学号:1001
姓名:
语文:87
数学:
英语:
那么直修改 1001 号学生的语文成绩,其它的不修改。
3、删除成绩
录入学生的学号就删除成绩记录,执行命令 delete,例如:
>delete
学号:1001
4、导入成绩
从文本文件 marks.txt 中批量导入成绩,文件的格式如下:
学号
姓名
语文
数学
英语
每个字段值占一行,成绩必须有效,程序启动时会读取该文件数据。
5、导出成绩
成绩按学号顺序导出到文件 marks.txt 中,这也是成绩存储的文件,程序结束时会把成绩保存到该文件。
6、成绩统计
程序可以统计出各个科成绩的平均值、均方差,执行命令 stat,例如:
>stat
7、分段统计
程序可以统计各个分数段的人数,执行命令 range Chinese/math/English,分别按语文、数学、英语进行分段统计,例如:
>range math
按数学进行分段统计。
8、成绩排序
程序可以按各科成绩进行排序输出,执行命令 order Chinese/math/English/total,分别按语文、数学、英语、总分进行排序输出,例如:
>order total
按总分排序输出。
3.2 总体设计
3.2.1 成绩功能模块
依据需求分析结果,家庭财务管理系统由四大功能模块组成
成绩管理
程序排序
成绩统计
成绩存储
3.2.2 数据结构设计
class Mark:
def __init__(self,no,name,chinese=0,math=0,english=0):
self.no=no
self.name=name
self.chinese=chinese
self.math=math
self.english=english
class StudentMark:
def __init__(self):
self.marks=[]
其中 marks 中存储了学生成绩对象,即每个元素是一个 Mark 对象。
3.2.3 程序命令设计
程序命令 功能说明
show 显示学生成绩学生成绩管理程序统
insert 插入学生成绩记录
update 更新学生成绩记录
delete 删除学生成绩记录
stat 统计学生成绩
range Chinese/math/english 统计各个分数段的人数,例如:
Range math
统计数学成绩的分数段人数
Sort Chinese/math/emglish/total 按语文、数学、英语、总分排序输出成绩,例如:
Sort total
按总分排序输出
3.3 程序代码
import math
import os
import random
# 夜光
class Mark:
def __init__(self,no,name,chinese=0,math=0,english=0):
self.no=no
self.name=name
self.chinese=chinese
self.math=math
self.english=english
def show(self):
print("%-12s%-12s%-12d%-12d%-12d%-12d(self.no,self.name,self.chinese,self.math,self.english,self.chinese+self.math+self.english)")
class StudentMark:
def __init__(self):
self.marks=[]
def insert(self,m):
#插入的 m.no 希望能按 no 顺序插入
i=0
while i<len(self.marks) and self.marks[i].no<m.no:
i=i+1
if i<len(self.marks) and self.marks[i].no==m.no:
print(m.no+" already exists")
return
self.marks.insert(i,m)
print("插入成功")
def show(self):
print("%-12s%-12s%-12s%-12s%-12s%-12s" % ("No","Name","Chinese","Math","English","Total"))
for m in self.marks:
m.show()
print()
def enter(self):
try:
no=input("学号:").strip() #trim()
if no=="":
raise Exception("学号不能为空")
name=input("姓名:").strip()
#if name=="":
# raise Exception("姓名不能为空")
m=input("语文:").strip()
if m=="":
m="0"
m=int(m)
if m<0 or m>100:
raise Exception("无效的成绩")
chinese=m
m=input("数学:").strip()
if m=="":
m="0"
m=int(m)
if m<0 or m>100:
raise Exception("无效的成绩")
math=m
m=input("英语:").strip()
if m=="":
m="0"
m=int(m)
if m<0 or m>100:
raise Exception("无效的成绩")
english=m
m=Mark(no,name,chinese,math,english)
return m
except Exception as e:
print(e)
return None
def update(self,m):
for i in range(len(self.marks)):
if self.marks[i].no==m.no:
if m.name!="":
self.marks[i].name=m.name
if m.chinese>0:
self.marks[i].chinese=m.chinese
if m.math>0:
self.marks[i].math=m.math
if m.english>0:
self.marks[i].english=m.english
print("更新成功")
return
print(m.no+"不存在")
def delete(self,no):
i=0
while i<len(self.marks):
if self.marks[i].no==no:
del self.marks[i]
print("删除成功")
return
else:
i=i+1
print(no+"不存在")
def orderBy(self,course):
course=course.lower()
print("order by ",course)
print("%-12s%-12s%-12s%-12s%-12s%-12s" % ("No","Name","Chinese","Math","English","Total"))
index=[]
for m in self.marks:
index.append(m)
for i in range(len(index)):
for j in range(i+1,len(index)):
if course=="chinese":
if index[i].chinese>index[j].chinese:
k=index[i]
index[i]=index[j]
index[j]=k
elif course=="math":
if index[i].math > index[j].math:
k = index[i]
index[i] = index[j]
index[j] = k
elif course=="english":
if index[i].english > index[j].english:
k = index[i]
index[i] = index[j]
index[j] = k
elif course=="total":
if index[i].chinese+index[i].math+index[i].english >index[j].chinese+index[j].math+index[j].english:
k = index[i]
index[i] = index[j]
index[j] = k
for m in index:
m.show()
print()
def printChar(self,s,n):
print("%-12s%-6d" %(s,n),end=":")
if len(self.marks)>0:
n=n*100//len(self.marks)
for i in range(n):
print("*",end="")
print()
def rangeBy(self,course):
n0059=0
n6069=0
n7079=0
n8089=0
n90100=0
course=course.lower()
for i in range(len(self.marks)):
if course=="chinese":
m=self.marks[i].chinese
elif course=="math":
m=self.marks[i].math
elif course=="english":
m=self.marks[i].english
if m<60:
n0059+=1
elif m<70:
n6069+=1
elif m<80:
n7079+=1
elif m<90:
n8089+=1
else:
n90100+=1
print(course+"各个分数段人数")
#print("[0,59]:",n0059," [60,69]:",n6069," [70,79]:",n7079," [80,89]:",n8089," [90,100]:",n90100)
self.printChar("[0,59]",n0059)
self.printChar("[60,69]",n6069)
self.printChar("[70,79]",n7079)
self.printChar("[80,89]",n8089)
self.printChar("[90,100]",n90100)
print()
def statistics(self):
if len(self.marks)==0:
return
ca=0
cs=0
ma=0
ms=0
ea=0
es=0
for m in self.marks:
ca+=m.chinese
cs+=m.chinese*m.chinese
ma+=m.math
ms+=m.math*m.math
ea+=m.english
es+=m.english*m.english
ca=ca/len(self.marks)
cs=math.sqrt(cs/len(self.marks)-ca*ca)
ma=ma/len(self.marks)
ms=math.sqrt(ms/len(self.marks)-ma*ma)
ea=ea/len(self.marks)
es=math.sqrt(es/len(self.marks)-ea*ea)
print("语文平均分:%.2f 语文均方差:%.2f" % (ca,cs))
print("数学平均分:%.2f 数学均方差:%.2f" % (ma,ms))
print("英语平均分:%.2f 英语均方差:%.2f" % (ea,es))
print()
def saveMarks(self):
try:
fobj=open("marks.txt","wt")
for m in self.marks:
fobj.write(m.no+"\n")
fobj.write(m.name+"\n")
fobj.write(str(m.chinese)+"\n")
fobj.write(str(m.math) + "\n")
fobj.write(str(m.english) + "\n")
fobj.close()
except Exception as e:
print(e)
def readMarks(self):
self.marks=[]
if not os.path.exists("marks.txt"):
return
try:
fobj=open("marks.txt","rt")
while True:
try:
no=fobj.readline().strip("\n")
if no=="":
break
name = fobj.readline().strip("\n")
m=fobj.readline().strip("\n")
m=int(m)
if m<0 or m>100:
raise Exception("无效成绩")
chinese=m
m=fobj.readline().strip("\n")
m=int(m)
if m<0 or m>100:
raise Exception("无效成绩")
math=m
m=fobj.readline().strip("\n")
m=int(m)
if m<0 or m>100:
raise Exception("无效成绩")
english=m
self.marks.append(Mark(no,name,chinese,math,english))
except Exception as ea:
print(ea)
fobj.close()
except Exception as eb:
print(eb)
def process(self):
self.readMarks()
while True:
s=input(">")
s=s.lower()
s=s.split(" ")
if s[0]=="show":
self.show()
elif s[0]=="order":
if len(s)>1:
self.orderBy(s[1])
else:
print("格式示范: order chinese")
elif s[0]=="insert":
m=self.enter()
if m:
self.insert(m)
elif s[0]=="update":
print("提示:不输入直接回车的字段不更新")
m=self.enter()
if m:
self.update(m)
elif s[0]=="delete":
no = input("学号:").strip()
if no != "":
self.delete(no)
else:
print("学号不能为空")
elif s[0]=="range":
if len(s) > 1:
self.rangeBy(s[1])
else:
print("格式示范: range chinese")
elif s[0] == "stat":
self.statistics()
elif s[0]=="exit":
break
else:
print("有效的命令:")
print("show")
print("insert")
print("update")
print("delete")
print("stat")
print("order chinese/math/english/total")
print("range chinese/math/english")
print("exit")
self.saveMarks()
sm=StudentMark()
sm.process()
3.4 程序测试
我们为了测试程序的各个功能,编写函数 createMarks 随机产生几十条学生成绩记录:
def createMarks(self):
n=random.randint(10,20)
self.marks=[]
for i in range(n):
s=str(i+1)
while len(s)<5:
s="0"+s
name=chr(ord("a")+random.randint(0,26))
chinese=random.randint(0,100)
math = random.randint(0, 100)
english = random.randint(0, 100)
self.marks.append(Mark(s,name,chinese,math,english))
经过 show、insert、update、delete、sort、range、stat 等命令的测试,程序功能完善。