用Python写个空课表生成器

开发背景
刚入大学的CYQ加入了我们学校的学生会,面对繁杂的工作,能“偷懒”就“偷懒”。这不,最近要举办几场活动,部门要安排人员值班,需要十几人的空课表。此时,CYQ自告奋勇,接下了制作任务,没想到,困难重重,效率低下,重复性劳动,小学加减法算得头皮发麻。聪明的CYQ终于在倒下前的那一刻,想起了自己的身份,在午夜时分,完成了这个小程序。


前提准备

  • Python3.7

  • 安装xlrd,xlwd第三方库
    (建议用pip安装,官方原装速度感人,镜像速度贼快)自行百度,python国内镜像源

  • 电脑

  • 南昌航空大学官方总课表(这里仅仅是对我们学校的版本,可自行更改源代码,达到自己的需求)

  • 脑子


需求分析

  • 能够根据一份总的课程表(有课)生成一份空课表Excel表
  • 并能根据开始周数和结束周数进行在线生成
  • 操作要求简单,易操作

功能实现(较为简单)

  • 生成函数
  • 可视化图形界面(日后优化)

问题分析

  • 如何实现对xls文件读取呢?
    我们借用了第三方库xlrd,xlwd对于这两种函数的介绍,这里不细讲。
    我们知道xlrd是用于读取.xls文件的,xlwd是写入.xls文件的,我们可以通过观察,r和w的区别记忆,read和write。
    这里有几个关键的用法

    • xrld部分

      用于打开一个Excel文件

       work_book = xlrd.open_workbook('filename.xls')
      

      获取Excel文件的所有sheet,这里我们暂时不用,因为CYQ的课表只有一个sheet

       work_sheets = work_book.sheet_names()
      

      通过索引来访问一个表单

       table = work_book.sheet_by_index(0)
      

      获取到文档的行数

       nrows = table.nrows
      

      类推这是列数

       ncols = table.ncols
      

      通过索引来访问第row_index行的所有数据,以字符串形式返回

       table.row_values(row_index)
      

  • 如何实现对xls文件写入操作呢?

    • xrwd部分

      这是对写入文档的编码规定为ascii

      workbook = xlwt.Workbook(encoding = 'ascii')
      

      创建一个sheet,名称为sheet_1
      里面的cell_overwrite_ok = True参数是为了防止重复操作,导致报错

        sheet_1 = workbook.add_sheet('sheet_1',cell_overwrite_ok = True)
      

      新建一个样式

      style = xlwt.XFStyle()
      

      字体样式

      font = xlwt.Font()
      

      字体类型为这个东东

      font.name = 'Times New Roman'
      

      实例化

      font.bold = True
      style.font = font
      

      这是最重要的,把Contents写入到sheet_1中的row行col列,用你设置的style来写入(也可以不用style,上面的新建样式就可以省去)

      sheet_1.write(row,col,"Contens",style)
      

  • 数据的处理
    首先,确定我们要的数据结构
    用字典用得方便些
    所以用一个字典来存储全部人的数据
 all_the_data = {}##存储总的数据

首先获取本目录下的满足要求的文件

import os
files = [d for d in os.listdir('.')]

通过生成器来生成一个文件列表
之后通过一个大循环来获取所需的数据(根据我们课表的特征)
名字在第一行,可以通过正则来匹配
前三行为无效数据,最后一行为无效数据
剩下的为有效数据,通过正则来匹配
大循环开始

    for i in files:if (i[-4:]=='.xls' and i != 'Blank_Courses.xls'):work_book = xlrd.open_workbook(i) #open file to read contenswork_sheets = work_book.sheet_names()table = work_book.sheet_by_index(0) # by_name('')sheet()[x]nrows = table.nrowsncols = table.ncolsname = re.findall(' (.*?) ',table.cell(0,0).value)[0]print(name+"OK!\n")course = {}#用一个字典来存储一个循环里面一个人的信息for i in range(nrows-4):#从上往下遍历表单内容li = [] #用一个表存储临时数据for j in table.row_values(i+3):li.append(j)course[i] = li

以上有个判断,从本目录下的所有xls文件,过滤生成文件,加入到程序的处理链条中
匹配一下名字,正则这样写,会更好一点,名字存在name里面
之后从上到下遍历初始数据
为了得到有效信息,我们继续处理

