随机点名小程序 tkinter_python和tk随机不重复点名-程序员宅基地

技术标签: 一些小作品  

随机点名小程序

源码见github:
https://github.com/linli1724647576/Random_roll_call

问题描述

随机点名程序(越不来上课的人,被点中的概率越高,实现抽查问题、预警等功能)

问题分析

采用python 的 tkinter 库实现用户图形界面,采用 pickle 存储数据,可以对点名对象进行插入或删除。user_info.pickle文件中存储着一个字典,包括名字和缺勤次数,根据迟到的次数往列表中增加名字的个数,越不来上课的人被点中的概率越高。

代码分析

导入相应的包:

import tkinter as tk
import tkinter.messagebox
import pickle
import random

定义随机点名对象,方法有

  1. def init_data(self): 初始化数据
  2. def init_lable(self): 初始化标签
  3. def run(self): 运行
class RandomNameGame(object):
    def __init__(self):
        self.window = tk.Tk()  #建立底层窗口
        self.window.title('随机点名程序')   #窗口名称
        self.window.geometry('500x500')   #窗口大小
        self.var = tk.StringVar()   #被点到成员的名字
        self.status = True  #随机状态控制

初始化数据:从pickle上下载数据

    def init_data(self):
        try:
            with open('users_info.pickle','rb') as user_file:
                self.user_info = pickle.load(user_file)
                print(self.user_info)
                self.user_name = [i for i in self.user_info.keys()]
                self.length = len(self.user_info)   #成员数量
                print(self.length)
        except FileNotFoundError:  #初始化成员
            with open('users_info.pickle','wb') as user_file:
                self.user_info = {
    'teacher':'0'}    #成员名字,旷课次数
                pickle.dump(self.user_info,user_file)

