夜光序言:
人,可以爱到什么地步?
爱到,表面仍能不动声色微笑,内心却以常人难以发觉的惊人速度衰老,直至最后枯竭。
正文:
7.5 实践项目 学生成绩管理
7.5.1 目标
学生成绩记录包括学号(pNo)、姓名(pName)、语文成绩(pChinese)、数学成绩(pMath)、英语成绩(pEnglish),它们存储在MySQL 的 MyDB 数据库的 marks 表中。程序的功能包括:
显示成绩:显示全部学生成绩记录;
增加成绩:增加新的成绩记录;
更新成绩:更新指定学号的成绩记录;
删除成绩:删除指定学号的成绩记录;
导出成绩:把数据库成绩导出到 marks.txt 文件;
导入成绩:从指定的文本文件导入成绩到数据库中;
7.5.2 项目设计
1、数据库设计
成绩存储在 MyDB 的 marks 表中,marks 表的建立命令如下:
create table marks (pNo varchar(16) primary key,pName varchar(16) ,pChinese float,pMath float,pEnglish float)
2、增加成绩、更新成绩、删除成绩
这些功能与前面很多示例很相似,不再多说了嗯~~。
3、导出成绩
把数据库的成绩按一定文件格式导出到文本文件是十分有用的,本程序导出的文件
marks.txt 格式如下:
学号,姓名,语文,数学,英语
111,张三,67.0,78.0,90.0
222,James,57.0,78.0,45.0
其中第一行是标题,第二行后是数据,每条记录占一行,各个字段的值用逗号分开,导出函数设计如下:
def export(self):
try:
f=open("marks.txt","wt")
self.cursor.execute("select * from marks")
f.write("学号,姓名,语文,数学,英语\n")
rows = self.cursor.fetchall()
for row in rows:
f.write(row["pNo"]+","+row["pName"]+","+str(row["pChinese"])+","+str(row["pMath"])+","+str(row["pEnglish"])+"\n")
f.close()
print("成绩导出完毕")
except Exception as err:
print(err)
4、导入成绩
程序能够从与 marks.txt 文件格式一样的文本文件中批量导入成绩到数据库,这个功能是十分有用的和高效的,不用一条条记录输入。
要导入成绩必须要求导入文件有严格的格式,第一行是学号,姓名,语文,数学,英语的标题,第二行后是数据,每个数据行的成绩都经过严格的控制,设计函数__parseMark 来获取字符串 s 表示的成绩,保证 s 表示一个[0,100]之内的合理的成绩。
def __parseMark(self,s):
m=0
try:
m=float(s)
if m<0 or m>100:
m=0
except:
pass
return m
7.5.3 项目实践
import pymysql
import os
class MarkDB:
def open(self):
self.con = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="123456", db="mydb", charset="utf8")
self.cursor = self.con.cursor(pymysql.cursors.DictCursor)
try:
sql = "create table marks (pNo varchar(16) primary key,pName varchar(16) ,pChinese float,pMath float,pEnglish float)"
self.cursor.execute(sql)
except:
pass
def close(self):
self.con.commit()
self.con.close()
def clear(self):
try:
self.cursor.execute("delete from marks")
except Exception as err:
print(err)
def show(self):
try:
self.cursor.execute("select * from marks")
print("%-16s%-16s%-8s%-8s%-8s" % ("学号", "姓名", "语文", "数学","英语"))
rows = self.cursor.fetchall()
for row in rows:
print("%-16s%-16s%-8.0f%-8.0f%-8.0f" % (row["pNo"],
row["pName"], row["pChinese"], row["pMath"],row["pEnglish"]))
except Exception as err:
print(err)
def __insert(self, pNo, pName, pChinese, pMath,pEnglish):
try:
sql = "insert into marks (pNo,pName,pChinese,pMath,pEnglish) values(%s,%s,%s,%s,%s)"
self.cursor.execute(sql, (pNo, pName, pChinese, pMath,pEnglish))
print(self.cursor.rowcount, " row inserted")
except Exception as err:
print(err)
def __update(self, pNo, pName, pChinese, pMath,pEnglish):
try:
sql = "update marks set pName=%s,pChinese=%s,pMath=%s,pEnglish=%s
where pNo=%s"
self.cursor.execute(sql, (pNo, pName, pChinese, pMath, pEnglish))
print(self.cursor.rowcount, " row updated")
except Exception as err:
print(err)
def __delete(self, pNo):
try:
sql = "delete from marks where pNo=%s"
self.cursor.execute(sql, (pNo,))
print(self.cursor.rowcount, " row deleted")
except Exception as err:
print(err)
def enterMark(self,s):
while True:
m=input(s)
try:
m=float(m)
if m>=0 and m<=100:
break
except Exception as err:
print(err)
return m
def insert(self):
pNo=input("学号:").strip()
pName=input("姓名:").strip()
if pNo!="" and pName!="":
pChinese=self.enterMark("语文:")
pMath = self.enterMark("数学:")
pEnglish = self.enterMark("英语:")
self.__insert(pNo,pName,pChinese,pMath,pEnglish)
else:
print("学号、姓名不能空")
def update(self):
pNo = input("学号:").strip()
pName = input("姓名:").strip()
if pNo != "" and pName != "":
pChinese = self.enterMark("语文:")
pMath = self.enterMark("数学:")
pEnglish = self.enterMark("英语:")
self.__update(pNo, pName, pChinese, pMath, pEnglish)
else:
print("学号、姓名不能空")
def delete(self):
pNo = input("学号:").strip()
if pNo != "":
self.__delete(pNo)
else:
print("学号不能空")
def export(self):
try:
f=open("marks.txt","wt")
self.cursor.execute("select * from marks")
f.write("学号,姓名,语文,数学,英语\n")
rows = self.cursor.fetchall()
for row in rows:
f.write(row["pNo"]+","+row["pName"]+","+str(row["pChinese"])+","+str(row["pMath"])+","+str(row["pEnglish"])+"\n")
f.close()
print("成绩导出完毕")
except Exception as err:
print(err)
def __parseMark(self,s):
m=0
try:
m=float(s)
if m<0 or m>100:
m=0
except:
pass
return m
def load(self):
try:
s=input("输入导入文件路径与名称:")
if os.path.exists(s):
f=open(s,"rt")
s=f.readline().strip("\n")
st=s.split(",")
if len(st)==5 and st[0]=="学号" and st[1]=="姓名" and st[2]=="语文" and st[3]=="数学" and st[4]=="英语":
s="going"
while s!="":
s=f.readline().strip("\n")
if s!="":
st=st.split(",")
if len(st)==5:
pNo=st[0].strip()
pName=st[1].strip()
pChinese=self.__parseMark(st[2])
pMath = self.__parseMark(st[3])
pEnglish = self.__parseMark(st[3])
if pNo!="" and pName!="":
self.__insert(pNo,pName,pChinese,pMath,pEnglish)
print("成绩转载完毕")
else:
print("文件格式不正确")
f.close()
else:
print(s+"文件不存在")
except Exception as err:
print(err)
def process(self):
db=self.open()
while True:
s=input(">")
if s=="show":
self.show()
elif s=="insert":
self.insert()
elif s=="update":
self.update()
elif s=="delete":
self.delete()
elif s=="export":
self.export()
elif s=="load":
self.load()
elif s=="exit":
break
else:
print("Accept commands: show/insert/update/delete/export/load/exit")
print("show --- show the rows")
print("insert --- insert a new row")
print("update --- update a row")
print("delete --- delete a row")
print("export --- export to marks.txt")
print("load --- load from a file")
print("exit --- exit and stop")
db.close()
db=MarkDB()
db.process()
程序运行后显示">"提示符,接受的命令是 show,insert,update,delete,export,load,exit之一,根据不同的命令执行不同的操作。