实训案例1 学生成绩管理系统
1.1 功能介绍 
学生成绩管理系统用于实现对学生基本信息的管理,主要包括以下功能。
(1)输入并存储学生信息:输入学生的学号、姓名和分数,把数据保存在创建的
students.txt文件中。
(2)打印学生信息:通过打印函数把学生的所有信息打印在屏幕上。
(3)修改学生信息:通过查询功能查询某学生是否存在,如果存在就对该学生的信息
进行修改,如果不存在则返回到主界面。
(4)删除学生信息:对相应的学生进行删除操作,如果某学生存在就查找并进行删除。
(5)按学生成绩进行排序:按照学生的总分从高到低进行排序。
(6)查找学生信息:输入学生的学号,查找该学生的相关信息,如果查找到就输出该学
生的信息,如果没有查找到则提示输入的学号不存在。
1.2 程序设计的思路
将学生信息设计成一个Student类,这里假设学生有语文、数学和英语三门课的成绩。 
class Student: #定义一个学生类 
def _ _init_ _(self): 
self.name = " 
self.ID =" 
self.score1 = 0 #语文成绩 
self.score2 = 0 #数学成绩 
self.score3 = 0 #英语成绩 
self.sum = 0 #总分
学生成绩管理系统在开始使用之前先进行初始化,判断students.txt文件中是否保存
了学生的信息,如果保存了就把文件的内容读取出来,供接下来的操作使用;如果没有保存
就初始化一个空的列表,用来保存用户的输入,程序中接下来的所有数据都会保存在该列
表中。在
对学生基本信息进行操作(包括查找、修改、删除、排序)时,首先打开students.txt文

1 56 
件,对文件中的内容进行读取操作,由于在文件中保存的内容是以空格进行分隔的,并且每
个学生的信息占用一行,所以读出所有的内容,先通过换行进行分隔,得到每个学生的信息, 
然后对每个学生的信息以空格进行分隔,得到每个学生的详细信息,包括学生的姓名、学号、
成绩,形成学生类对象并存入stulist列表中。对学生基本信息的所有操作都是针对stulist 
列表进行的,如果是添加学生,则追加写入文件中;如果是删除和修改学生,则在操作完成后
将stulist列表覆盖写入文件中。
1.3 程序设计的步骤
1.设计Student类。将学生信息设计成一个Student类,存储学生的语文、数学和英语
成绩。在该类中定义计算总分的方法。 
class Student: #定义一个学生类 
def _ _init_ _(self): 
self.name =" 
self.ID =" 
self.score1 = 0 #语文成绩 
self.score2 = 0 #数学成绩 
self.score3 = 0 #英语成绩 
self.sum = 0 #总分 
def sumscore(self): #计算总分 
self.sum=self.score1 + self.score2 + self.score3 
def input(self): #输入学生的信息 
self.name = input("请输入学生的姓名: ") 
self.ID = input("请输入学生的ID: ") 
self.score1 = int(input("请输入学生的语文成绩: ")) 
self.score2 = int(input("请输入学生的数学成绩: ")) 
self.score3 = int(input("请输入学生的英语成绩: ")) 
self.sumscore() 
def output(self,file_object): #输出到文件中 
print(self.name,self.ID, self.score1, self.score2, self.score3, self.sum) 
file_object.write(self.ID) 
file_object.write(" ") 
file_object.write(self.name) 
file_object.write(" ") 
file_object.write(str(self.score1)) 
file_object.write(" ") 
file_object.write(str(self.score2)) 
file_object.write(" ") 
file_object.write(str(self.score3)) 
file_object.write(" ") 
file_object.write(str(self.sum)) 
file_object.write("\n") 
2.设计功能函数。
(1)添加学生信息。在添加一个学生信息时,首先判断学号是否已经存在,如果已经存
在则取消添加操作;否则由用户选择是否保存,如果保存则以追加方式写入文件。