初始化标签:

    def init_lable(self):
        #刷新
        def Refresh():
            self.init_data()
            init_student_label()
            print(self.user_info)
            
        def init_student_label():   
            #初始化标签
            self.var_x = 40
            self.var_y = 150
            for item in self.user_name:
                if(self.var_x>=450):
                    tk.messagebox('Error','The student is too much')
                if(self.var_y>=350):
                    self.var_x += 100
                    self.var_y = 150
                    self.generate_label(item,self.var_x,self.var_y)
                    self.var_y +=60
                else:
                    self.generate_label(item,self.var_x,self.var_y)
                    self.var_y += 60
        init_student_label()
            
        #添加新成员
        def Add():
            #判断是否注册过,如果没注册则添加
            def sign_to():
                np = new_user_name.get()
                with open('users_info.pickle','rb') as user_file:  #对比有没重复
                    exist_user_info = pickle.load(user_file)
                if np in exist_user_info:
                    tk.messagebox('Error','The student has already in !')
                else:
                    exist_user_info[np] = 0
                    with open('users_info.pickle','wb') as user_file:
                        pickle.dump(exist_user_info,user_file)
                    tk.messagebox.showinfo('successful','You have successfully add !')
                    window_sign_up.destroy()
                    
            window_sign_up = tk.Toplevel(self.window)
            window_sign_up.geometry('300x100')
            window_sign_up.title('Add new student')
            tk.Label(window_sign_up,text='New User name :').place(x=20,y=30)
            new_user_name = tk.StringVar()  #定义新成员变量
            new_user_name.set('请输入新成员名字')
            #add entry
            entry_new_user_name = tk.Entry(window_sign_up,textvariable=new_user_name)
            entry_new_user_name.place(x=140,y=30)
            #Add Button
            btn_sign_up = tk.Button(window_sign_up,text='Add',command=sign_to)
            btn_sign_up.place(x=130,y=65)
            
        #删除成员
        def Drop():
            #self.init_data()
            window_drop_out = tk.Toplevel(self.window)
            window_drop_out.title('drop out')
            window_drop_out.geometry('400x200')
            
            list1 = self.user_name
            lb = tk.Listbox(window_drop_out,listvar = list1)
            for item in list1:
                lb.insert('end',item)
            lb.place(x=80,y=0)
             #撤销
            def cancel():
                lb.delete(0, "end")  #删除所有元素,用于更新列表
                window_drop_out.destroy()
            def dropout():
                value = lb.get(lb.curselection())
                print(value)
                #lb.delete(value)
                with open('users_info.pickle','rb') as user_file:  #对比有没重复
                    exist_user_info = pickle.load(user_file)
                    del exist_user_info[value]
                with open('users_info.pickle','wb') as user_file:
                    pickle.dump(exist_user_info,user_file)
                tk.messagebox.showinfo('successful','You have drop out it!')
                window_drop_out.destroy()                
            #定义删除按钮
            b1 = tk.Button(window_drop_out,text = 'drop',width = 15,height = 2,command=dropout,fg='white',bg='green')
            b1.place(x=250,y=40)
            b2 = tk.Button(window_drop_out,text = 'cancel',width = 15,height = 2,command=cancel,fg='white',bg='green')
            b2.place(x=250,y=100)
        def startup():
            list1 = []
            #根据迟到的次数往列表中增加名字的个数
            for key,value in self.user_info.items():
                for i in range(value+1):
                    list1.append(key)  #往名单中增加名字个数
            on_label = random.randint(0,len(list1)-1)  #随机抽取名单中的序列
            self.name = list1[on_label]  #得到点到人的名字
            self.var.set(self.name)
            print(self.name)
                
                
        def Attend():  #出勤
            tk.messagebox.showinfo('提示','perfect')
        def Absent():  #缺勤,记录次数
            self.user_info[self.name] +=1
            print(self.user_info)
            with open('users_info.pickle','wb') as user_file:
                pickle.dump(self.user_info,user_file)
            if(self.user_info[self.name]<5):
                tk.messagebox.showinfo('提示','你已经缺勤'+str(self.user_info[self.name])+'次')
            elif(self.user_info[self.name]>=5):
                tk.messagebox.showinfo('提示','你已经缺勤'+str(self.user_info[self.name])+'次'+'。您将被通知家长')
            

            
        #标题
        Label_title = tk.Label(self.window,text = '点名啦',font=('Arial','24'),fg='blue',height=2).pack()
        #点名名字的标题栏
        l = tk.Label(self.window,textvariable = self.var ,bg='yellow',font=('Arial',12),width = 15,height = 2)
        l.pack()
        #刷新,添加,删除
        Button_Refresh = tk.Button(self.window,text='刷新',bg='green',font=('Arial',12),fg='white',command=Refresh).place(x=60,y=420)
        Button_Add = tk.Button(self.window,text='添加',bg='green',font=('Arial',12),fg='white',command=Add).place(x=220,y=420)
        Button_Drop = tk.Button(self.window,text='删除',bg='green',font=('Arial',12),fg='white',command=Drop).place(x=380,y=420)
        #Label = tk.Label(self.window,text = self.user_info.values()).pack()
        #开始点名按钮
        Button_Stop = tk.Button(self.window,text='Start',bg='green',font=('Arial',20),fg='white',command=Start).place(x=55,y=30)
        #到
        Button_Attend = tk.Button(self.window,text='出勤',bg='green',font=('Arial',13),fg='white',command=Attend).place(x=420,y=15)
        #没到
        Button_Absent = tk.Button(self.window,text='缺勤',bg='green',font=('Arial',13),fg='white',command=Absent).place(x=420,y=70)

运行:

    def run(self):
        self.init_data()
        self.init_lable()
        self.window.mainloop()

实现结果

在这里插入图片描述

改进

迟到五次以上实现发短信提醒的功能

