【Python库和代码案例:第二课】一边写“鼓励师”给自己打气,一边写“学生管理”鞭策别人:Python拿捏了

【Python库和代码案例:第二课】一边写“鼓励师”给自己打气,一边写“学生管理”鞭策别人:Python拿捏了

在这里插入图片描述


🎬 个人主页艾莉丝努力练剑
专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录
Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:

在这里插入图片描述

文章目录


在这里插入图片描述

3 ~> 第三方库

3.5 代码示例:“程序猿鼓励师”

有些公司会设有程序猿鼓励师这样一个岗位,程序猿敲代码很辛苦,需要鼓励,一般程序猿鼓励师是一些好看的妹子,在程序猿燃尽了的时候可以鼓励程序员继续敲代码。

但是,很多公司没有这样一个岗位怎么办?程序猿自己来实现一下这个功能,自己鼓励一下自己。

监听键盘按键,每按键20下,就自动播放一个音频,鼓励一下辛苦搬砖的自己。

在这里插入图片描述

3.5.1 安装第三方依赖

  • pynput用于监听键盘按键,注意版本不要用最新。
  • playsound用于播放音频。
pip install pynput==1.6.8 pip install playsound==1.2.2

3.5.2 准备音频文件

此处准备了一个ding.mp3放到和py代码同级目录中。

3.5.3 编写代码

  • 使用from import的格式直接导入模块中的指定对象/函数。
  • 使用keyboard.Listener监听键盘按键,其中on_release会在释放按键时被调用。
  • 使用listener.start启动监听器.为了防止程序直接退出,使用listener.join让程序等待用户按键。
  • 使用count计数,每隔10次,调用playsound播放音频文件。
from pynput import keyboard from playsound import playsound count =0defon_release(key):print(key)global count count +=1if count %10==0: playsound('ding.mp3') listener = keyboard.Listener( on_release=on_release) listener.start() listener.join()

运行一下程序,即可感受到效果。

3.5.4 改进代码

上述代码在执行过程中,会感觉到播放音频会导致按键卡顿,可以使用多线程解决这个问题,关于多线程的知识,在此处不详细介绍。

  • 使用threading.Thread引入多线程类。
  • 使用Thread的构造函数来构造一个线程,target表示线程要执行的任务,args表示target中要调用函数的参数。
  • 使用Thread.start()启动线程。
from pynput import keyboard from playsound import playsound from threading import Thread count =0defon_release(key):print(key)global count count +=1if count %10==0: t = Thread(target=playsound, args=('ding.mp3',)) t.start()#playsound('ding.mp3') listener = keyboard.Listener(on_release=on_release) listener.start() listener.join()

3.5.5 操作流程

先搞几个音频文件到专门的目录底下——

在这里插入图片描述
在这里插入图片描述

像音频这些就被称为 资源文件

在这里插入图片描述

开个玩笑哈。

我们用前面介绍的两个命令,先在pip把两个可执行文件下载一下——

在这里插入图片描述
在这里插入图片描述

写了代码之后,我们测试一下代码实现的键盘按键动作捕获功能能不能成功——

在这里插入图片描述
可以捕获到用户的键盘按键动作。

运行——

在这里插入图片描述

3.5.6 最佳实践

