前言
国庆节结束了,在重庆待了三天,然后就回峨眉,然后就一直在家里,顺便写了个程序。
之前我参与了团委学生会的办公室部门。由于刚开始,我们需要统计数据同时制作表格等文件。比如之前打算要做一个无课表,无课表内登记了每一位学生会成员的空闲时间(也就是不上课的时间段),用于学生会任务分发。
这个听起来挺简单,操作的确也没有什么技术含量,就是有点费时间。因此我们安排了4个人来做这件事情。
在10月5日的早上,可能是刚睡醒比较清醒,我突然想到能否用程序来完成这个过程,至于要快速完成开发,那就选Python。
好在Python作为一门相对简单的语言,内置了大量的库,提供了丰富的功能。基本上就是读读开发文档,再加上查资料,就能开发出对应的程序,可以称为“拿来就用”。
中学阶段,我用这个语言给PDF批量增加了水印(https://blue16.cn/index.php/2023/08/22/213/),也算是用过这个语言。当然,那个比较简单,没有涉及到什么算法。这次写的程序,我从思路上都改了几次。从查资料到调试完成,应该用了5个小时(10:30-15:30),虽然时间用的久,但效果还是不错,具体怎么样,就等我们收集到正式数据后再进行。
效果预览
这个直观一点,直接上图:


思路
你不知道我解决这个问题后有多兴奋。我之前想了比较多的方法,也否定了许多方法,留下来的最后一个,可以说接近完美,bug基本上不会出现。
说到思路,其实我改了几个版本,最后选择了一个最优的解法。
最早我想的是直接使用现成的课程表数据(也就是表格式),但是表的解析非常复杂(将PDF转成csv的时候行与列对不上),而且容易出错。
后来想的是只提取文字,然后分析文字内容。可是文字太乱,而且课程详细信息只带节次,不带星期,在内容错位的情况下,分析也有困难。

最后我在教务系统发现有列表式的课程表,我试探性的下载下来,转成CSV之后,格式基本正常。但是如果想提取出对应课程,还是有些难,比如部分课程没有对齐,软件将这些数据直接放在了第一列。
后来我还想抓包,看能否只通过学号获取到课程表数据包,直接解析(还可以直接对接教务系统,有变化自动输出新的内容)。但可能会有验证,不可能说直接一个学号就弄完了?
后来突然想了一下,我们并不需要知道是什么课,只需要知道这段时间你在上课就行了。因此少部分数据出错不重要,其实我们要的就只是两行数据,不,甚至是一行数据,也就是“节次”。
这也就是最终的解决方案。其实我只提取了第二列,也就是课程的“节次”,由于节次自带顺序,因此其实不需要分析对应的是星期几,突变(从11-14直接变为1-3这种)直接就可以视为下一天。也就是说,如果出现了下一个1-2节(其他亦然),那就直接跳为下一个星期。


看了看课表,现在就确定思路了:
首先将pdf转为csv,然后提取出对应的两列保存为一个新的csv,根据星期+课时直接填入一个预定的模板(xlsx)中:
填入规则:办公室 张三,学科部 李四,全角逗号分隔
如果存在课表变动,重新生成一遍就行了,反正都是全自动,可想而知,能省下多少时间。
格式说明
由于表格模式导出的PDF课表结构复杂,好看但是不好写代码解析。因此这次需要使用列表模式导出的PDF。先进入教务系统(jw.swu.edu.cn),和之前下载课表一样,进入到课表页面,也就是下面这个,然后点击“输出PDF”按钮右侧的“列表”:

待课表切换成列表模式后,再点击“输出PDF”下载课表文件:

确认课表文件为下面的样式:

这就是最终的文件了,各个部门把这个文件直接发给你们对应负责人即可。负责人汇总检查无误后再上传到各部门入驻干事。
使用方法
代码Github开源地址:Blue16-WangFudi/freetimetable-generate: 一个由人工智能学院团委办公室部门开发的通过已有课表自动生成无课表的小工具 (github.com)
下面说一下代码如何运行:
打开CMD,确保系统中已经安装Python(我这里环境为Python3.11),然后安装需要的Python库
pip install pdfminer3k
pip install tabula-py
pip install openpyxl
pip install pdfminer==20191125
安装的同时,可以先将搜集到的课表放入InputTable文件夹,按照文件夹分部门放入:

单个课程表文件保持原文件名,不要改变文件名,文件名用于标记是谁:

通过cd命令等方式进入程序所在目录,然后执行py main_all.py:

回车确认,待程序解析完成后,输入保存的文件名,如果只输入文件名(不带路径),程序会将文件保存在程序执行路径中。如果输入的是带路径的文件名,程序会保存到相应位置。
完成,打开即可查看:

贴一个调试过程:


总结
节省了大家宝贵的时间,而且如果教务系统不升级,程序原则上是无需修改,可以重复利用。我的收获也挺多,比如加深了对Python的理解,学会了什么是浅拷贝,知道了Python中range是左闭右开的,比如如何高效的偷懒与躺平,让电脑帮我做事情(狗头)



