python3读写excel,计算学分绩

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35603331/article/details/79616425

问题背景

今天遇到一个小任务,根据学校整个电力系一个学期的各科成绩表,计算出每个人的学分绩。数据共有5000+条,每条数据代表每个人每一科的成绩,由于每个人的考试科目数量不一,并且存在不参与学分绩计算的任选课,直接使用excel无法达成目的。经过考虑使用python3脚本计算学分绩。

一.安装库

首先安装读写excel的两个库
写入excel库

pip install xlwt

读取excel库

pip install xlrd

二.读取excel文件测试

# 打开excel文件
input_data = xlrd.open_workbook('score.xlsx')
# 打开文件中的指定工作表,索引从0开始
score_sheet = input_data.sheet_by_index(0)
# 获取总数据条数
n = score_sheet.nrows
# 循环读取指定单元格内容
for row_num in range(1, n):
    # 参数为行号,列号,读取到的数据根据单元格格式不同,可能是字符串或者数字
    name = score_sheet.cell_value(row_num,1)
    # 根据数据进行逻辑判断等···

三.写入excel文件测试

# 新建文件
result_book = xlwt.Workbook()
# 添加工作表
result_sheet = result_book.add_sheet('Result Sheet')
# 用于写入表头的方法,参数为行号,列号,内容,序号从0开始
def writeTitle(result_sheet):
    result_sheet.write(0, 0, '学生学号')
    result_sheet.write(0, 1, '学生姓名')
    result_sheet.write(0, 2, '学生班级')
    result_sheet.write(0, 3, '学生总学分')
    result_sheet.write(0, 4, '学生总绩点')
    result_sheet.write(0, 5, '学生学分绩')
writeTitle(result_sheet)
# 保存文件,注意保存时不要打开这个excel,不然会因为文件被占用而失败
result_book.save('15级学分绩.xlsx')

四.思路

由于excel本身有排序功能,并且排序后的文件,数据被读取的顺序也会改变
因此可以事先在excel中根据学号排序,保证同一个人的各条成绩数据连续
这样我们就可以根据下一条数据的学号和当前数据的学号是否一致来判断一个人的所有信息是否统计完毕。
每统计完一个人的数据,就向保存学分绩的表中写入这个人的信息,最终保存即可。

五.注意事项

  1. 在给excel表排序时,不要根据姓名排序,因为可能会有重名的问题存在
  2. 需要注意是否存在个别数据中成绩为空的情况,或者是为及格,优秀等字样,这样的数据最好事先处理。
  3. 注意表中数据是否带有空格,如果学号字段带有空格,可能导致判断学号一致时出错
  4. 需要注意是否去掉了任选课
  5. excel的筛选功能并不会影响数据读取,如果只想读取表中部分数据,需要将这部分数据先筛选,再复制到另一个表中读取,如筛选掉16,17级数据,只留下15级数据,将15级数据复制到表2中进行读取。

六.源码附录

import xlwt
import xlrd


# 序号从0开始,表头第0行,有效数据从第1行开始
# 输入数据格式:1学号,2姓名,4班级,8学分,9成绩
std_num_index = 1
name_index = 2
class_index = 4
xf_index = 8 # 学分索引
score_index = 11 #考试成绩索引
type_index = 10 #考试成绩索引
input_data = xlrd.open_workbook('aa.xlsx')
score_sheet = input_data.sheet_by_index(3)
# 输出数据格式:0学号,1姓名,2班级,3总学分,4总绩点,5总学分绩
r_std_num_index = 0
r_name_index = 1
r_class_index = 2
r_all_xf_index = 3
r_all_score_index = 4
r_result_index = 5
# 当前数据条数+1
result_num = 1
name = ''
std_class = ''
# 总学分和总绩点
all_xf = 0;
all_score = 0;

def writeOneStudent(result_sheet,result_num):
    result_sheet.write(result_num, r_std_num_index, std_num)
    result_sheet.write(result_num, r_name_index, name)
    result_sheet.write(result_num, r_class_index, std_class)
    result_sheet.write(result_num, r_all_xf_index, all_xf)
    result_sheet.write(result_num, r_all_score_index, all_score)
    if all_xf!= 0:
        result_sheet.write(result_num, r_result_index, all_score/all_xf)
def writeTitle(result_sheet):
    result_sheet.write(0, r_std_num_index, '学生学号')
    result_sheet.write(0, r_name_index, '学生姓名')
    result_sheet.write(0, r_class_index, '学生班级')
    result_sheet.write(0, r_all_xf_index, '学生总学分')
    result_sheet.write(0, r_all_score_index, '学生总绩点')
    result_sheet.write(0, r_result_index, '学生学分绩')


# 用于存储学分绩数据
result_book = xlwt.Workbook()
result_sheet = result_book.add_sheet('Result Sheet')
writeTitle(result_sheet)
# 流程:读取每行数据,叠加学分,总绩点,读取后判断下一行学号是否改变,如果改变,说明一个人的数据统计完毕,输出
# 缓存第一个人的学号
next_std_num = score_sheet.cell_value(1,std_num_index).strip()
n = score_sheet.nrows
for row_num in range(1, n):
    print(row_num)
    # 取上一次读取到的本条数据的学号
    std_num = next_std_num
    # 姓名不必反复读取
    # name = score_sheet.cell_value(row_num, name_index)
    # 班级不必反复读取
    # std_class = score_sheet.cell_value(row_num, class_index)
    type = score_sheet.cell_value(row_num, type_index)
    if type.strip() != '任选':

        # 学分
        xf = score_sheet.cell_value(row_num, xf_index)
        # 成绩(负数变正)
        score = score_sheet.cell_value(row_num, score_index)
        if xf != '' and not str(xf).isspace() and score != '' and not str(score).isspace():
            # 累加学分
            xf = abs(float(xf))
            all_xf+= xf
            # 累加绩点
            score = abs(float(score))
            all_score+= xf*score
        # 取下一条数据学号
    if row_num<n-1:
        next_std_num = score_sheet.cell_value(row_num+1, std_num_index).strip();
        if next_std_num != std_num:
            # 一个人的数据统计完毕
            name = score_sheet.cell_value(row_num, name_index)
            std_class = score_sheet.cell_value(row_num, class_index)
            # 写入记录
            writeOneStudent(result_sheet,result_num)
            result_num+=1
            # 清空累加学分和总绩点
            all_xf = 0;
            all_score = 0;
    else:
        # 末尾
        # 一个人的数据统计完毕
        name = score_sheet.cell_value(row_num, name_index)
        std_class = score_sheet.cell_value(row_num, class_index)
        # 写入记录
        writeOneStudent(result_sheet, result_num)
        result_num += 1
        # 清空累加学分和总绩点
        all_xf = 0
        all_score = 0
result_book.save('15级2017-2018(1)学分绩.xlsx')

七.总结
其实了解了读写功能如何实现后,基本没有难点了,源码因为是临时简单写的,比较丑陋,仅供参考。

猜你喜欢

转载自blog.csdn.net/qq_35603331/article/details/79616425
今日推荐