吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2107|回复: 9
收起左侧

[Python 转载] 用python3统计数据我们学校的德育加分数据

[复制链接]
ctOS_ 发表于 2020-3-9 12:07
本帖最后由 ctOS_ 于 2020-3-9 21:40 编辑

引入:
前些日子我们学校部门上头要求统计上个学期的德育分
(就是统计上个学期所有学生参加志愿者的时长,然后汇总成表)
虽然好像很简单的样子
但是每个学院都需要一个独立的表格,但是总的数据表把全校所有学生的数据都放在一起了。
并且同一个学生可能参加多次志愿者,要把记录放到一起,合并单元格,从大到小排序
之前我想过用excel的分类汇总,但是部门其他几个人对Office软件似乎并不怎么理解
(我只用做两个学院,所以工作并不是很艰辛,但经常要帮她们处理问题)
这就很累人了。
于是我就想着用python写套代码,把中间流程去掉。

这样,这套德育分汇总代码就诞生了!


虽然可能对大部分坛友没什么用(我感觉自己的代码一点都不精简)

就当留个纪念好了

[Python] 纯文本查看 复制代码
while True:# 学院统计
    import xlrd
    import xlwt
    import pandas as pd
    from os import remove

    college = input('请问你当前要筛选的学院是?')
    doc = input('请输入数据库的文件名(带后缀)')
    outdoc = input('请输入你要输出的文件名(.xls)')
    data = xlrd.open_workbook(doc)  # 打开d数据库
    dataout = xlwt.Workbook(encoding='utf-8')
    dataout_sheet = dataout.add_sheet('result')
    line = 0
    sheet = data.sheet_by_index(0)  # 打开data.xlsx中第一个表
    nrows = sheet.nrows  # 获取表的行数
    Class = ['班级']  # 存放该学院班级的列表
    Notclass = []  # 存放不是该学院的班级列表


    # 第一步,找出该学院的相关数据

    def writein(x, l, s):
        fanwei = len(x)
        for i in range(fanwei):
            s.write(l, i, x[i])

    print('-----------------------------------开始从数据中筛选班级------------------------')
    for i in range(nrows):  # 表中的第i行
        idata = sheet.row_values(i)  # 获取第i行数据
        iclass = idata[0]  # 获取班级单元格的值
        eleclass = iclass[0:2]  # 获取前两个字(也就是班级专业简称)
        isclass = False
        notclass = False
        for y in Class:
            if y == eleclass:
                isclass = True
        for y in Notclass:
            if y == eleclass:
                notclass = True
        if isclass:
            writein(idata, line, dataout_sheet)
            line += 1
        if notclass == False and isclass == False:
            ask = input('请问<' + eleclass + '>是不是<' + college + '>的班级?(y/n):')
            if ask == 'y':
                Class.append(eleclass)
                writein(idata, line, dataout_sheet)
                line += 1
            elif ask == 'n':
                Notclass.append(eleclass)

    dataout.save('step.xls')
    print('-----------------------------------筛选完毕------------------------')
    # 第二步,就当前数据按照姓名,班级,日期进行排序
    print('-----------------------------------开始给数据排序------------------------')
    data = pd.read_excel('step.xls')  # 用pd打开excel
    data.sort_values(by=['姓名', '班级', '日期'], inplace=True)
    data.to_excel('step1.xlsx')  # 输出排序后的结果
    print('-----------------------------------计算时长与加分(记得请将加分细则填入表2)------------------------')
    # 第三步,准备根据时长总和排序
    data = xlrd.open_workbook('step1.xlsx')  # 打开数据库
    sheet = data.sheet_by_index(0)  # 打开第一个表
    nrows = sheet.nrows  # 读取数据表行数
    start = 0
    end = 0
    timetotal = 0  # 该学生总时长

    newdoc = xlwt.Workbook(encoding='utf-8')  # 新表(存储总时长和姓名)
    newsheet = newdoc.add_sheet('result')
    line = 1  # 实时更新新表写入数据的行数
    newsheet.write(0, 0, '姓名')
    newsheet.write(0, 1, '时长')

    for i in range(1, nrows-1):  # 因为数据表第一行不是数据,所以从第二行开始
        idata = sheet.row_values(i)
        iname = idata[2]
        y = i + 1
        ydata = sheet.row_values(y)
        yname = ydata[2]
        if i < nrows:
            if iname == yname:
                timetotal += idata[5]
            else:
                timetotal += idata[5]
                newsheet.write(line, 0, iname)
                newsheet.write(line, 1, timetotal)  # 纪录这个学生的总时长
                timetotal = 0
                line += 1
    timetotal += idata[5]  # 在i=nrows时,没有i+1了,所以独立出来再写一次
    newsheet.write(line, 0, iname)
    newsheet.write(line, 1, timetotal)


    newdoc.save('step2.xls')

    data = pd.read_excel('step2.xls')  # 用pd打开excel
    data.sort_values(by='时长', inplace=True, ascending=False)
    data.to_excel('step3.xlsx')  # 输出排序后的结果
    remove('step.xls')
    remove('step2.xls')  # 清理一下之前的文件


    # 第四步 在原数据表的表2进行时长与分数的换算
    print('-----------------------------------准备写入最终数据------------------------')
    def score(x):
        lable2 = xlrd.open_workbook('data.xlsx')
        sheet2 = lable2.sheet_by_index(1)
        lines = sheet2.nrows
        for i in range(1, lines):
            idata = sheet2.row_values(i)
            maxtime = float(idata[0])
            if maxtime >= x:
                return float(idata[1])


    # 第五步 以step1.xlsx和step3.xlsx为参考,最终成表

    data = xlrd.open_workbook('step3.xlsx')  # 打开新表
    sheet = data.sheet_by_index(0)
    nrows = sheet.nrows  # 获取新表行数

    data2 = xlrd.open_workbook('step1.xlsx')
    sheet2 = data2.sheet_by_index(0)
    nrows2 = sheet2.nrows  # 旧表行数

    result = xlwt.Workbook(encoding='utf-8')  # 最终数据库
    result_sheet = result.add_sheet('result', cell_overwrite_ok=True)  # 结果表
    x = sheet2.row_values(0)

    style = xlwt.XFStyle()
    al = xlwt.Alignment()
    al.horz = 0x02
    al.vert = 0x01
    style.alignment = al


    def wrotein(data, line, doc):
        lenline = len(data)
        for i in range(lenline - 1):
            doc.write(line, i, data[i + 1], style)
        print('-----------------------------------写入'+data[2]+'的数据------------------------')

    wrotein(x, 0, result_sheet)  # 写入表头
    line = 1  # 从第一行开始写入数据

    for i in range(1, nrows):  # 新表中遍历
        idata = sheet.row_values(i)  # 新表第i行
        iname = idata[1]  # 姓名
        iscore = score(idata[2])  # 总时长
        place = False  # 判断是否找对了地方
        for y in range(1, nrows2):
            ydata = sheet2.row_values(y)
            yname = ydata[2]

            if place == False and iname == yname:
                wrotein(ydata, line, result_sheet)
                place = True
                step = 0
                start = line
                Place = y
                line += 1
            elif place == True and iname == yname:
                wrotein(ydata, line, result_sheet)
                step += 1
                line += 1
            if place == True and iname != yname:
                place = False
                break

        the_data = sheet2.row_values(Place)
        theclass = the_data[1]
        thename = the_data[2]
        thescore = str(iscore)
        result_sheet.write_merge(start, start + step, 0, 0, theclass, style)
        result_sheet.write_merge(start, start + step, 1, 1, thename, style)
        result_sheet.write_merge(start, start + step, 5, 5, thescore, style)



        print('-----------------------------------合并相同数据------------------------')
    remove('step1.xlsx')
    remove('step3.xlsx')
    result.save(outdoc + '.xls')
    print('--------------------------------------------------------------------------<成功>')
    print('---------------------------------------------------------------------------请记得修改日期的单元格格式')