1 57 
def Add(stulist,stu): #添加一个学生信息 
if searchByID(stulist, stu.ID) == True: #判断学号是否存在 
print("学号已经存在!") 
return False 
print("是否要保存学生信息?") 
nChoose = input("Choose Y/N") 
if nChoose == 'Y' or nChoose == 'y': 
stulist.append(stu) #加入列表 
print(stu.name,stu.ID, stu.score1, stu.score2, stu.score3, stu.sum) 
file_object = open("students.txt", "a") #"a"为追加方式 
stu.output(file_object) #输出到文件中保存 
file_object.close() 
print("保存成功!") 
(2)删除学生信息。在删除一个学生信息时,首先遍历stulist列表中学生的ID是否为
要删除的学号,如果是则从stulist列表中删除,然后采用覆盖写入方式将stulist列表中的
剩余学生重新写入文件。 
def Del(stulist, ID): #删除一个学生信息
count = 0 
flag=False 
for item in stulist: 
if item.ID == ID: 
stulist.remove(item) #从列表中删除 
flag=True #删除成功 
break 
count +=1 
if flag==False: #或者count == len(stulist) 
print("没有该学生学号!") 
return 
file_object = open("students.txt", "w") #覆盖写入
for stu in stulist: 
stu.output(file_object) 
print("删除保存成功!") 
file_object.close() 
(3)修改学生信息。在修改一个学生信息时,首先遍历stulist列表中学生的ID是否为
要修改的学号,如果是则输入这个被修改学生的新信息,添加此学生到文件中。 
def Change(stulist, ID): #修改学生信息 
count = 0 
flag=False 
for item in stulist: 
if item.ID == ID: 
flag=True 
stulist.remove(item) 
file_object = open("students.txt", "w") 
for stu in stulist:

1 58 
stu.output(file_object) 
file_object.close() 
if flag==False: 
print("没有该学生学号!") 
return 
#输入这个被修改学生的新信息 
stu = Student() 
stu.input() 
Add(stulist,stu) #添加stu 学生信息到文件中
(4)显示所有学生信息。这里指将stulist列表中的学生信息打印到屏幕上。 
def display(stulist): #显示所有学生信息 
print("学号\t 姓名语文数学英语总分") 
for item in stulist: 
#print(item.ID, '\t' ,item.name,'\t', item.score1,'\t',item.score2, '\t', 
item.score3, '\t',item.sum) 
#格式化输出 
print( "%5s%5s%3d %3d %3d %4d"%(item.ID, item.name, item.score1, item. 
score2, item.score3,item.sum)) 
(5)成绩排序。成绩排序指按学生成绩由高至低进行排序,在实现的时候使用比较排
序算法,按照总分对stulist中保存的学生信息进行排序。 
def Sort(stulist): #按学生成绩排序 
insertSort(stulist) #比较排序 
display(stulist) 
def insertSort(stulist): #比较排序
for i in range(len(stulist)-1): 
for j in range(i+1,len(stulist)): 
if stulist[i].sum<stulist[j].sum: #交换 
temp = stulist[i] 
stulist[i]= stulist[j] 
stulist[j]= temp 
(6)查询学生信息。在查询学生信息时,按学号(ID)进行搜索,如果该学生的学号在
stulist列表中,则将该学生的信息打印出来。 
def Search(stulist, ID): #查询学生信息 
print("学号\t 姓名\t 语文\t 数学\t 英语\t 总分") 
count = 0 
for item in stulist: 
if item.ID == ID: 
print(item.ID, '\t' ,item.name,'\t', item.score1,'\t',item.score2, '\t', 
item.score3, '\t',item.sum) 
break 
count = count + 1 
if count == len(stulist): 
print("没有该学生学号!")

