前言

自疫情爆发以来啊,对大学牲来讲,上网课已基本成为司空见惯的事情了,在看的各位谁还没上过个网课呢。抛开事实不谈,上网课的效率还是比较高的(手动狗头)。

那有些游手好闲,啊不对,是热爱学习的小可爱(yue),自然要考虑怎么进一步提升上网课的效率。

好!说干就干,马上分析一波:

网课,顾名思义是在网上上课。上课,首先得知道该上什么课,对吧。好,掏出手机打开学校教务系统(或者手机相册),“今天是……星期三,第一节课是《母猪的产前婚检》,嗯,知道了。”

那岂不是很麻烦。请诸位想想,我上网课,还得先打开手机看课表,这不是消耗体力对手机做功吗。对于吾等热爱学习的好宝贝,自然要尽可能节省体力。没错,我甚至不愿意打开手机。

那第一个需求就有了:导入课表,根据当前时间,判断要上的课程。

解决了上什么课的问题,接下来考虑怎么上课。网课那一定要依托平台喽。钉钉、腾讯会议、腾讯课堂、学习通乃至QQ群,大家耳熟能详。我们只需要在电脑上双击运行平台,输入会议号关闭麦克风和摄像头,或者登录账号找到要上的课程,点击进入。

那么自然而然,第二个需求:根据当前要上的课程,获得这个课程在哪个平台上,然后帮我自动打开平台。

接下来课程打开,我们就可以进入(可能)愉快的听课阶段了。两个需求,现在开始实现。

实现

#导入需要的库
import time        #标准库,时间模块,用来获取系统时间
import os          #标准库,与操作系统进行交互,执行shell命令
import sys         #标准库,与Python解释器进行交互
import webbrowser  #标准库,调用系统浏览器打开网页
import winreg      #标准库,操作注册表,获取软件安装信息
#定义函数,获取当前时间,根据条件返回不同值代表第几节课
def currentTime():
    CT = time.strftime("%H:%M:%S")       #核心函数:把一个代表时间的元组或者struct_time转化为格式化的时间字符串
    if "06:00:00" < CT <= "09:50:00":    #当前时间在第一节课的时间范围内
        return 0
    elif "09:50:00" < CT <= "12:00:00":  #当前时间在第二节课的时间范围内
        return 1
    elif "12:00:00" < CT <= "16:20:00":  #当前时间在第三节课的时间范围内
        return 2
    elif "16:20:00" < CT <= "18:30:00":  #当前时间在第四节课的时间范围内
        return 3
    elif "18:20:00" < CT <= "21:20:00":  #当前时间在第五节课的时间范围内
        return 4
#定义函数,检查网络连接,返回布尔值
def CheakNetwork():
    if os.system("ping www.baidu.com") == 0:    #ping百度(百度:你礼貌吗)
        os.system("cls")                        #os.system()运行shell命令,返回0/1,0代表成功执行
        return True,
    else:
        return False
定义函数,启动腾讯会议
def RunWeMeet():
    reg = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\WeMeet",reserved=0,access=winreg.KEY_READ)
    pathWeMeet = winreg.QueryValueEx(reg,"DisplayIcon")[0]  #这个注册表键值存放了腾讯会议的启动路径
    winreg.CloseKey(reg)
    strProcess = "".join(list(os.popen("tasklist")))    #用os模块运行tasklist,获取所有进程信息
    strProcessCount = strProcess.count("wemeetapp.exe") #返回程序正在运行的进程数量
    if strProcessCount > 1:                             #腾讯会议正在运行:关闭程序并重启
        os.system("taskkill /f /t /im wemeetapp.exe")   #关闭进程
        os.system(pathWeMeet)
    else:                                               #腾讯会议未运行:正常启动
        os.system(pathWeMeet)