表一放数据
表二是具体的加分规则(两个表第一行都不写数据)

  班级  
姓名
日期
服务项目
服务时长/小时
加分
组织部门

免费评分

参与人数 3吾爱币 +1 热心值 +2 收起 理由
plasd + 1 谢谢@Thanks!
夕临垓下 + 1 我很赞同!
zp2020qq + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

linling 发表于 2020-3-9 12:24
代码很棒,方便他人,自己有时候也可以快速改改应急呀。
ericwise 发表于 2020-3-9 13:02
GalaxyMimi 发表于 2020-3-9 13:27
HighBox 发表于 2020-3-9 13:47
收下了,谢谢楼主分享
知意执意 发表于 2020-3-9 20:38
值得学习
 楼主| ctOS_ 发表于 2020-3-9 21:42
我今晚测试的时候发现
程序不会算上该学院中最后一个学生纪录
现在修改好了
不好意思
wolaileo 发表于 2020-3-10 10:48
我觉得 还是 把 表格一起传(修改掉 真实数据),这样才好测试代码

免费评分

参与人数 1吾爱币 +1 收起 理由
ctOS_ + 1 严谨

查看全部评分

 楼主| ctOS_ 发表于 2020-3-10 11:12
wolaileo 发表于 2020-3-10 10:48
我觉得 还是 把 表格一起传(修改掉 真实数据),这样才好测试代码

表格里其实就班级,姓名还有服务项目比较涉及隐私
数据量大的话测试代码也比较麻烦
可以自己随便做个数据少一点的excel啦

我们学校的班级命名格式是<专业简称+入学年份+班级序列>
比如说19年入学的大数据技术与应用,就写成<数应191>
判断班级是否所属学院也只根据前面两个字
其他姓名张三李四王五之类都没问题
加分那一栏留空,在表二里用这样的格式输入就好了
最大时长        得分
5        0.5
10        1
20        1.5
30        2
plasd 发表于 2020-3-10 12:34
先收藏,感谢
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 07:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表