- 0、来由
- 1、设计、实现思路
- 1-1 课表数据文档设计
- 1-2 解析获取周课表
- 1-3 获取当前周数
- 1-4 绘制周课表蒙版、合并背景壁纸
- 1-5 调用接口更换壁纸
- 1-6 设置定时任务
- 2、总结
- 2-1 用到的关键技术
- 2-2 不规范、不足之处、改进方向
0、来由
- 去官网查课表太慢太麻烦
- 在手机上留截图看屏幕小(主要那段时间看电脑多)
- 电脑上存截图也得找
- 那时候还没发现小爱自带的课表(也可能自动导入功能还没有)
于是,就有了这个想法,之前也实现过(P好每周的课表蒙版图,存起来,然后写个脚本把课表蒙版跟壁纸合并,然后调用接口更换壁纸)文章考古-点这里。但是P图毕竟费时间,想要修改也比较费劲,也就自己折腾自己。
后来就有了新想法:
- 根据课表数据,
- 自动绘制课表蒙版,
- 自动贴合背景,
- 自动换壁纸。
将学期课表按一定规则,存储为文本文件,然后程序读取文件,根据当前时间与设定好的学期开始时间计算出当前周数,并设置学期总周数,超过则不显示课表。
当时编程还不是很规范,许多配置参数都只写死到代码中,要修改都只能到代码中找,很不方便。比如:
- 学期开始时间
- 总周数
- 壁纸文件夹路路径
- 课表文件路径
- 课表位置偏移量
- 。。。
其实,可将这些参数,同课表数据一样,抽离出来作为配置项,通过配置文件获取,从而就大大方便了定制化。
学期课表中,需要存储一些必要的信息项:
- 课程名称。为了方便显示,尽量简写
- 课程教室。
- 课程时间。也可以记录为:当天的第几节课
- 课程跨度。课程的开课周数,如[1, 3-6, 10] 表示1周,3-6周,10周有课。
根据上述这些信息,就可以完整提取出每一周的课表。根据一些实际情况,做出一些调整:将教室、课程简写合并为课程名称;于是,设置一个wks的列表表示周数,如wks[1:5]+wks[8:9] 表示: 1-4周+第8周。
鉴于Python有个强悍的函数eval(),那就直接把学期课表按照Python列表的格式设计,读取的时候直接对接就行;学期课表设计为一个含有五个元素的文档,每个元素为存储周一到周五中一天的课程信息;每个元素由六个列表单元构成,表示一天中的六节课(上午、下午、晚上各两节);而每个最小单元,也就是每节课,是一个二元列表(或是元组),第一个元素是设计后的 课表名称 如:B211大物,第二个元素为课程跨度,如:wks[1:5]+wks[8:9] 。
# 学期课表示例
[ # 周一课程
[('105射频', wks[1:6]+wks[7:12])],
[('419微测', wks[4:6]+wks[7:13])],
[],
[('407微波', wks[3:6]+wks[7:19])],
[('317信完', wks[1:6]+wks[7:14])],
[]
];
[ # 周二课程
[('305微原', wks[1:6]+wks[7:11]+wks[12:15])],
[('114数电', wks[1:4])],
[],
[('418随机', wks[1:6]+wks[7:11]+wks[12:13])],
[('114智能', wks[1:6]+wks[7:11]+wks[12:15])],
[]
];
[ # 周三课程
[('105射频', wks[1:6]+wks[7:12])],
[('211专业', wks[8:10])],
[],
[('211形政', wks[15:17])],
[],
[]
];
[ # 周四课程
[('305微原', wks[1:5]+wks[7:15]+wks[12:15])],
[('219编程', wks[1:6]+wks[7:10]), ('105工概', wks[10:18])],
[],
[('418随机', wks[1:5]+wks[7:13])],
[],
[]
];
[ # 周五课程
[('407微波', wks[3:6]+wks[7:17])],
[],
[],
[('518学导', wks[7:8]+wks[15:16])],
[('onl学导', wks[1:2]+wks[11:12])],
[],
];
1-2 解析获取周课表
根据学期课表的设计,便可以逆向解析到周课表。大致思路为:获取到学期课表列表后,循环遍历五天的课表信息,再遍历每天的课程信息,如果当前周数存在于当前课程跨度中,那么向周课表列表中加入该课程,否则置入空字符串表示没课。最终得到周课表。
- 重要信息:
- 当前周数
- 学期课表
# 获取此周课表
def getnow_cs(now_wk, cs_path):
'''
# now_wk: 当前周数
# cs_path: 课表文件地址
'''
# 临时周课表路径
path = op.join(op.split(cs_path)[0], 'tem_cls')
# 如果已经生成过本周课表txt 那么读取后直接返回,否则执行后续
if op.exists(c_path := op.join(path, f'{now_wk}周课表.txt')):
f = open(c_path, 'r', encoding='utf8')
if len(f.read()) > 20:
with open(c_path, 'r', encoding='utf8') as f:
now_cs = list(map(eval, f.read().split('n')[:-1]))
f.close()
return now_cs
clss = [op.join(path, name) for name in os.listdir(path)]
# 删除过时的周课表
for k in clss:
os.remove(k)
now_cs = [[] for i in range(5)]
f = open(op.join(path, f'{now_wk}周课表.txt'), 'a', encoding='utf8')
for wk in range(5):
# cls 代表单天的课程列表
for cls in getall_cs(cs_path)[wk]:
flag = 1
# cl 代表每一节课
for cl in cls:
# 如果当前周在当前循环课程的 周跨度中
# 将该课程添加到改周课表对应位置
if now_wk in cl[1]:
now_cs[wk].append(cl[0])
flag = 0
# flag = 1 表示当节课没有课程安排
# 那么该位置添入 空字符串 占位
if flag:
now_cs[wk].append('')
f.write(str(now_cs[wk]) + 'n')
f.close()
return now_cs
# 获取学期课表 传入学期课表路径
def getall_cs(cs_path):
# 周数列表,最多应该不会超过 23 周
wks = [i for i in range(23)]
with open(cs_path, 'r', encoding='utf8') as f:
# eval 将每天课表的字符串数据转换为 列表;
# split 规则参照 1-1 的课表文档
lh = list(map(eval, f.read().split(';n')[:-1]))
f.close()
return lh
1-3 获取当前周数
1-4 绘制周课表蒙版、合并背景壁纸先睡了,下次更新…
1-5 调用接口更换壁纸先睡了,下次更新…
1-6 设置定时任务先睡了,下次更新…
先睡了,下次更新…
2、总结 2-1 用到的关键技术
- Python eval() :从文件获取周课表数据列表
- Python time 库:时间处理
- Python os 库:路径、文件处理
- Python Pillow 库:图像处理
- Python Windows接口 更换桌面壁纸
- 大部分参数与代码耦合度太高,调参是个大问题
- 配置文件功能简单,可以发挥更多作用:将更多参数配置迁移到配置文件中,代码打包后便可以只修改配置文件而定制程序。
- 配置文件按可以考虑采用JSON YAML等
- 可以编写图形化界面导入学期课表 或者 使用爬虫到网站直接爬取学期课表。



