基于Python的课堂点名器V3

前言

在课堂点名器V2的基础上,我们又有了更高的要求。

需求分析

课堂点名器V3的大致需求如下:
在这里插入图片描述下面就说说自己看到这个大致需求后,脑子里的初步想法。

因为思路很难一下理清,我先阐述自己得出的结论

我们的目的:输入是学生名单的csv文件,输出的是四大名单并且要保存在四个csv文件中。
判别方法:有两次点名,课前点一次(后面叫第一次点名)和课后点名(第二次点名);四个输出的数据判定如下:

  • 迟到判定:第一次点名不在就是迟到
  • 请假判定:第一次点名输出已请假
  • 早退判定:第一次点名在,但是第二次点名不在
  • 旷课判定:第一次和第二次点名都不在

然后,第一次点名得出迟到名单和请假名单,第二次点名得出早退名单,然后旷课名单经过迟到名单和早退名单的交运算得出。

或许有人会说,这个结果和需求有些不同。确实有些不同,但是程序在不考虑换显示界面的话(GUI等界面),无法在调试窗口那里实时显示出四种名单(个人认为),肯定是两次点名结束才显示出来最后的名单,那么,我们只要确保最终的名单是符合需求的就行了,判断过程可以怎么方便怎么来。

下面我就放一些自己思考过程中的想法
在这里插入图片描述在这里插入图片描述

在这里插入图片描述当然,上面这三张已经是自己第二次思考过程了。下面再给些自己第一次思考的过程(你们可能看不懂)
在这里插入图片描述(下面这张是我一开始打算用tkinter来写GUI的点名器所想的东西)
在这里插入图片描述
虽然都是很累赘的东西,但毕竟是自己所想,也给出来看看,自己第一次自己独立搞一个大程序,想法方面还是很稚嫩,万一有个大佬看我这样,来指导我呢 ~ ~

全部代码(讲解就放注释里面了)

# 点名器V3
import csv
import random

# 规定的一些常量
student_late = []   # 存储迟到名单
students_late = []   # 迟到录入名单 这种形式[[姓名, 学号], [], [], ....]
# student_absence = []   # 存储旷课名单(不需要,因为absence这个表是通过late和early交运算得到的)
students_absence = []    # 旷课录入名单 这种形式[[姓名, 学号], [], [], ....]
student_sick = []   # 存储请假名单
students_sick = []   # 请假录入名单 这种形式[[姓名, 学号], [], [], ....]
student_early = []   # 存储早退名单
students_early = []   # 早退录入名单 这种形式[[姓名, 学号], [], [], ....]


###
# 功能:读入csv文件学生名单
# 输入:文件名(string)
# 返回值:学生全部信息(dict),学生名单(list)
###
def file_in(file_name):
    students_info = {}
    students_name = []
    # open()函数读入文件
    with open(file_name, newline='') as info:
        reader = csv.reader(info)
        for row in reader:
            students_info[row[0]] = row[1]
            students_name.append(row[0])
    return students_info, students_name


###
# 功能:产生随机学生名单
# 输入:学生名单(list)
# 返回值:打乱的学生名单(list)
###
def new_list(students_name):
    student_upset_name = random.sample(students_name, len(students_name))
    return student_upset_name


###
# 功能:完成点名器的初始化,整合了new_list()和file_in()两个函数
# 输入:学生名单(list)
# 返回值:学生信息(dict)和打乱的学生名单(list)
###
def dmq_init(file_name):
    student_info = file_in(file_name)[0]
    # print(students_wg_dict)
    student_upset_name = new_list(file_in(file_name)[1])
    # print(students_wg_list)
    return student_info, student_upset_name


###
# 功能:第一次点名,更新请假名单和迟到名单
# 输入:打乱的学生名单(list)
# 返回值:None
###
def dmq_dm(student_upset_name):
    student_dm_wrong = []
    print('课程即将开始!开始第一次点名!\n')
    for name in student_upset_name:
        temp = input(name + "到了吗?(输入到或没到,请假输入已请假)")
        if temp == "到":
            continue
        elif temp == "没到":
            student_late.append(name)
        elif temp == '已请假':
            student_sick.append(name)
        else:
            student_dm_wrong.append(name)
            print("请按要求输入!该名字被放置最后点名。")
    if student_dm_wrong:
        for name in student_dm_wrong:
            temp = input(name + "到了吗?(输入到或没到,请假输入已请假)")
            if temp == "到":
                continue
            elif temp == "没到":
                student_late.append(name)
            elif temp == '已请假':
                student_sick.append(name)
            else:
                print("仍然未按照要求输入!算入迟到名单!")
                student_late.append(name)