定义函数,启动钉钉,思路和启动腾讯会议的一样
def RunDingDing():
    reg = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\App Paths\nw.exe")
    pathWeMeet = winreg.QueryValueEx(reg,"")[0]
    winreg.CloseKey(reg)
    strProcess = "".join(list(os.popen("tasklist")))
    strProcessCount = strProcess.count("DingTalk.exe")
    if strProcessCount > 1:
        os.system("taskkill /f /t /im DingTalk.exe")
        os.system(pathWeMeet)
    else:
        os.system(pathWeMeet)
#定义函数,启动腾讯课堂,腾讯课堂网页端就可以用
def Runke_qq():
    webbrowser.open("https://ke.qq.com",new=1,autoraise=1)    #webbrowser模块,打开浏览器,进入腾讯课堂主页
#定义函数,启动学习通
def Runchaoxing():
    webbrowser.open("http://i.chaoxing.com",new=1,autoraise=1)
#定义函数,从文件获取当日课程信息。参数i(0~4)决定当前时间段应该上哪一节课(currentTime()的返回值),返回[课程名,上课平台]格式的列表
def ReadSchedule(i):
    Weekday = time.strftime("%A")           #获取系统时间,判断当日是星期几
    f = open("schedule.txt","r",encoding="utf-8")
    ReadList = f.readlines()[8:13]          #读取周一至周五的课表
    f.close()
    MondaySchedule = "".join(ReadList[0])   #周一课表
    TuesdaySchedule = "".join(ReadList[1])  #周二课表
    WednesdaySchedule = "".join(ReadList[2])#周三课表
    ThursdaySchedule = "".join(ReadList[3]) #周四课表
    FridaySchedule = "".join(ReadList[4])   #周五课表
    if Weekday == "Monday":
        Weekday = MondaySchedule
    elif Weekday == "Tuesday":
        Weekday = TuesdaySchedule
    elif Weekday == "Wednesday":
        Weekday = WednesdaySchedule
    elif Weekday == "Thursday":
        Weekday = ThursdaySchedule
    elif Weekday == "Friday":
        Weekday = FridaySchedule
    oneClassList = Weekday[4:].split(";",4)            #分离单个课程和上课的平台,存放在列表
    if oneClassList[i].find("-") != -1:
        ClassName = oneClassList[i].split("-")[0]       #课程名
        ClassSoftware = oneClassList[i].split("-")[1]   #上课平台
    else:
        ClassName = "无课"
        ClassSoftware = "None"
    return ClassName,ClassSoftware



"""
关于从文件获取课程信息:我想的是自定义一个txt文档(schedule.txt),
文档里面按照格式手动导入课表和对应的上课平台信息,
所以这个程序想运行,还得在程序所在目录下自定义一个schedule.txt文档,里面存放课程信息
这段代码的“谜之”操作,需要配合自定义的schedule.txt文件格式,文件内容如下:
"""

#自定义课表格式要求:星期N:《课程名称1》-上课平台;《课程名称2》-上课平台;……;《课程名称5》-上课平台;(N的范围:一到五)
#整个课表文档没有任何一个空格,自定义课表的时候不要!不要!不要!敲空格。你看到的觉得有空格,是因为这个课表的标点是中文输入状态下写的,全角符号占2字符
#各课程之间用分号(;)隔开(注意是中文输入下的分号,占2字符)
#上课平台目前只支持钉钉、腾讯会议、腾讯课堂和学习通。如果上课平台是腾讯会议,格式为:腾讯会议(会议号)
#同一天的课程写在同一行,按照上课时间,从早到晚依次排列,顺序不能乱
#当天最多5堂课,没有课的部分填:“无课”。5个分号,一个都不能缺。比如:《课程1》-钉钉;课程《2》-钉钉;无课;《课程4》-钉钉;无课;
#自定义下方课表时,以上内容仔细阅读!仔细阅读!仔细阅读!严格遵循课表格式,不要擅自更改及删除其他任何内容