Course = {}
for index in range(len(course)):li_a = [] #创建一个列表,储存每大节课的周for i in range(len(course[index])):#从每大节课遍历if(i==0): #跳过无效数据continueli = []#创建一个小列表,存储星期所对的课data = re.findall(r'\n.*?\n.*?\n(.*?)\n.*?\n',course[index][i])#正则匹配数据for j in data:i.append(j.replace('[周]','').split(',')) #存储到小列表中li_a.append(li) #存储到大列表中Course[index] = li_a #将列表存储到字典中,获得了一个完整的有课表

聪明的你如果对正则感兴趣的话,可以搜索相关资料。
上面我们又对数据进行了处理,将时间匹配到了
程序设计基础
杨老师()
9[周]
B203

我们学校的表单信息是这种格式,正则就按上面这样写
之后我们同理,将数据存储起来

for index in Course:L = []for i in range(len(Course[index])):have = e_to_have(Course[index][i])#生成有课的所有时间点ha_not = e_to_not(have,start,end)#生成无课的区间,和所有点if(index not in all_the_data.keys()):s = '\n'+name #这是else:s = all_the_data[index][i] + '\n' + name #追加写入,不删除之前的我数据temp = ' '#用来判断是不是全员无课的标记for j in ha_not:temp = temp+j+' 'if(temp==' '):L.append(' '+s)#标记在这里添加else :L.append(s+temp)all_the_data[index] = L #存入总的数据字典里

大循环到此结束
以上我们使用了两个函数

def e_to_have(li):L = []for i in li:#传入的i是一个列表,但只有一个元素,用i[0]表示它的值if(len(i[0])<=2):#没有出现-连接(表示区间)时,小于2L.append(i[0])else:sp = i[0].split('-')##进行切片for i in range(int(sp[1])-int(sp[0])+1):#循环加入单点到有课列表L.append(str(int(sp[0])+i))return L

转化为无课的区间或者时间点

def e_to_not(li,start,end):L = []##生成无课单点表for i in range(end-start+1):##循环次数,也表示总的课区间if(str(i+start)not in li):L.append(i+start)#若此单点不在有课表内,就表示无课,加入其中    S = []##生成无课区间和单点po = 0##初始一个区间头for i in range(len(L)-1):if(L[i]+1!=L[i+1]):if(L[po]!=L[i]):S.append(str(L[po])+'-'+str(L[i]))else:S.append(str(L[po]))po = i+1else:if(i==len(L)-2):S.append(str(L[po])+'-'+str(L[i+1]))#此算法要对最后一个要进行特判,才能加入连续区间return S

里面的算法就不细讲了,思路重要
之后我们进行写入操做
将字典里面的数据依次写入到文件里面

    #进行写入操作workbook = xlwt.Workbook(encoding = 'ascii')sheet_1 = workbook.add_sheet('NCHU_Blank_Courses',cell_overwrite_ok = True) #create sheet objectstyle = xlwt.XFStyle()font = xlwt.Font()font.name = 'Times New Roman'font.bold = Truestyle.font = font #字体样式设置,可以跳过for index in range(len(all_the_data)):for i in range(len(all_the_data[index])):sheet_1.col(i).width = 256*25sheet_1.row(index).height = 256*25if (all_the_data[index][i][:2] != '  '):sheet_1.write(index,i,all_the_data[index][i],style)else:sheet_1.write(index,i,"全员无课",style)

到这里大概的框架就完成了,接下来就是漫长的迭代过程。或者是shi沉大海
不过我们也不能忘记了用户体验,配置文件README.docx
还是要写一下的,程序开头的初步使用操作也是要写的
程序执行过程中的状态,也是要写的,哪怕甩点什么数据出来也是可以的
麻雀虽小,五脏可还得俱全啊!
最后来甩几张图

最后完整代码