###
# 功能:迟到名单的写入和输出
# 输入:迟到学生名单(list)和学生全部信息(dict)以及一行的显示数量
# 返回值:None
###
def dmq_file_in_late(late_list, student_info, num):
    # 向 迟到录入名单 加入信息
    for name in late_list:
        students_late.append([name, student_info[name]])
    # 输出 迟到录入名单
    print_info('迟到', students_late, num)
    # 写入 迟到录入名单
    with open("late_students_info.csv", "w", newline="") as f_in:
        file_writer = csv.writer(f_in, quotechar='|', quoting=csv.QUOTE_MINIMAL)
        for info in students_late:
            file_writer.writerow(info)
    print("\n已导出迟到学生名单!文件位置位于当前目录下late_students_info.csv")


###
# 功能:请假名单的写入和输出
# 输入:请假学生名单(list)和学生全部信息(dict)以及一行的显示数量
# 返回值:None
###
def dmq_file_in_sick(sick_list, student_info, num):
    # dmq_file_in_sick()、dmq_file_in_early()和dmq_file_in_absence()都是一个原理,注释参照dmq_file_in_late()
    for name in sick_list:
        students_sick.append([name, student_info[name]])
    print_info('请假', students_sick, num)
    with open("sick_students_info.csv", "w", newline="") as f_in:
        file_writer = csv.writer(f_in, quotechar='|', quoting=csv.QUOTE_MINIMAL)
        for info in students_sick:
            file_writer.writerow(info)
    print("\n已导出请假学生名单!文件位置位于当前目录下sick_students_info.csv")


###
# 功能:早退名单的写入和输出
# 输入:早退学生名单(list)和学生全部信息(dict)以及一行的显示数量
# 返回值:None
###
def dmq_file_in_early(early_list, student_info, num):
    for name in early_list:
        students_early.append([name, student_info[name]])
    print_info('早退', students_early, num)
    with open("early_students_info.csv", "w", newline="") as f_in:
        file_writer = csv.writer(f_in, quotechar='|', quoting=csv.QUOTE_MINIMAL)
        for info in students_early:
            file_writer.writerow(info)
    print("\n已导出早退学生名单!文件位置位于当前目录下early_students_info.csv")


###
# 功能:旷课名单的写入和输出
# 输入:旷课学生名单(list)和学生全部信息(dict)以及一行的显示数量
# 返回值:None
###
def dmq_file_in_absence(absence_list, student_info, num):
    for name in absence_list:
        students_absence.append([name, student_info[name]])
    print_info('旷课', students_absence, num)
    with open("absence_students_info.csv", "w", newline="") as f_in:
        file_writer = csv.writer(f_in, quotechar='|', quoting=csv.QUOTE_MINIMAL)
        for info in students_absence:
            file_writer.writerow(info)
    print("\n已导出旷课学生名单!文件位置位于当前目录下absence_students_info.csv")


###
# 功能:输出 特定 列表数据
# 输入:名单名称、特定的list  [[*, *], [*, *], [*, *], ...]和每行显示数字
# 返回值:None
###
def print_info(string, special_list, num):
    count = 0
    print('--'*5 + '**' + string + '名单(' + str(num) + '个一行)' + '**' + '--'*5)
    for i in special_list:
        if (count % num == 0) & (count != 0):
            print()
        print(i[0]+","+i[1], end=' ')
        count += 1


###
# 功能:第二次点名
# 输入:打乱的学生名单(list)
# 返回值:早退的学生名单(list)
###
def dmq_dm_2(list_1):
    name_list = list(set(list_1) - set(student_sick))
    student_dm_wrong = []
    print('\n下课时间到!开始第二次点名!\n')
    for name in name_list:
        temp = input(name + "在吗?(输入在或不在)")
        if temp == "在":
            continue
        elif temp == "不在":
            student_early.append(name)
        else:
            student_dm_wrong.append(name)
            print("请按要求输入!该名字被放置最后点名。")
    if student_dm_wrong:
        for name in student_dm_wrong:
            temp = input(name + "在吗?(输入在或不在)")
            if temp == "在":
                continue
            elif temp == "不在":
                student_early.append(name)
            else:
                print("仍然未按照要求输入!算入早退名单!")
                student_early.append(name)