星期一:《高分子技术》-腾讯会议(12345678910);《金属与热处理》-腾讯会议(10987654321,密码:560237);《有色金属》-腾讯会议(10203040506);无课;《炼钢》-腾讯会议(60708090100);
星期二:《生物化学》-腾讯会议(10102020303);《物理化学》-钉钉;无课;无课;无课;
星期三:《母猪的产前婚检》-钉钉;《水稻繁育学》-学习通;无课;无课;《修狗绝育研究》-腾讯会议(33445566778);
星期四:《数据结构》-腾讯会议(12312312312);《汇编语言》-钉钉;《软件工程》-腾讯会议(74185296371);《大学英语》-钉钉;无课;
星期五:《修仙概论》-腾讯会议(010203040506);《练气期修炼方法》-学习通;《筑基入门》-腾讯会议(04050607080);《元神孕育精要》-腾讯课堂;无课;
#程序入口
if __name__ == "__main__":
    startTime = time.strftime("%H:%M:%S")
    if startTime >= "06:00:00" and startTime <= "21:20:20":     #如果系统时间大于早上六点,不晚于晚上九点二十,启动程序
        if CheakNetwork() == True:
            ClassList = ReadSchedule(currentTime())             #列表返回当前时间段(currentTime()控制)要上的课程和上课平台,[课程名,上课平台]
            if ("腾讯会议" in ClassList[1]) == True:
                print("当前课程为:"+ClassList[0])
                print("启动"+ClassList[1])
                RunWeMeet()
                input()
            elif ("钉钉" in ClassList[1]) == True:
                print("当前课程为:"+ClassList[0])
                print("启动"+ClassList[1])
                RunDingDing()
                input()
            elif ("腾讯课堂" in ClassList[1]) == True:
                print("当前课程为:"+ClassList[0])
                print("启动"+ClassList[1])
                Runke_qq()
                input()
            elif ("学习通" in ClassList[1]) == True:
                print("当前课程为:"+ClassList[0])
                print("启动"+ClassList[1])
                Runchaoxing()
                input()
            elif ("None" in ClassList[1]) == True:
                  input("你当前无课\n")
        else:
            input("你没联网啊铁子\n")
            sys.exit()
    else:
        input("这个点你上什么课……\n")
        sys.exit()

后记

看起来代码似乎挺多,实际上实现的功能真的很简单很基础。一句话概括就是根据课表打开要上课的平台,真的仅此而已。其实最一开始想的是开机能自启动,后台也能一直监测,到了上课时间,就能自动启动程序,在平台内自动点击进行上课,我只需要开着电脑就够了。开机自启动和后台监测比较好实现,可是“在平台内自动点击进行上课”的实现,确实有难度。对于我自己的电脑,当然可以用最粗暴最笨的方法,比如用pyautogui模块模拟键鼠操作。但是我一直想怎么能让它足够“普适”,至少在别人的电脑上起码能跑起来。似乎没有足够优雅的解决办法?

说一些不足之处吧:“归功于”我蹩脚的英语,那些标识符的命名真是一言难尽;有些地方的设计和处理不够优雅,比如那个自定义课表。事实上ReadSchedule(i)函数的整个设计都很“笨”,不够轻盈不够优雅,可读性也很差,最重要的是,那些关键逻辑参数都是写死的,比如列表的切片位置和索引值。这样就导致一旦那个自定义课表的格式或出现问题,程序立马就会崩掉;异常处理压根没做,因为嫌麻烦(还是因为懒)。代码中对于注册表的操作也是直接写死,一旦读取不到正确内容,也是立马就崩。事实上应当有必要去做,并把异常处理作为一种习惯才好;封装方面也做的不是很“尽人意”,那几个启动平台的函数,其实我觉得完全可以定义在同一个函数体。

整体代码的维护性我觉得还可以(谁给你的自信),在代码复用方面做的不好。不过这么短这么简单的代码,也谈不上维护和复用了。

很感谢你能看到这里。(鞠躬!)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