实验目的:
(1)了解扩展库openpyxl的安装与使用。
(2)了解使用扩展库openpyxl操作Excel文件的方法。
(3)熟练运用字典结构解决实际问题。
实验内容:
假设某学校所有课程每学期允许多次考试,学生可随时参加考试,系统自动将每次成绩添加到Excel文件(包含3列:姓名,课程,成绩)中,现期末要求统计所有学生每门课程的最高成绩。
编写程序,模拟生成若干同学的成绩并写入Excel文件,其中学生姓名和课程名称均可重复,也就是允许出现同一门课程的多次成绩,最后统计所有学生每门课程的最高成绩,并写入新的Excel文件。
实验环境:
Windows 10/11 + Jupyter Notebook \PyCharm \ Spyder \ VScode + Python 3.12
实验代码
from random import choice, randint
from openpyxl import Workbook, load_workbook
# 生成随机数据
def generateRandomInformation(filename):
workbook = Workbook()
worksheet = workbook.worksheets[0]
worksheet.append(['姓名','课程','成绩'])
# 中文名字中的第一、第二、第三个字
first = '赵钱孙李'
middle = '伟昀琛东'
last = '坤艳志'
subjects = ('语文','数学','英语')
for i in range(200):
name = choice(first)
# 按一定概率生成只有两个字的中文名字
if randint(1,100)>50:
name = name + choice(middle)
name = name + choice(last)
# 依次生成姓名、课程名称和成绩
worksheet.append([name, choice(subjects), randint(0, 100)])
# 保存数据,生成Excel 2007格式的文件
workbook.save(filename)
def getResult(oldfile, newfile):
# 用于存放结果数据的字典
result = dict()
# 打开原始数据
workbook = load_workbook(oldfile)
worksheet = workbook.worksheets[0]
# 遍历原始数据
for row in worksheet.rows:
if row[0].value == '姓名':
continue
# 姓名,课程名称,本次成绩
name, subject, grade = map(lambda cell:cell.value, row)
# 获取当前姓名对应的课程名称和成绩信息
# 如果result字典中不包含,则返回空字典
t = result.get(name, {})
# 获取当前学生当前课程的成绩,若不存在,返回0
f = t.get(subject, 0)
# 只保留该学生该课程的最高成绩
if grade > f:
t[subject] = grade
result[name] = t
workbook1 = Workbook()
worksheet1 = workbook1.worksheets[0]
worksheet1.append(['姓名','课程','成绩'])
# 将result字典中的结果数据写入Excel文件
for name, t in result.items():
print(name, t)
for subject, grade in t.items():
worksheet1.append([name, subject, grade])
workbook1.save(newfile)
if __name__ == '__main__':
oldfile = r'd:\test.xlsx'
newfile = r'd:\result.xlsx'
generateRandomInformation(oldfile)
getResult(oldfile, newfile)
运行结果:
D:\Users\ASUS\anaconda3\python.exe "C:\Users\ASUS\AppData\Local\Temp\e1d94af6-a14a-45e4-ae03-62510b7828c9_实验9+处理Excel文件中的成绩数据 (1).zip.8c9\实验9 处理Excel文件中的成绩数据.py"
赵艳 {'数学': 10, '语文': 90}
李琛坤 {'语文': 99, '数学': 48, '英语': 35}
钱艳 {'英语': 83}
孙伟志 {'数学': 52, '语文': 33}
李志 {'语文': 96, '数学': 64, '英语': 96}
李坤 {'英语': 94, '数学': 69}
孙昀艳 {'语文': 39, '数学': 44}
李伟坤 {'英语': 86, '数学': 78}
孙艳 {'语文': 61, '英语': 62}
钱昀艳 {'语文': 98, '英语': 54}
赵志 {'语文': 94, '数学': 69, '英语': 84}
李昀坤 {'数学': 25, '语文': 60}
李伟志 {'语文': 80, '英语': 2}
孙志 {'英语': 80, '语文': 65, '数学': 28}
赵坤 {'英语': 87, '语文': 85, '数学': 99}
赵东志 {'英语': 37, '语文': 44}
赵琛艳 {'语文': 92, '英语': 81}
李昀艳 {'语文': 68, '数学': 60}
钱东志 {'语文': 58, '英语': 97, '数学': 94}
孙琛志 {'数学': 62}
钱琛志 {'英语': 93}
钱东艳 {'语文': 25}
钱坤 {'英语': 99, '数学': 15, '语文': 90}
钱伟坤 {'英语': 57}
李东志 {'英语': 86, '语文': 9}
李东艳 {'数学': 100}
孙东坤 {'英语': 19, '语文': 47, '数学': 10}
赵琛坤 {'英语': 91}
孙琛艳 {'数学': 40, '英语': 66}
孙坤 {'语文': 39, '英语': 99, '数学': 82}
李琛艳 {'数学': 57, '语文': 92}
孙昀坤 {'英语': 63, '语文': 88}
孙昀志 {'数学': 73, '语文': 93, '英语': 86}
钱志 {'语文': 97, '英语': 76, '数学': 88}
赵东坤 {'语文': 75}
李艳 {'数学': 77, '英语': 44, '语文': 87}
赵昀坤 {'语文': 25, '数学': 66}
赵东艳 {'英语': 90, '语文': 96, '数学': 49}
钱伟艳 {'数学': 56, '语文': 98}
孙伟艳 {'数学': 43, '语文': 14, '英语': 82}
孙东志 {'语文': 60, '数学': 53}
钱琛坤 {'语文': 29}
李琛志 {'语文': 95, '数学': 49}
赵琛志 {'英语': 61, '数学': 24}
赵昀志 {'英语': 23}
赵伟志 {'英语': 65, '语文': 59}
钱昀坤 {'英语': 62}
李东坤 {'数学': 35}
赵伟坤 {'数学': 77, '语文': 46}
李昀志 {'语文': 37}
孙琛坤 {'英语': 91}
李伟艳 {'英语': 12}
钱琛艳 {'语文': 33}
钱昀志 {'语文': 75, '英语': 38}
孙伟坤 {'英语': 58}
进程已结束,退出代码为 0