# 创建发送短信窗口
def send_message():
    email = entry_email.get()
    content = "你已经迟到"+str(self.user_info[self.name])+'次,请通知家长'
    flag = send_mail(content, email)
    if(flag == 1):
        tk.messagebox.showinfo('提示', '信息发送成功')
    else:
        tk.messagebox.showerror('失败', '请重新发送')
        window_send_message = tk.Toplevel(self.window)
        window_send_message.geometry('400x100')
        window_send_message.title('Add new student')
        tk.Label(window_send_message, text='Email :').place(x=20, y=30)
        new_user_name = tk.StringVar()  # 定义新成员变量
        new_user_name.set('输入邮箱')
        # add entry
        entry_email = tk.Entry(window_send_message, textvariable=new_user_name)
        entry_email.place(x=140, y=30)
        # Add Button
        btn_send_message = tk.Button(window_send_message, text='发送', command=send_message)
        btn_send_message.place(x=330, y=30)
       #tk.messagebox.showinfo('提示', '你已经缺勤' + str(self.user_info[self.name]) + '次' + '。您将被通知家长')

定义发短信的模块,可以设定发送方邮箱,需在QQ邮箱中开通POP3/SMTP服务。send_message.py模块如下:

import smtplib
from email.mime.text import MIMEText

def send_mail(content, email):
    msg_from = '[email protected]'  # 发送方邮箱
    passwd = 'ezdgvskeyvpvdbdh'  # 填入发送方邮箱的授权码
    msg_to = email
    subject = "点名"
    msg = MIMEText(content)
    msg['Subject'] = subject
    msg['From'] = msg_from
    msg['To'] = msg_to
    try:
        s = smtplib.SMTP_SSL("smtp.qq.com", 465)  # 发送一般使用465端口,使用163邮箱的话,需要更换成smtp.163.com
        s.login(msg_from, passwd)
        s.sendmail(msg_from, msg_to, msg.as_string())
    except Exception as e:
        return 0
        print('error')
        return False
    else:
        return 1
        print('邮件发送成功')

    finally:
        s.quit()
    return True

if __name__ == '__main__':
    message = '测试'
    email = '[email protected]'
    send_mail(message, email)

显示:发送成功!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/matafeiyanll/article/details/104453086

智能推荐

mktemp linux,Linux mktemp 命令使用方法-程序员宅基地

文章浏览阅读213次。原标题:Linux mktemp 命令使用方法Linux mktemp命令用于建立暂存文件。mktemp建立的一个暂存文件,供shell 使用。创建临时文件或者目录,这样的创建方式是安全的。此命令的适用范围:RedHat、RHEL、Ubuntu、CentOS、SUSE、openSUSE、Fedora。语法mktemp [-qu][文件名参数]参数:-q  执行时若发生错误,不会显示任何信息。-u ..._xbfi

API接口技术开发1688阿里巴巴alibabaAPI请求获取宝贝详情页数据、原价、销量、主图等参数可支持高并发调用接入演示-程序员宅基地

文章浏览阅读637次,点赞26次,收藏8次。请注意,由于1688的API可能会有调用频率的限制,因此在高并发场景下,你可能需要实现更复杂的逻辑来管理API密钥和访问令牌,以及处理API请求的排队和重试机制。此外,如果1688开放平台有提供特定的SDK,可以使用SDK来简化开发过程。

docker部署nginx_docker 部署nginx-程序员宅基地

文章浏览阅读1.2k次,点赞26次,收藏23次。本文讲述docker如何部署nginx的详细步骤和解释。_docker 部署nginx

PyCharm无法索引cannot find declaration to go to||CTRL+也不起作用(已解决)-程序员宅基地

文章浏览阅读9.9k次,点赞4次,收藏2次。如题所述,见下图问题解决很简单:方案一:file–&amp;gt;close project然后重新导入方案二:file–&amp;gt;settings–&amp;gt;project—&amp;gt;project interpreter绑定解释器方案三:真的是代码写错了,重新写一下,上级目录要带上...2018-12-14 22:15:18写于滨州市博兴县..._pycharm无法索引

十、卷积神经网络知识和二维卷积层计算(3.7学习笔记)_二维卷积后的参数怎么计算-程序员宅基地

文章浏览阅读519次。进入卷积神经网络学习_二维卷积后的参数怎么计算

