zoukankan      html  css  js  c++  java
  • Python — 学生成绩管理

    Python — 学生成绩管理

    摘要

      本次实验要求使用python语言,读取现有的班级花名册,写入SQlite数据库,逐个显示每一个学生的学号姓名,输入其python、英语等课程的成绩,写入SQLite数据库。全部记录结束后,计算大家的总分、名次,并显示整个花名册。
      在实验过程中,我首先分析实验要求,决定使用”将Excel文件导入数据库、录入学生各科成绩信息、计算总成绩、显示输出、导出文件”的基本思路,使用cmd和Notepad++环境进行实验。在”录入信息方式”,”输出显示方式”,”整合代码”,“导出为Excel文件”等方面进行代码优化,最终完成学生成绩管理程序的编写,完成实验要求。

    关键字:Python SQLite数据库 文件读写 学生信息管理

    一、总体思路

       读取现有的班级花名册,写入SQlite数据库,逐个显示每一个学生的学号姓名,输入其python、英语等课程的成绩,写入SQLite数据库。全部记录结束后,计算大家的总分、名次,并显示整个花名册。
    图1 流程图

    图1 流程图

    二、设计思路

    2.1数据录入部分

      首先需要创建一个数据库表格,用于储存学生的数据。之后,读出excel表中的数据,将数据插入到数据库表格中。然后手动或自动录入成绩信息。

    2.2数据计算部分

      读取数据库中各科成绩的信息,求和得出总成绩,将总成绩记录并更新表格。

    2.3输出部分

      将数据库表格中的数据,以一定的格式进行输出,并生成excel文件保存。

    三、具体实现过程

    3.1读取excel数据

      要读取excel文件,需要使用openpyxl模块,该模块是一个用于读取/写入Excel 2010 xlsx / xlsm / xltx / xltm文件的Python库。可以使用pip命令安装该模块。
    图2 安装openpyxl模块

    图2 安装openpyxl模块

      安装完成后,就可以执行命令,读取excel表格中的数据了。
    图3 读取文件数据

    图3 读取文件数据

      在上图中,使用load_workbook()命令,打开了名为”DK172register.xlsx”的工作簿,使用.worksheet[0],选择第一张工作表。使用for语句对工作表内的数据循环输出。于是,程序就会将表格中的每行数据,以元组的形式输出。其中包括学号和姓名信息。

    3.2创建数据库表格

      可以读取数据之后,我们需要创建一个数据库表格,用于储存读到的文件。
    图4 创建表格

    图4 创建表格

      上图中,使用sqlite3模块,创建了一个名为”class.db”的数据库对象,之后,在数据库中创建了一个名为”DK172”的表格。该表格包含”StudentID、Name、python_score、English_score、Total”这几个表头,分别用来代表”学号、姓名、python成绩、英语成绩、总成绩”。

    3.3插入表格数据

      创建表格完成之后,我们就可以将excel中的数据导入到数据库中了。在这里,我也遇到了一些问题。
    图5 INSERT报错

    图5 INSERT报错

      在上图中,我使用sqlite3模块创建数据库,使用openpyxl模块读取到了表格中的文件。将学号信息储存在id变量中,将姓名信息储存在name变量中。想通过INSERT语句及那个这两个信息插入到数据库表格中。没想到程序发生了错误。
      在百度上查找相关资料,发现是INSERT语句的格式不对,经过修改后,再次执行程序:
    图6 插入数据

    图6 插入数据

      上面的语句中,我将VALUES中的内容替换为了(%d ‘%s’),并用格式控制字符%将id、name变量中的值传入了VALUES中。程序正常执行,显示了导入数据的情况。为了更加直观的看出数据库中的数据,我使用”DB Brower for SQLite”查看数据库内容。
    图7 查看可视化界面

    图7 查看可视化界面

      可以看出,数据已经成功地导入了数据库中。

    3.4更新成绩数据

      在将excel表格中的数据导入到数据库之后,就需要插入成绩数据了。一开始我尝试使用INSERT语句进行数据导入,成绩数据导入成功,但是在DB中查看数据库,发现并不是我们想要的结果。
    图8 使用INSERT语句插入成绩数据

    图8 使用INSERT语句插入成绩数据

    图9 程序运行结果

    图9 程序运行结果

      由上图可以看到,刚刚使用INSERT语句插入的随机成绩数据,并不是插入到了我们想要的位置,而是增加了新的数据。所以应该使用其他语句执行该命令。
      于是,我尝试使用UPDATE命令,更新原有表格中的数据,从而实现添加数据的效果。
    图10 UPDATE更新数据

    图10 UPDATE更新数据

      上图中,我首先使用SELECT语句将“DK172”表格中所有的“StudentID”数据取出,并保存在IDs中。接着,使用for语句,将”IDs”中的数据循环取出,使用UPDATE语句,对指定的学生ID进行更新操作。
      可以看出,为了方便测试,程序中代表成绩的数据的”python”和”English”都是随机生成的。现在,我们去”DB Brower for SQLite”查看一下数据库里的内容。
    图11 插入随机数据

    图11 插入随机数据

      可以看出,随机产生的”python”和”English”数据,已经成功插入到了数据库中指定的位置。现在,我尝试为数据库手动输入数据。
      既然已经实现了将随机数据插入到数据库指定位置,要想实现手动输入数据,只需将产生随机数据改为手动输入数据就可以了。
    图12 手动输入数据

    图12 手动输入数据

      将”python”和”English”更改为手动输入,就实现了手动输入数据的功能。但是,如果仅仅修改这些,我们班42人的所有数据都需要手动输入,比较麻烦。所以我希望实现”前40个数据随机产生,后2个数据手动输入”的功能。
      要实现该功能,加一个条件判断语句就可以了,于是编写了下面的函数。
    图13 随机加手动数据

    图13 随机加手动数据

      上图的函数,设置了一个变量”con”用来记录循环次数。当循环次数小于40次时,让数据随机产生;当循环次数大于40次时,显示提示并手动输入数据。
    图14 查看可视化界面

    图14 查看可视化界面

      在上图中可以看出,最后两组数据确实是我所刚刚手动输入的数据。后面Total字段里的数据,我们可以先不看。那些数据是测试”计算总分”时产生的,与现在演示的功能无关。由于没有更新这些数据,所以这些数据是不正确的。
      现在,已经实现了”导入Excel数据”和”录入分数”功能,下面将尝试进行”计算总成绩”。

    3.5计算总分数

      要计算总分数,我想应该首先将每组数据中”python_score”和”English_score”数据取出,相加后记录在一个变量中,再使用UPDATE语句更新这组数据,从而将总分数据插入改组数据。于是编写如下代码:
    图15 计算总分数

    图15 计算总分数

      上面的代码中,我首先使用SELECT语句,将”DK172”表格中字段为”python_score”和”English_score”的所有数据保存在marks变量中。之后利用for语句,用mark变量逐条取出marks中的数据。于是,在每次循环中,mark[0]表示该组数据的“StudentID”数据;mark[1]表示该组数据的“python_score”数据;mark[2]表示该组数据的“English_score”数据。这样就可以使用UPDATE语句更新总分数据了。
      现在去”DB Brower for SQLite”中查看现在的“DK172”表格。
    图16 计算总分并更新数据库

    图16 计算总分并更新数据库

      可以看出,这里所显示的数据与图14所示的程序中的数据一致,说明程序执行成功。

    3.6将数据导入excel

      现在就基本上实现了要求的功能,记录排序名次功能我没能实现,但已经可以实现简单的排序,我会在后面介绍。为了将数据库中的文件保存,我希望能将数据库中的文件导出为excel文件。
    通过查阅资料和阅读课本例程,我编写了下面的代码去实现该功能。
    图17 数据库文件导入excel

    图17 数据库文件导入excel

      上图的程序中,使用openpyxl模块用于对excel的操作,创建了一个名为“Mysheet“的工作表。连接到数据库之后,使用SELECT语句将”DK172“中的所有数据记录在marks变量中,定义一个名为”head”的元组数据,用于保存表头数据,使用.append()方法将marks中的所有数据全部导入到excel中,最后使用.save()方法,将excel文件保存并命名为”test.xlsx”,从而实现想要的功能。
    图18 导入数据到excel

    图18 导入数据到excel

      上图中,可以看出已经将数据导入到了excel,但是字段为”StudentID”的那一列数据,显示的内容不对。查看其中任意一个元素的内容,可以在上方的内容栏看到该元素的内容。可以看出,我们刚刚导入的数据并没有问题,只是excel显示的数字格式不对。将其格式改为分数之后,内容就正常显示了。
    图19 excel正常显示内容

    图19 excel正常显示内容

    3.7代码优化

      接下来,我整理了之前写过的代码。将他们全部整合到了一个文件下,测试执行结果。由于代码稍多,我将它们拆分开进行分析。
    图20 part1

    图20 part1

      上图定义了两个函数,”create_table()”用来创建一个数据库表格;”export_data()”用来导入花名册里的数据。
    图21 part2

    图21 part2

      上图定义了两个函数,”update_mark()”用于录入数据,其中的”AutoNum”参数用来限定需要产生多少随机数据;“calculate_sum()”用来计算总成绩。
    图22 part3

    图22 part3

      上图包含两个函数,”show_data()”用来在命令行显示数据;”export_to_excel()”用来将数据库中的文件导出生成excel表格。
    图23 part4

    图23 part4

      上图是程序的调用部分,con是全局变量,用在”update_mark()”函数中。之后按顺序调用函数,分布实现想要的功能。
      程序执行之后,首先会导入数据,它会先导入40组随机数据,然后让你输入两组数据。之后会计算总分,完成计算后,会将数据表格显示在命令行界面,最后,生成这些数据对应的excel文件。程序的执行效果还是不错的,但是由于显示的结果太长,我就不在这里截图演示了。我会在附录部分截图展示。

    四、待改进部分及期望

    4.1排名并记录名次

      上面也曾说过,排名功能还没有实现。我曾尝试使用这样的思路:使用” ALTER”语句为数据库表格添加一个字段用于储存排名名次,之后使用SQLite的“Order By”子句,让所有数据根据总分降序排列,之后在新增的字段里按从1升序,写入名次,最后需要再次使用“Order By”按照”StudentID”升序排列。这样应该可以实现想要的效果,但是我卡在了”再新增字段里写入排名序号”这一步。因为我想使用UPDATE写入这些数据,但是UPDATE需要使用WHERE来描述更新数据的位置,然而经过排名的数据,“StudentID”已经乱序了,也就无法使用UPDATE语句。我也曾尝试使用索引方法,还是没有成功。
      最后,我找到了pandas模块,但通过该模块,我目前也只能实现一个简单的排序功能。
    图24 简单排序

    图24 简单排序

      上图中,使用pandas模块,先读取了刚刚生成的excel文件,然后使用.sort_index()方法对数据进行排序,其中的参数”by=Total“表示按照Total排序,”ascending=False”表示降序排列。

    4.2数据格式问题

      现在的程序中,包括导入数据和输入成绩数据等,都只是限制在了”特定格式的花名册”和”只有两科成绩”的条件内,可以在“增加程序适应性”方面加以改进。

    4.3代码问题

      现在我将代码集成在了一个文件中,但问题是:虽然不同的功能都定义了相应的函数,但是函数之间还是相互依赖,不够独立。以后可以优化代码,降低耦合性。

    五、实验总结

      这次实验还是挺有意思的。编程过程中遇到了很多问题,最后通过查找资料等方法也都得到了解决。通过这次实验我也感受到,我在编程或者生活中遇到的问题,别人也有遇到,而他们会把解决方案放到网上与我们分享。所以说,网上的资源太多了。
      但是,网上的资源大多也是提供一个解决方案,想真正能够深入学习,还是得静下心去慢慢学。

    六、附录

    6.1 read_data.py

    from openpyxl import load_workbook
    wb = load_workbook(r'C:UsersHJDesktoppyworkDK172register.xlsx')
    ws = wb.worksheets[0]
    for row in ws.values:
    	print(row)
    

    6.2 create_table.py

    import sqlite3
    conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    c = conn.cursor()
    print("Opened databaase successfully..")
    c.execute('''CREATE TABLE DK172 (StudentID, Name, python_score, English_score, Total score)''')
    conn.commit()
    print("Create table successfully..")
    conn.close()
    

    6.3 export_data.py

    import sqlite3
    from openpyxl import load_workbook
    conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    c = conn.cursor()
    print("Opened databaase successfully..")
    wb = load_workbook(r'C:UsersHJDesktoppyworkDK172register.xlsx')
    ws = wb.worksheets[0]
    for row in ws.values:
    	id = row[0]
    	name = row[1]
    	print(id, name, 'OK')
    	c.execute("INSERT INTO DK172 (StudentID, Name) VALUES (%d, '%s')"%(int(id), name))
    	conn.commit()
    print("Export data successfully..")
    conn.close()
    

    6.4 insert_random.py

    import sqlite3
    import random
    conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    c = conn.cursor()
    print("Opened databaase successfully..")
    c.execute("SELECT StudentID from DK172")
    IDs = c.fetchall()
    for id in IDs:
    	python = random.randint(85, 100)
    	English = random.randint(80, 100)
    	ID = id[0]
    	#print(ID, type(ID))
    	c.execute("UPDATE DK172 SET python_score = ?, English_score = ? WHERE StudentID = ?",(python, English, ID))
    	conn.commit()
    print("Insert data successfully..")
    conn.close()
    

    6.5 insert_progra.py

    import sqlite3
    import random
    conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    c = conn.cursor()
    print("Opened databaase successfully..")
    c.execute("SELECT StudentID from DK172")
    IDs = c.fetchall()
    for id in IDs:
    	ID = id[0]
    	print("ID =",ID)
    	python = int(input("Please type in the Python score:"))
    	English = int(input("Please type in the English score:"))
    	c.execute("UPDATE DK172 SET python_score = ?, English_score = ? WHERE StudentID = ?",(python, English, ID))
    	conn.commit()
    print("Insert data successfully..")
    conn.close()
    

    6.6 insert_mixing.py

    import sqlite3
    import random
    con = 0
    conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    c = conn.cursor()
    print("Opened databaase successfully..")
    c.execute("SELECT StudentID from DK172")
    IDs = c.fetchall()
    for id in IDs:
    	ID = id[0]
    	if con<40:
    		python = random.randint(85, 100)
    		English = random.randint(80, 100)
    	else:
    		if con == 40:
    			print("The first 40 data have been randomly generated.
    please manually enter the following data")
    		print("ID =",ID)
    		python = int(input("Please type in the Python score:"))
    		English = int(input("Please type in the English score:"))
    	c.execute("UPDATE DK172 SET python_score = ?, English_score = ? WHERE StudentID = ?",(python, English, ID))
    	con += 1
    	conn.commit()
    print("Update data successfully..")
    conn.close()
    

    6.7 calculate_sum.py

    import sqlite3
    import random
    conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    c = conn.cursor()
    print("Opened databaase successfully..")
    c.execute("SELECT StudentID, python_score, English_score from DK172")
    marks = c.fetchall()
    for mark in marks:
    	total = mark[1] + mark[2]
    	ID = mark[0]
    	print(mark[1], mark[2], total)
    	c.execute("UPDATE DK172 SET Total = ? WHERE StudentID = ?",(total, ID))
    	conn.commit()
    print("Calculate data successfully..")
    conn.close()
    

    6.8 show_data.py

    import sqlite3
    conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    c = conn.cursor()
    print("Opened database successfully");
    cursor = c.execute("SELECT StudentID, Name, python_score, English_score, Total  from DK172")
    print("  StudentID   Name     python  English  Total")
    for data in cursor:
    	print(data[0], data[1], '	', data[2],'	', data[3],'	', data[4])
    print("Operation done successfully");
    conn.close()
    

    6.9 excel_test.py

    from openpyxl import Workbook
    import sqlite3
    import random
    wb = Workbook()
    ws = wb.create_sheet("Mysheet",0)
    conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    c = conn.cursor()
    c.execute("SELECT * from DK172")
    marks = c.fetchall()
    head = ('StudentID', 'Name', 'Python_score', 'English_score', 'Total')
    ws.append(head)
    for mark in marks:
    	print(mark[0], mark[1], mark[2], mark[3], mark[4])
    	ws.append(mark)
    conn.close()	
    wb.save(r'C:UsersHJDesktoppywork	est.xlsx')
    

    6.10 Final_procedure.py

    import sqlite3
    import random
    from openpyxl import load_workbook, Workbook
    def create_table():
    	conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    	c = conn.cursor()
    	print("Opened database successfully.")
    	c.execute('''CREATE TABLE DK172 (StudentID, Name, python_score, English_score, Total score)''')
    	conn.commit()
    	print("Create table successfully!")
    	conn.close()
    	
    def export_data():
    	conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    	c = conn.cursor()
    	#print("Opened databaase successfully..")
    	print("Importing excel file......")
    	wb = load_workbook(r'C:UsersHJDesktoppyworkDK172register.xlsx')
    	ws = wb.worksheets[0]
    	for row in ws.values:
    		id = row[0]
    		name = row[1]
    		print(id, name, '	', 'OK')
    		c.execute("INSERT INTO DK172 (StudentID, Name) VALUES (%d, '%s')"%(int(id), name))
    		conn.commit()
    	print("Export data successfully!")
    	conn.close()
    	
    def update_mark(AutoNum):
    	global con
    	conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    	c = conn.cursor()
    	#print("Opened database successfully..")
    	print("Then enter the marks.")
    	c.execute("SELECT StudentID from DK172")
    	IDs = c.fetchall()
    	for id in IDs:
    		ID = id[0]
    		if con<AutoNum:
    			python = random.randint(85, 100)
    			English = random.randint(80, 100)
    		else:
    			if con == AutoNum:
    				print("The first %d data have been randomly generated.
    please manually enter the following data"%AutoNum)
    			print("ID =",ID)
    			python = int(input("Please type in the Python score:"))
    			English = int(input("Please type in the English score:"))
    		c.execute("UPDATE DK172 SET python_score = ?, English_score = ? WHERE StudentID = ?",(python, English, ID))
    		con += 1
    		conn.commit()
    	print("Update data successfully!")
    	conn.close()
    
    def calculate_sum():
    	conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    	c = conn.cursor()
    	#print("Opened database successfully..")
    	print("Calculate the total score...")
    	c.execute("SELECT StudentID, python_score, English_score from DK172")
    	marks = c.fetchall()
    	for mark in marks:
    		total = mark[1] + mark[2]
    		ID = mark[0]
    		#print(mark[1], mark[2], total)
    		c.execute("UPDATE DK172 SET Total = ? WHERE StudentID = ?",(total, ID))
    		conn.commit()
    	print("Calculate data successfully!")
    	conn.close()
    	
    def show_data():
    	conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    	c = conn.cursor()
    	#print("Opened database successfully")
    	print("
    ..............Show student data..............")
    	cursor = c.execute("SELECT StudentID, Name, python_score, English_score, Total  from DK172")
    	print("  StudentID   Name     python  English  Total")
    	for data in cursor:
    		print(data[0], data[1], '	', data[2],'	', data[3],'	', data[4])
    	print(".............   End of Table   .............")
    	print("Operation done successfully");
    	conn.close()
    
    def export_to_excel():
    	wb = Workbook()
    	ws = wb.create_sheet("Mark",0)
    	conn = sqlite3.connect(r'C:UsersHJDesktoppyworkclass.db')
    	c = conn.cursor()
    	c.execute("SELECT * from DK172")
    	marks = c.fetchall()
    	head = ('StudentID', 'Name', 'Python_score', 'English_score', 'Total')
    	print("Exporting to excel...")
    	ws.append(head)
    	for mark in marks:
    		#print(mark[0], mark[1], mark[2], mark[3], mark[4])
    		ws.append(mark)
    	wb.save(r'C:UsersHJDesktoppyworkDK17-2_Mrak.xlsx')
    	conn.close()
    	print("Export excel successfully!")
    
    if __name__ == '__main__':
    	con = 0 
    	create_table()
    	export_data()
    	update_mark(40)
    	calculate_sum()
    	show_data()
    	export_to_excel()
    
    

    6.11 order_data.py

    import pandas as pd
    df=pd.read_excel(r'C:UsersHJDesktoppyworkDK17-2_Mrak.xlsx',sheetname=0)
    print(df.sort_index(by='Total', ascending=False))
    

    6.12Final_procedure.py 效果展示

    在这里插入图片描述

  • 相关阅读:
    本周学习小结(04/11
    学习笔记之知识图谱 (Knowledge Graph)
    本周学习小结(28/10
    本周学习小结(21/10
    条件分页 代替离线查询
    Apache POI 一键上传(导入excel文件到数据库)
    easyui 菜单按钮&提示框
    Jquery ztree树插件
    Jquery ztree树插件2
    ui
  • 原文地址:https://www.cnblogs.com/ZHJ0125/p/12904523.html
Copyright © 2011-2022 走看看