def e_to_have(li):L = []for i in li:##i是一个列表,但只有一个元素,用i[0]表示它的值if(len(i[0])<=2):#没有出现-连接(表示区间)时,小于2L.append(i[0])else:sp = i[0].split('-')##进行切片for i in range(int(sp[1])-int(sp[0])+1):##循环加入单点到有课列表L.append(str(int(sp[0])+i))return Ldef e_to_not(li,start,end):L = []##生成无课单点表for i in range(end-start+1):##循环次数,也表示总的课区间if(str(i+start)not in li):L.append(i+start)##若此单点不在有课表内,就表示无课,加入其中    S = []##生成无课区间和单点po = 0##初始一个区间头for i in range(len(L)-1):if(L[i]+1!=L[i+1]):if(L[po]!=L[i]):S.append(str(L[po])+'-'+str(L[i]))else:S.append(str(L[po]))po = i+1else:if(i==len(L)-2):S.append(str(L[po])+'-'+str(L[i+1]))##此算法要对最后一个要进行特判,才能加入连续区间return Sdef main():print("=========================\n使用前,阅读使用文档(README.docx)\n目前只可以使用南昌航空大学课程表\n请将成员课表(.xls文件)放在本程序目录下\n目录下不要放其他文件\n本程序上级目录尽量不要为中文名\nMADE FOR NCHU WITH PYTHON\n=========================")try:print("请输入课程周数内的合理数字\n")start = int(input("请输入开始周数:\n"))end = int(input("请输入结束周数:\n"))if(start > 25 or start < 0 or end > 25 or end < 0 or start > end):print("请输入课程合理的数字\n你的输入有误,程序自动退出")input()returnexcept:print("请输入合理的数字\n你的输入有误,程序自动退出")input()returnimport re,osimport xlrd #用来读取excel文件,不能修改数据import xlwt #创建Excel文件并对其进行操作,但不能对已有的Excel文件进行修改import xlutils #对已有的Excel文件进行修改all_the_data = {}##存储总的数据files = [d for d in os.listdir('.')]for i in files:if (i[-4:]=='.xls' and i != 'Blank_Courses.xls'):####################################循环体work_book = xlrd.open_workbook(i) #open file to read contenswork_sheets = work_book.sheet_names()table = work_book.sheet_by_index(0) # by_name('')sheet()[x]nrows = table.nrowsncols = table.ncolsname = re.findall(' (.*?) ',table.cell(0,0).value)[0]print(name+"OK!\n")course = {}for i in range(nrows-4):#从上往下遍历li = [] #用一个表存储数据for j in table.row_values(i+3):li.append(j)course[i] = liCourse = {}for index in range(len(course)):li_a = [] #创建一个列表,储存每大节课的周for i in range(len(course[index])):#从每大节课遍历if(i==0): #跳过无效数据continueli = []#创建一个小列表,存储星期所对的课data = re.findall(r'\n.*?\n.*?\n(.*?)\n.*?\n',course[index][i])#正则匹配数据for j in data:li.append(j.replace('[周]','').split(',')) #存储到小列表中li_a.append(li) #存储到大列表中Course[index] = li_a #将列表存储到字典中,获得了一个完整的有课表for index in Course:L = []for i in range(len(Course[index])):have = e_to_have(Course[index][i])ha_not = e_to_not(have,start,end)if(index not in all_the_data.keys()):s = '\n'+nameelse:s = all_the_data[index][i] + '\n' + nametemp = ' 'for j in ha_not:temp = temp+j+' 'if(temp==' '):L.append(' '+s)else :L.append(s+temp)all_the_data[index] = L##############################循环体#进行写入操作workbook = xlwt.Workbook(encoding = 'ascii')sheet_1 = workbook.add_sheet('NCHU_Blank_Courses',cell_overwrite_ok = True) #create sheet objectstyle = xlwt.XFStyle()font = xlwt.Font()font.name = 'Times New Roman'font.bold = Truestyle.font = fontfor index in range(len(all_the_data)):for i in range(len(all_the_data[index])):sheet_1.col(i).width = 256*25sheet_1.row(index).height = 256*25if (all_the_data[index][i][:2] != '  '):sheet_1.write(index,i,all_the_data[index][i],style)else:sheet_1.write(index,i,"全员无课",style)#sheet_1.write(index,i,s,style)    #sheet_1.write(r,c,val,style) #write dates in the sheet whith style        workbook.save('Blank_Courses.xls')print("=========================\nCongratulations!生成空课表成功!\n若程序出现问题可以互相交流QQ1614143338\n=========================")input()
#    print(Course)if __name__ == '__main__':main()

写的不是很好,由于写入文件需要在同一函数中,创建文件和保存文件,导致很难再拆分主函数里面的功能。那就为了代码的集中,区域模块化,干脆就把读取数据也写入到主函数中。上述的原因导致不能较好的模块化程序,引发一些程序的漏掉和不稳定性,望大佬们指正。也可以一起交流学习。