1 59 
(7)初始化函数。在从文件中读取学生信息后,以空格进行分隔形成列表s,将列表s 
形成学生对象实例,依次加入保存所有学生信息的stulist列表中。stulist列表中存放的是
学生对象实例。 
def Init(stulist): #初始化函数 
print("初始化......") 
if os.path.exists('students.txt'): #判断students.txt 文件是否存在 
file_object = open('students.txt', 'r') 
for line in file_object: 
stu = Student() 
line = line.strip("\n") 
s = line.split(" ") #按空格分隔形成列表 
stu.ID = s[0] 
stu.name = s[1] 
stu.score1 = int(s[2]) 
stu.score2 = int(s[3]) 
stu.score3 = int(s[4]) 
stu.sum = s[5] 
stulist.append(stu) 
file_object.close() 
print("初始化成功!") 
main() 
3.设计主函数。主函数是一个无限循环,用于实现用户选择的功能。 
def main(): #程序的入口函数 
while True: 
print("*********************") 
print("--------菜单---------") 
print("添加学生信息--------1") 
print("查找学生信息--------2") 
print("删除学生信息--------3") 
print("修改学生信息--------4") 
print("显示所有学生信息--------5") 
print("按照分数排序--------6") 
print("退出程序------------0") 
print("*********************") 
nChoose = input("请输入你的选择: ") 
if nChoose == "1": 
stu = Student() 
stu.input() 
Add(stulist,stu) 
if nChoose == '2': 
ID = input("请输入学生的ID: ") 
Search(stulist, ID) 
if nChoose == '3': 
ID = input("请输入学生的ID: ") 
Del(stulist, ID) 
if nChoose == '4':

1 60 
ID = input("请输入学生的ID: ") 
Change(stulist, ID) 
if nChoose == '5': 
display(stulist) 
if nChoose == '6': 
Sort(stulist) 
if nChoose == '0': 
break 
#主程序
if _ _name_ _ == '_ _main_ _': 
stulist =[] 
Init(stulist) #调用初始化函数
程序的运行结果如下: 
初始化...... 
********************* 
--------菜单--------- 
添加学生信息--------1 
查找学生信息--------2 
删除学生信息--------3 
修改学生信息--------4 
显示所有学生信息--------5 
按照分数排序--------6 
退出程序------------0 
********************* 请输入你的选择: 1 
请输入学生的姓名: 张海
请输入学生的ID: 98001 
请输入学生的语文成绩: 78 
请输入学生的数学成绩: 88 
请输入学生的英语成绩: 79 
张海98001 78 88 79 245 
是否要保存学生信息? Choose Y/N 
y
保存成功! 
请输入你的选择: 5 
学号 姓名 语文 数学 英语 总分
98001 张海 78 88 79 245 
98002 赵大强 88 90 98 276 
98003 李东方 77 66 77 220 
请输入你的选择: 6 
学号 姓名 语文 数学 英语 总分
98002 赵大强 88 90 98 276 
98001 张海 78 88 79 245 
98003 李东方 77 66 77 220 
思考:在掌握以上方法后,请读者思考商品库存管理系统的实现,具体要求如下。
(1)商品的信息用类来表示,包含商品编号id、商品名称name、商品类别category、商
品库存量kcl、商品销售量xsl等信息。