3.5.6.1 播放一个音频
# 程序员鼓励师# 播放一个音频from pynput import keyboard # 引入播放音频的模块from playsound import playsound # 创建一个计数器,记录当前用户按了多少次键盘 count =0defonRelease(key):""" 这个函数,就是在用户释放键盘按键的时候,就会被调用到 这个函数不是咱们自己调用的,而是咱们把这个函数交给了 Listener 自己, 由这个 Listener 在用户释放按键的时候自动调用 像这样的不是我们自己主动调用,而是交给别人,在合适的时机进行调用,这样的函数,叫做“回调函数(callback function)” :param key:用户按下了哪个键 :return: """print(key)global count count +=1if count %10==0:# 只有按的次数是10的倍数的时候才会播放音频# 播放一个音频!# playsound('python_code/sound/1.mp3') # 传入的参数就是要播放的文件名 playsound('D:/Python_code/python_code/sound/1.mp3')# 替换为实际完整路径# 当我们创建好 listener 之后,用户的键盘按键动作就会被捕获到# 我们还希望捕获到之后能够执行一段代码 listener = keyboard.Listener(on_release=onRelease)# 这个操作不是在进行调用,而是把函数名当成了一个变量传到了 Listener 里面,具体什么时候调用,由 Listener 自己决定# 所谓的“自己决定”就是会说它会检测键盘什么时候释放,释放,就执行,不释放就不执行 listener.start() listener.join()
3.5.6.2 多个音频循环播放
# 程序员鼓励师# 多个音频循环播放import random from threading import Thread from pynput import keyboard # 引入播放音频的模块from playsound import playsound soundList =['D:/Python_code/python_code/sound/1.mp3','D:/Python_code/python_code/sound/2.mp3','D:/Python_code/python_code/sound/3.mp3']# 创建一个计数器,记录当前用户按了多少次键盘 count =0defonRelease(key):""" 这个函数,就是在用户释放键盘按键的时候,就会被调用到 这个函数不是咱们自己调用的,而是咱们把这个函数交给了 Listener 自己, 由这个 Listener 在用户释放按键的时候自动调用 像这样的不是我们自己主动调用,而是交给别人,在合适的时机进行调用,这样的函数,叫做“回调函数(callback function)” :param key:用户按下了哪个键 :return: """print(key)global count count +=1if count %10==0:# 只有按的次数是10的倍数的时候才会播放音频# 如果感觉播放得太频繁了,吵到耳朵了,也可以适当降低一下频率,把除余的数字改大一点# 播放音频!# 先生成随机数 i = random.randint(0,len(soundList)-1)# 此处的播放音频,消耗时间比较多,可能会引起输入的卡顿(不流畅)# 可以创建一个线程,在线程里面播放音频!# playsound(soundList[i]) # 传入的参数就是要播放的文件名 t = Thread(target=playsound,args=(soundList[i],))# 在一个新的线程里面完成播放音频# (新的线程可以想象成一个新的执行流)# 上面这里只是给线程安排任务,下面才是创建了一个线程出来 t.start()# 当我们创建好 listener 之后,用户的键盘按键动作就会被捕获到# 我们还希望捕获到之后能够执行一段代码 listener = keyboard.Listener(on_release=onRelease)# 这个操作不是在进行调用,而是把函数名当成了一个变量传到了 Listener 里面,具体什么时候调用,由 Listener 自己决定# 所谓的“自己决定”就是会说它会检测键盘什么时候释放,释放,就执行,不释放就不执行 listener.start() listener.join()# 编写一段代码,感受一下这个程序的效果# 播放音频可能出现卡顿# 再次感受下代码的效果,此时感觉就流畅了!# 现在是把频率降低到 xx 下播放一次,感觉好不少啦!

4 ~> 综合案例:学生管理系统

4.1 需求说明

实现一个命令行版本的学生管理系统。

4.1.1 功能

在这里插入图片描述

4.2 创建入口函数

  • 使用一个全局列表 students 表示所有学生信息。
  • 使用 menu 函数和用户交互. 这是一个自定义函数。
  • 使用 insertshowfinddelete 这几个自定义函数完成增删查操作。
  • 使用 sys.exit 实现程序退出。
# 使用列表表示所有的学生 students =[]defmain():""" 程序的入口函数 """print('+--------------------------+')print('| 欢迎来带学生管理系统! |')print('+--------------------------+')whileTrue: choice = menu()if choice ==0: sys.exit()if choice ==1: insert()elif choice ==2: show()elif choice ==3: find()elif choice ==4: delete()else:print('您的输入有误!请重新输入!') main()

4.3 实现菜单函数

defmenu():print("1. 新增学生信息")print("2. 显示所有同学信息")print("3. 根据名字查找学生信息")print("4. 删除学生信息")print("0. 退出程序") choice =input("请输入您的选择:")returnint(choice)

4.4 实实现增删查操作