用Python写个空课表生成器-Excel文件操作实例相关推荐

  1. python自动化之excel文件操作

    excel文件操作 首先为什么要讲excel文件操作呢,因为一般用到的自动化框架中大部分都是用excel存放测试用例数据,是数据驱动的来源. 一.安装 本次分享的是通过openpyxl 这个模块来操作 ...

  2. excel数据导入python后不对齐_Python处理Excel文件的实用姿势

    真正的勇士,敢于直面银行卡上的余额,敢于正视磅秤上的数字. 表格数据是最常见的数据类型,Excel是日常办公中最常接触的文件. 上一章提过Python可以通过openpyxl模块处理Excel文件. ...

  3. python 导出大量数据到excel_怎么在python中将大量数据导出到Excel文件

    怎么在python中将大量数据导出到Excel文件 发布时间:2021-01-16 11:09:40 来源:亿速云 阅读:76 作者:Leah 这期内容当中小编将会给大家带来有关怎么在python中将 ...

  4. Python使用xlwt和xlrd读写excel文件

    Python使用xlwt和xlrd读写excel文件 xlwt和xlrd是两个相互配套的模块,在Python中,用于将数据写入Excel文件和读取Excel文件的数据. 从字面即可看出xlwt是对xl ...

  5. 使用Python批量筛选上千个Excel文件中的某一行数据并另存为新Excel文件(下篇)

    点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 野火烧不尽,春风吹又生. 大家好, ...

  6. Python使用openpyxl和pandas处理Excel文件实现数据脱敏案例一则

    推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),清华大学出版社,2020年6月第1次印刷 送书活动火爆进行中:董老师又双叒叕送书啦,30本 ...

  7. 使用Python解决对比出两个Excel文件中的不同项并将结果重新写入一个新的Excel文件

    使用Python解决对比出两个Excel文件中的不同项并将结果重新写入一个新的Excel文件 因为有统计成员到会情况的任务,每次汇总时都很麻烦,需要一个个对应腾讯会议导出名单的成员,然后在总表上进行标 ...

  8. python 横向合并_使用Python横向合并excel文件的实例

    起因: 有一批数据需要每个月进行分析,数据存储在excel中,行标题一致,需要横向合并进行分析. 数据示意: 具有多个 代码: # -*- coding: utf-8 -*- "" ...

  9. python处理excel教程实例-python 读写excel文件操作示例【附源码下载】

    本文实例讲述了python 读写excel文件操作.分享给大家供大家参考,具体如下: 对excel文件的操作,python有第三方的工具包支持,xlutils,在这个工具包中包含了xlrd,xlwt等 ...

最新文章

  1. .NET弹出对话框小结
  2. DBGridEh使用指南
  3. “10亿赌约”董明珠赢了!格力电器2018年总收入超2000亿
  4. android布局错,Android Studio布局错误
  5. 第十二课:OpenGL扩展
  6. Hilbert变换器
  7. TRNSYS模块中英文对照
  8. Python源码学习笔记:Python万物皆对象
  9. 购买一台服务器安装 青龙面版 撸京豆 ~超详细~
  10. U3D Shader
  11. 2020家用千兆路由器哪款好_家用千兆路由器哪款好(2020年千兆路由器排行榜)...
  12. iphone控制中心自定义没有计算机,如何在iPhone上自定义iOS 11控制中心功能
  13. JAVA音视频解决方案----视频基础知识
  14. 业务设计师(产品经理)P级晋升必备职能(P3-P7)
  15. android手机电视互动,安卓手机投屏酷开电视如何实现 多屏互动这么玩
  16. python期末大作业_上海交通大学python期末大作业题目(姚天昉)
  17. Oracle数据库版本
  18. 2022年吉林最新中级消防员模拟试题题库及答案
  19. Python搭建博客网站小结
  20. 《请别叫我奥特曼,我只是你望尘莫及的神话》

热门文章

  1. 【模电】0016 线性稳压电源的几个实用电路
  2. MySQL 之JDBC编程
  3. Fabric 节点类型&交易流程
  4. vs2019如何关闭自动更新
  5. 维度数据建模的概念和术语
  6. Python启发式算法中爬山法的讲解及解方程问题实战(超详细 附源码)
  7. oracle 数据库如何建立索引 如何用索引?
  8. SSD Performance测试简介
  9. LeetCode刷题框架总结
  10. 打印系统开发(27)——WinForm开发(49)——c# winform 打印图像,PrintDialog打印并且设置打印纸张大小