1 61 
(2)能够输入商品信息,能够显示所有商品信息。
(3)能够按商品名称、商品类别等查询,可以查询商品库存量小于5的商品,查询方式
自定。
(4)能够按商品销售量进行排序,并在屏幕上打印排序结果。
(5)能够添加、删除、修改(增加商品库存量、商品销售量)商品的信息。
(6)商品的信息保存在文件中。
实训案例2 基于文件存储的公交查询系统
2.1 功能介绍 
随着公交系统越来越庞大,人们很难得到准确的公交信息,这样就给人们的出行带来了
不便,因此急需一个方便、快捷的公交信息查询系统。本系统提供了换乘查询功能、路线查
询功能,乘客可以方便地进行查询,以防止乘错车次。本系统主要有4个模块,即线路查询
模块、站点查询模块、换乘查询模块和后台管理模块。
(1)线路查询模块:可以获得要查询公交所通过的各个站点。
(2)站点查询模块:通过输入的指定站点查询经过该站点的公交。
(3)换乘查询模块:分为公交直达、公交一次换乘,主要体现不可直达需要转车的路线
的所有换乘方法。
(4)后台管理模块:用于管理员登录,实现添加、修改、删除公交线路等功能。
2.2 程序设计的思路
公交查询系统程序需要存储各公交线路的站点信息,这里用文件存储线路信息,形式
如下: 
1s%通利公交公司%长途客运西站%建设路国棉六厂%建设路桐柏路站%建设路文化宫路站%建设
路工人路站%碧沙岗公园西门%绿城广场%嵩山路伊河路站%解放军测绘学院%市骨科医院%陇海路
站%陇海路京广客运站%陇海路铁英街站%郑州铁路局%锦荣商贸城%福寿街大同路站%火车站%6:00- 
21:00 票价1 元ABCD 卡有效 
1x%火车站%一马路陇海路站%郑州铁路局%陇海路铁英街站%陇海路京广客运站%陇海路站%市
骨科医院%解放军测绘学院%嵩山路伊河路站%绿城广场%碧沙岗公园西门%碧沙岗%建设路工人路
站%建设路文化宫路站%建设路桐柏路站%建设路国棉六厂%华山路建设路站%通利公交公司%6:00- 
21:00 票价1 元ABCD 卡有效
…… 
其中,1s为上行,1x为下行,站点信息之间以%分隔。
公交查询系统程序从文件中读取线路信息,其中线路信息存入route字典,线路名存入
routename列表。route字典的存储形式为{线路名:线路经过站点的列表}。
例如,以上线路信息存入route字典时键名为线路名1s,键对应的内容为1s线路经过
站点的列表: 
print(route['1s']) 
print(route['1x'])