如何修改Tomcat服务器Server Locations-程序员宅基地

文章浏览阅读1.4k次。首先双击我们集成好的Tomcat服务器 ,进入修改页面,修改Server Locations选项 , 会发现 Server Locations 灰色不可选,如果需要更改设置,则需要移除与Tomcat服务器关联的项目,同时,鼠标右键菜单Clean清除Tomcat服务器的状态,就可..._server locations

随便推点

在数据库层面分析系统性能(原创)-程序员宅基地

文章浏览阅读301次。系统级别信息v$sysstat按照OracleDocument中的描述,v$sysstat存储自数据库实例运行那刻起就开始累计全实例(instance-wide)的资源使用情况。该视图存储下列的统计信息:1&gt;.事件发生次数的统计(如:user commits)2&gt;.数据产生,存取或者操作的total列(如:redo size)3&gt;.如果TIMED_STATISTIC..._v$sysstat字段说明

c++配置libtorch_libtorch c++ param_groups-程序员宅基地

文章浏览阅读675次,点赞8次,收藏14次。CUDA版本最好选与本机一致的版本进行使用,但是我的经验告诉我即使下载的版本和电脑安装的CUDA版本不一致,但只要能兼容也可以使用。比如我下载的LIbTorch的CUDA版本是11.7但是电脑的CUDA版本是12.0,也是可以正常使用的,其中CUDA版本要大于等于LIbTorch的CUDA版本。把libtorch/lib中的所有dll放到libtorch/bin中,然后把libtorch/bin加到环境变量的path中.1、由于找不到xxx.dll,无法继续执行代码,重新安装程序可能会解决此问题。_libtorch c++ param_groups

PHP与ASP.NET:如何选择合适PHP?-程序员宅基地

文章浏览阅读353次。Are you a business owner looking for 您是正在寻找PHP web development services or ASP.Net development services, but unable to decide the right technology for your project? Are you looking for the PHP Web开..._网站 asp asp.net php如何选择

PIC16LC66-04I/SO 8位微控制器 -MCU 中文资料PDF参数-程序员宅基地

文章浏览阅读370次,点赞9次,收藏5次。工厂Lead Time:通常为4周 PIC16LC66-04I/SO是一种低功耗、高性能的8位CMOS微控制器,适用于各种嵌入式应用。PIC16LC66-04I/SO可以通过Microchip的MPLAB X IDE进行编程和调试。在使用该微控制器时,请务必查看其数据手册和参考手册,以了解其引脚定义、功能、应用电路图、电压和使用方法等详细信息。产品类型:8-bit Microcontrollers - MCU。器件名称:PIC16LC66-04I/SO。输入/输出端数量:22 I/O。

以太坊中私钥、公钥、账户地址详解_eth私钥地址分享-程序员宅基地

文章浏览阅读1.6w次,点赞2次,收藏14次。在学习以太坊的过程中,有些描述告诉我:公钥和账户地址有关系。一个以太坊地址就代表着一个以太坊账户,地址是账户的标识。对于外部账户来说,地址表示的是该账户公钥的后20字节(通常会以0x开头,例如,0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826,该地址使用的是16进制表示法2)。自己的疑问:那私钥呢?就是我们创建账户时,输入的密码吗?这也太简单了吧?..._eth私钥地址分享

基于springboot+vue.js的图书管理系统附带文章和源代码设计说明文档ppt-程序员宅基地

文章浏览阅读817次,点赞18次,收藏18次。博主介绍:CSDN特邀作者、985计算机专业毕业、某互联网大厂高级全栈开发程序员、码云/掘金/华为云/阿里云/InfoQ/StackOverflow/github等平台优质作者、专注于Java、小程序、前端、python等技术领域和毕业项目实战,以及程序定制化开发、全栈讲解、就业辅导、面试辅导、简历修改。精彩专栏 推荐订阅2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选题推荐2023-2024年最值得选的Java毕业设计选题大全:500个热门选题推荐。

推荐文章

热门文章

相关标签