###
# 功能: 计算两列表的交集
# 输入: 两个列表(不分先后)
# 返回: None
###
def list_mix(list_1, list_2):
    mix = []
    for i in list_1:
        if i in list_2:
            mix.append(i)
    return mix


def main(file_name, num):
    # 读入csv文件
    temp = dmq_init(file_name)
    student_info = temp[0]
    name_list = temp[1]

    # 第一次点名
    dmq_dm(name_list)
    # 第二次点名
    dmq_dm_2(name_list)

    # 对运算结果做出调整
    # 交集运算出旷课名单
    student_absence = list_mix(student_late, student_early)
    # 迟到名单里不能有旷课和请假的人(确保一下)
    student_late_new = list(set(student_late) - set(student_absence) - set(student_sick))
    # 早退名单里不能有旷课和请假的人(确保一下)
    student_early_new = list(set(student_early) - set(student_absence) - set(student_sick))

    # 输出并导入请假名单
    dmq_file_in_sick(student_sick, student_info, num)
    # 输出并导入迟到名单
    dmq_file_in_late(student_late_new, student_info, num)
    # 输出并导入早退名单
    dmq_file_in_early(student_early_new, student_info, num)
    # 输出并导入旷课名单
    dmq_file_in_absence(student_absence, student_info, num)
    # return '程序结束'


# 5代表5个名字一行输出
main("test.csv", 5)

这里就强调一下main函数里面的两次点名和输出写入中间的部分,因为旷课名单是迟到和早退的交集,所以名单肯定会重复,那我们就运用集合的差运算来避免这个问题,然后为了确保请假学生名单不会出现在迟到和早退名单里,就顺便加上了(感觉这种情况肯定不会发生,自己也就写一下确保一下)。

运行截图

这里就给出一组测试图了,但自己也测了很多遍了。
(以下人名不要在意)
开始第一次点名,这里可以看出请假的人有李浩,迟到的人有程阳王芝伟
在这里插入图片描述
然后我们继续输入,这里可以知道,袁震王芝伟是早退了,而且第二次点名的名单里没有第一次点名名单里的请假学生李浩(原因见代码中dmq_dm_2()开头的集合差运算)在这里插入图片描述
然后我们想一下,最终的名单应该是王芝伟旷课,袁震早退,李浩请假,程阳迟到。我们接着来看看输出的是否符合我们得到的结论
在这里插入图片描述
我们再看看文件里面是否正确
在这里插入图片描述正确,程序结束。

总结

这次从看到要求到写出代码花了挺长时间的,主要总结了几点自己犯的错误:

  1. 自己变量取名字太相近了,如果看我V2的代码,会发现很多方法里面的参数名字很相像,导致我V3在改的时候,很晕,毕竟200多行代码 /= =/
  2. 自己的V2写的方法还是没有真正达到降低耦合性的效果,有一定效果,但很少,这次V3的代码,我就已经一上来就把自己最终要的参数一一罗列为全局变量,让每个函数都少一点return值,第一是为了减少参数名,不然想名字想半天,第二就是想全力达到想要的从一开始的空值,一步步方法改变,到最后变成想要的值,过程中只知道经过了哪几个方法调用,而看不到方法内部。(不知道讲清楚了没,可以看代码体会下。。)
  3. 自己代码应该再多加点注释,自己就隔了三四天吧,拿到自己写的V2的代码,想改成V3的还花了点时间放在看参数上面(可能是自己参数太乱了,就是第一点提到的问题),挺晕的。第一次看自己的代码看晕= =

最后给大家看看自己一开始搞的GUI界面,毕竟是自己写的,代码就不给出了,就看看界面效果(后期可能会出个有关tkinter的博客,因为随着点名器功能的增加,很可能需要更换显示界面)
这里给出片段代码,然后我们就开始展示界面。
在这里插入图片描述
主界面:
在这里插入图片描述
选择点名名单和上课时间之后,点击开始点名;就会弹出实时显示四个名单的文本域和处理上课时来的学生的补签事件,点击返回就可以关闭界面。
在这里插入图片描述
点击补签,弹出新窗口,输入补签学生学号然后确定就可以了;
在这里插入图片描述
补签成功就会显示一行字;
在这里插入图片描述
主界面点击叉号还可以弹出messageBox提示窗口。
在这里插入图片描述文章到这就结束了。

最后就希望大家给点建议,如果文章给你提供了帮助和感触,自己也很高兴。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值