1 62 
结果如下: 
['通利公交公司', '长途客运西站', '建设路国棉六厂', '建设路桐柏路站', '建设路文化
宫路站', '建设路工人路站', '碧沙岗公园西门', '绿城广场', '嵩山路伊河路站', '解放军测
绘学院', '市骨科医院', '陇海路站', '陇海路京广客运站', '陇海路铁英街站', '郑州铁路
局', '锦荣商贸城', '福寿街大同路站', '火车站'] 
['火车站', '一马路陇海路站', '郑州铁路局', '陇海路铁英街站', '陇海路京广客运站', 
'陇海路站', '市骨科医院', '解放军测绘学院', '嵩山路伊河路站', '绿城广场', '碧沙岗公园
西门', '碧沙岗', '建设路工人路站', '建设路文化宫路站', '建设路桐柏路站', '建设路国棉
六厂', '华山路建设路站', '通利公交公司'] 
当线路信息存入route字典后,线路查询、站点查询、换乘功能的实现就可以转换为对
route字典的相应操作。
2.3 程序设计的步骤 
import math 
route = {} #线路信息的字典
routename=[] #线路名的列表
readRote()是读取线路信息的函数。readRote()从gongjiao.txt文件中读取线路信息
(一行一个线路),以%分隔后,第一个数据项是线路名(如1s,201x),存入routename,后面
的数据项存入route字典相应的键-值对中。其中,route字典中键为线路名,对应值为线路
经过站点的列表。 
def readRote(): 
fp=open("gongjiao.txt",'r', encoding='gbk') #注意文本文件编码,也可能为utf-8 
#UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf: illegal multibyte 
sequence 
while True: 
line=fp.readline() 
if line=="": #或者if not line 
break 
list1=line.split("%") #以%分隔 
routename.append(list1[0]) #线路名(如1s,201x),存入routename 
route[list1[0]]=list1[1:-1] #增加键-值对 
fp.close() #关闭文件
#print(route.values()) #返回字典中所有的值(所有线路信息) 
#print(route['1x']) 
findRote()是实现线路查询功能的函数,判断线路信息字典route中是否存在此线路名
的键,如果存在就打印出此线路名的键对应的值(即此线路信息)。 
def findRote(): #线路查询功能 
findRoteName = input("请输入查询线路名: ") 
if findRoteName in route: 
print(route[findRoteName]) #打印出对应的值(即此线路信息) 
else: 
print("输入有错误! 没有你要查询的线路")

1 63 
findStation()是实现站点查询功能的函数,仅需要遍历线路信息字典route,判断键对
应的值value(线路经过的站点)是否存在查询站点名,如果存在则打印出键key(线路名)。 
def findStation(): #站点查询功能 
stationName = input("请输入查询站点名: ") 
print('经过此站点的线路有: ',end=' ') 
#遍历字典 
for key,value in route.items(): 
if(stationName in value): 
print(key,end='; ') 
print() 
huanRote()是实现换乘查询功能的函数。此函数的功能比较复杂,首先需要判断起始
站点到终点是否有直达线路,如果无直达线路则需要换乘。
对直达的判断比较简单,仅需要判断起始站点和终点是否在同一个线路上。
换乘功能算法是找出经过起点的线路存入S列表,找出经过终点的线路存入D列表,然
后判断S列表中的key1线路和D列表中的key2线路是否有相同站点sameStationName,如果
有相同站点sameStationName,则乘客从起始站点经过key1线路到sameStationName相同
站点,换乘key2线路可以到达终点。 
def huanRote(): #换乘查询功能 
startStationName =input("请输入起始站点名: ") #"火车站" 
endStationName =input("请输入终点名: ") #"绿城广场" 
canGo=False 
#对直达的判断 
for key,value in route.items(): 
if(startStationName in value) and (endStationName in value): #在同一个线路上 
canGo=True 
print("公交可直达线路",key) 
if canGo==False: 
print("公交不可直达") 
#换乘 
S=[] #经过起点的线路 
D=[] #经过终点的线路 
for key,value in route.items(): 
if(startStationName in value): 
S.append(key) 
for key,value in route.items(): 
if(endStationName in value): 
D.append(key) 
#判断线路之间是否有相同站点 
for key1 in S: 
for key2 in D: 
if hasSameStation(key1,key2): 
sameStationName=hasSameStation(key1,key2) 
n1=stationNum(startStationName,sameStationName,key1) 
n2=stationNum(endStationName,sameStationName,key2)

1 64 
print("经过key1 线路"+key1+n1+"站到"+hasSameStation(key1,key2)+ 
"换乘key2 线路"+key2+n2+"站到达"+endStationName) 
#判断线路之间是否有相同站点
def hasSameStation(key1,key2): 
for stationName in route[key1]: 
if stationName in route[key2]: 
return stationName 
return False 
#两个站点之间的站数
def stationNum(Station1,Station2,routeName): 
for i in range(len(route[routeName])): 
stationName=route[routeName][i] 
if Station1==stationName: 
i1=i 
if Station2==stationName: 
i2=i 
return str(int(math.fabs(i1-i2))) 
main()是主函数,是公交查询系统程序的入口函数,主要通过循环实现用户选择的
功能。 
def main(): #主函数 
readRote() 
while True: 
print("*********************") 
print(u"--------菜单---------") 
print(u"线路查询------------1") 
print(u"站点查询------------2") 
print(u"换乘查询------------3") 
print(u"添加线路信息--------4") 
print(u"退出程序------------0") 
print("*********************") 
nChoose = input("请输入你的选择: ") 
if nChoose == "1": 
findRote() 
elif nChoose == "2": 
findStation() 
elif nChoose == "3": 
huanRote() 
elif nChoose == "4": 
#添加线路信息 
fp=open("gongjiao.txt",'a', encoding='gbk') 
addRoteName = input("请输入添加线路名: ") 
addRoteContent = input("请输入添加线路经过的站点及运行时间,以%分隔: \n") 
fp.write(addRoteName+"%"+addRoteContent+"\n") 
fp.close() 
routename.append(addRoteName) #添加线路名的列表 
route[addRoteName]=addRoteContent # 添加线路信息的字典 
elif nChoose == "0": 
break