4.4.1 新增学生

```python definsert():print("[新增学生] 开始!"); studentId =input("请输入学生的学号: ") name =input("请输入学生的姓名: ") gender =input("请输入学生的性别: ")if gender notin('男','女');print("性别不符合要求!新增学生失败!");return className =input("请输入学生的班级: ")# 使用一个字典表示学生信息 student ={'studentId': studentId,'name': name,'gender': gender,'className': className }# 把字典添加到学生列表中global students students.append(student)print("[新增学生] 完毕!");

4.4.2 显示学生

defshow():print("[显示学生] 开始!");for s in students:print(f"[{s['studentId']}]\t{s['name']}\t{s['gender']}\t{s['className']}")print(f"[显示学生] 完毕! 共显示了 {len(students)} 条记录!")

4.4.3 查找学生

deffind():print("[查找学生] 开始!"); name =input("请输入要查找的同学姓名:") count =0for s in students:if name == s['name'];print(f"[{s['studentId']}] \t{s['name']} \t{s['gender']} \t{s['className']}") count +=1print(f"[查找学生] 完毕!共查找到 {count} 条记录!")

4.4.4 删除学生

defdelete():print("[删除学生] 开始!"); studentId =input("请输入要删除的同学学号: "); count =0for s in students:if studentId == s['studentId'];print(f"删除 {s['name']} 同学的信息!"); students.remove(s) count +=1print(f"[删除学生] 完毕!共删除 {count} 条记录!");

4.5 加入存档读档

4.5.1 约定存档格式

约定存档文件放到d:/record.txt文件中。

并且以行文本的方式来保存学生信息,格式如下:

学号\t名字\t性别\t班级
学号\t名字\t性别\t班级
学号\t名字\t性别\t班级
  • 每个同学占一行。
  • 每个同学的信息之间使用\t制表符进行分隔。

4.5.2 实现存档函数

defsave():""" 存档函数 """withopen('d:/record.txt','w')as f:for s in students: f.write(f"{s['studentId']} \t{s['name']} \t{s['gender']} \t{s['className']} \n")print(f"存档成功!共存储了 {len(students)} 条记录!")

insertdelete末尾,调用save函数进行存档。

# 执行存档 save()

4.5.3 实现读档函数

defload():""" 读档函数 """# 如果存档文件不存在,则跳过读档环节ifnot os.path.exists('d:/record.txt');return# 先清空全局变量里的数据global students students =[]withopen('d:/record.txt','r')as f:for line in f:# 去除末尾的换行符 line = line.strip() tokens = line.split('\t')iflen(tokens)<4:print(f"文件格式有误!line={line}")continue student ={'studentId': tokens[0],'name': tokens[1],'gender': tokens[2],'className': tokens[3]} students.append(student)print(f"[读档成功] 共读取了 {len(students)} 条记录!")

main函数开头的地方,调用load加载存档:

load()

4.6 打包成 exe 程序发布

当前虽然已经实现了一个管理系统,但是.py的文件只能在安装了Python环境的机器上运行。

为了能够更好的部署到其他主机上,可以借助pyinstaller来把Python程序打包成exe程序。

4.6.1 安装 pyinstaller

pip install pyinstaller 

4.6.2 打包程序

  • -F表示打包成单个exe(不带动态库):
pyinstall -F 学生管理系统.py 

注意:如果提示找不到pyinstaller命令,则需要重启一下PyCharm。

稍等片刻,很快打包完成。

在这里插入图片描述

图标效果如下所示——

在这里插入图片描述

此时就可以把这个程序拷贝给其他机器使用了!无需Python环境即可运行!

4.7 最佳实践

在这里插入图片描述

使用这样的格式进行区分——

在这里插入图片描述
在这里插入图片描述

4.7.1 实现增删查功能

# 实现一个命令行版本的学生管理系统import sys # 使用这个全局变量,来管理所有的学生信息# 这个列表的每个元素都是一个“字典”,每个字典就分别表示了一个同学! students =[]# 数据保存在这样一个变量里面,变量容易丢失数据,为了持续保存,需要存在一个文件里面defmenu():print('1. 新增学生')print('2. 显示学生')print('3. 查找学生')print('4. 删除学生')print('0. 退出程序') choice =input('请输入您的选择: ')# return int(choice) # 转成选项# 或者直接以字符串的形式return choice # 实现增删查功能definsert():print('【新增学生】开始!') studentID =input('请输入学生的学号:') name =input('请输入学生的姓名:') gender =input('请输入学生的性别:')if gender notin('男,女'):print('性别输入的内容不符合要求,新增失败!')return className =input('请输入学生的班级:')# 使用一个字典把上述的信息给聚合起来 student ={'studentId':studentID,'name':name,'gender':gender,'className':className }global students students.append(student)# 通过 append 新增学生print('【新增学生】完毕!')defshow():# 遍历全局变量的这个列表,把每个学生的信息打印出来print('【显示学生】开始!')for s in students:print(f"[{s['studentId']}]\t{s['name']}\t{s['gender']}\t{s['className']}")# 通过制表符分隔开print(f'【显示学生】完毕!共显示了{len(students)}条数据!')deffind():# 改进学生姓名,来进行查找print('【查找学生】开始!') name =input('请输入要查找的同学姓名: ') count =0for s in students:# students(全局变量),读取全局变量的时候不需要加 global 去修饰,修改时才需要加if name == s['name']:print(f"[{s['studentId']}]\t{s['name']}\t{s['gender']}\t{s['className']}") count +=1print(f'【查找学生】结束!共找到了{count}个匹配的同学!')defdelete():print('【删除学生】开始!') studentId =input('请输入要删除的学生学号:')# 看看这个学号对应的同学是哪个字典,然后把这个字典从列表里面删掉就好了for s in students:if studentId == s['studentId']:print(f"删除{s['name']}同学的信息!") students.remove(s)print('【删除学生】完毕!')defmain():""" 入口函数 """# 通过控制台和用户进行交互print('-----------------------------------------------')print(' 欢迎来到学生管理系统 ')print('-----------------------------------------------')whileTrue:# 通过 menu 函数来打印出菜单项 choice = menu()if choice =='1':# 新增学生 insert()elif choice =='2':# 显示所有学生 show()elif choice =='3':# 查找学生 find()elif choice =='4':# 删除学生 delete()elif choice =='0':# 退出程序print('goodbye!') sys.exit(0)else:print('您的输入有误!请重新输入!')# 需要进入下次循环,让用户重新输入# continue# 存储在内存里面的数据是容易丢失的! main()

4.7.2 添加存档(save)和读档(load),将信息保存到硬盘上

在这里插入图片描述
# 实现一个命令行版本的学生管理系统import os.path import sys # 使用这个全局变量,来管理所有的学生信息# 这个列表的每个元素都是一个“字典”,每个字典就分别表示了一个同学! students =[]# 硬盘可以持久化存储数据!defsave():# 保存操作""" 用于存档 """# 使用上下文管理器# 此处的路径不是以d: 开头的“绝对路径”,而是相对路径# 此时这个写法的含义就是让 record.txt 和 当前的 code77.py 在同一个目录里withopen('record.txt','w',encoding='utf8')as f:# 直接写了文件名,没有写前面的路径(绝对路径)for s in students: f.write(f"{s['studentId']}\t{s['name']}\t{s['gender']}\t{s['className']}\n")print(f'【存档成功】共存储了{len(students)}条记录!')defload():# 读档操作""" 用于读档 """# 如果读档文件不存在,则直接跳过读档流程# 判断文件是否存在# 为了避免读方式打开文件的时候,文件不存在的情况ifnot os.path.exists('record.txt'):# path 这个模块可以帮我们进行一些路径上的判定操作return# 读档的时候要保证把旧的数据给清理干净!global students students =[]# 把列表置为空withopen('record.txt','r',encoding='utf8')as f:for line in f:# 按行读取文件# 针对这一行数据,按照 \t 进行切分操作!# 切分之前要去除末尾的换行,怎么去除? line = line.strip()# strip这是一个非常有用的方法,它的功能是:去掉一个字符串开头和末尾的空白符# 空白符:空格、换行、回车、制表符、翻页符、垂直制表符...... tokens = line.split('\t')iflen(tokens)!=4:print(f'当前行格式存在问题!line={line}')continue student ={'studentId':tokens[0],'name':tokens[1],'gender':tokens[2],'className':tokens[3]} students.append(student)print(f'【读档成功】共读取了{len(students)}条记录!')defmenu():print('1. 新增学生')print('2. 显示学生')print('3. 查找学生')print('4. 删除学生')print('0. 退出程序') choice =input('请输入您的选择: ')# return int(choice) # 转成选项# 或者直接以字符串的形式return choice # 实现增删查功能definsert():print('【新增学生】开始!') studentID =input('请输入学生的学号:') name =input('请输入学生的姓名:') gender =input('请输入学生的性别:')if gender notin('男,女'):print('性别输入的内容不符合要求,新增失败!')return className =input('请输入学生的班级:')# 使用一个字典把上述的信息给聚合起来 student ={'studentId':studentID,'name':name,'gender':gender,'className':className }global students students.append(student)# 通过 append 新增学生# 增加保存操作 save()print('【新增学生】完毕!')defshow():# 遍历全局变量的这个列表,把每个学生的信息打印出来print('【显示学生】开始!')for s in students:print(f"[{s['studentId']}]\t{s['name']}\t{s['gender']}\t{s['className']}")# 通过制表符分隔开print(f'【显示学生】完毕!共显示了{len(students)}条数据!')deffind():# 改进学生姓名,来进行查找print('【查找学生】开始!') name =input('请输入要查找的同学姓名: ') count =0for s in students:# students(全局变量),读取全局变量的时候不需要加 global 去修饰,修改时才需要加if name == s['name']:print(f"[{s['studentId']}]\t{s['name']}\t{s['gender']}\t{s['className']}") count +=1print(f'【查找学生】结束!共找到了{count}个匹配的同学!')defdelete():print('【删除学生】开始!') studentId =input('请输入要删除的学生学号:')# 看看这个学号对应的同学是哪个字典,然后把这个字典从列表里面删掉就好了for s in students:if studentId == s['studentId']:print(f"删除{s['name']}同学的信息!") students.remove(s)# 涉及修改,增加保存操作 save()print('【删除学生】完毕!')defmain():""" 入口函数 """# 通过控制台和用户进行交互print('-----------------------------------------------')print(' 欢迎来到学生管理系统 ')print('-----------------------------------------------')# 需要在程序启动的时候调用 load 即可(最开始加载一次,就不用反复加载了) load()whileTrue:# 通过 menu 函数来打印出菜单项 choice = menu()if choice =='1':# 新增学生 insert()elif choice =='2':# 显示所有学生 show()elif choice =='3':# 查找学生 find()elif choice =='4':# 删除学生 delete()elif choice =='0':# 退出程序print('goodbye!') sys.exit(0)else:print('您的输入有误!请重新输入!')# 需要进入下次循环,让用户重新输入# continue# 存储在内存里面的数据是容易丢失的! main()
在这里插入图片描述

运行一下,结果如下所示——

在这里插入图片描述

5 ~> 后续扩展

5.1 python cookbook

python经典进阶书籍,针对各种典型场景提供了一些解决方案。

在这里插入图片描述

这本书就像是一本菜谱,会给你罗列各种各样的场景下使用Python该如何解决。有助于打开解决问题的思路。

5.2 awesome-python

有大佬整理了Python的一些非常实用的程序库,这里挂了大佬的码云链接:awesome-python

5.3 500 Lines or Less

Python的代码示例集合。比艾莉丝前面举的例子要丰富得多。

使用简短的Python代码来实现一些有意思的程序,下面是其Github的链接:500 Lines or Less


结尾

uu们,本文的内容到这里就全部结束了,艾莉丝再次感谢您的阅读!

结语:希望对学习Python相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!

往期回顾:

【Python库和代码案例:第一课】Python 标准库与第三方库实战指南:从日期处理到 Excel 操作

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡૮₍ ˶ ˊ ᴥ ˋ˶₎ა

Read more

【计算机毕业设计案例】基于Python的电商用户行为分析系统(程序+文档+讲解+定制)

【计算机毕业设计案例】基于Python的电商用户行为分析系统(程序+文档+讲解+定制)

java毕业设计-基于springboot的(源码+LW+部署文档+全bao+远程调试+代码讲解等) 博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围::小程序、SpringBoot、SSM、JSP、Vue、PHP、Java、python、爬虫、数据可视化、大数据、物联网、机器学习等设计与开发。 主要内容:免费开题报告、任务书、全bao定制+中期检查PPT、代码编写、🚢文编写和辅导、🚢文降重、长期答辩答疑辅导、一对一专业代码讲解辅导答辩、模拟答辩演练、和理解代码逻辑思路。 特色服务内容:答辩必过班 (全程一对一技术交流,帮助大家顺利完成答辩,

By Ne0inhk
2025 腾讯广告算法大赛 Baseline 项目解析

2025 腾讯广告算法大赛 Baseline 项目解析

项目概述 2025 腾讯广告算法大赛 Baseline,一个简单的序列推荐系统,主要用于建模用户和物品的交互序列,并利用多模态特征(文本、图像等 embedding)来提升推荐效果。 核心文件功能 1. main.py - 主训练脚本 * 负责模型训练的整体流程 * 包含参数解析、数据加载、模型初始化、训练循环等 * 支持断点续训和仅推理模式 * 使用 TensorBoard 记录训练日志 main.py 代码 import argparse import json import os import time from pathlib import Path import numpy as np import torch from torch.utils.

By Ne0inhk

爬虫工程师必备:用Selenium+Python自动获取登录态Cookie的3种实战方案

爬虫工程师的“钥匙串”:三种高可用Selenium Cookie获取方案深度实战 做爬虫,尤其是需要处理用户登录态的爬虫,最让人头疼的往往不是解析页面,而是如何稳定、优雅地拿到那把“钥匙”——身份认证凭证。无论是传统的Cookie,还是现代应用偏爱的Token、Session,获取它们的过程,常常是项目从“玩具级”迈向“生产级”的第一道坎。很多开发者止步于简单的driver.get_cookies(),却在面对复杂登录流程、动态令牌或反爬策略时束手无策。今天,我们不谈那些手动复制粘贴的“玩具”方法,而是聚焦于如何用Selenium构建一套健壮的、可自动化的身份凭证获取体系。这不仅仅是调用一个API,更是一场关于浏览器自动化、网络协议理解与工程化思维的实战。 1. 基础与进阶:超越 get_cookies() 的API获取方案 绝大多数Selenium教程都会告诉你,获取Cookie只需一行代码:cookies = driver.get_cookies()。这没错,但如果你只停留在这一步,可能会错过一半的风景,并踩进无数的坑。

By Ne0inhk

EasyOCR用法全攻略:Python开源OCR工具快速上手,图文识别零门槛

在日常开发与办公场景中,图文识别(OCR)需求无处不在——比如提取图片中的文字、识别身份证/发票信息、批量处理扫描件等。传统OCR工具要么收费高昂,要么配置复杂,而 EasyOCR 作为Python开源OCR库,凭借“安装简单、支持多语言、识别精度高”的优势,成为入门级OCR开发的首选工具。 本文将从核心特性、环境搭建、基础用法到实战场景,全方位解析EasyOCR的使用技巧,帮你快速实现图文识别功能,无需深厚的计算机视觉知识。 一、为什么选择EasyOCR? 在众多OCR工具中,EasyOCR的核心优势的在于“轻量化+高性价比”,具体体现在: 1. 零门槛上手:API设计简洁,一行代码即可实现文字识别,无需复杂配置; 2. 多语言支持:默认支持80+种语言(中文、英文、日文、韩文等),可通过参数灵活切换; 3. 识别精度高:基于深度学习模型(CNN+

By Ne0inhk