随机点名程序

该程序利用Python设计了一个随机点名系统,缺勤者被点名的概率会增加。通过tkinter库实现交互式界面,支持点名、预警和记录缺勤情况。在点名过程中,缺勤同学的权重会提升,提高了他们被选中的几率。程序还具备结束点名时显示多次缺勤者名单的功能,有助于课堂管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第四次实验报告

程序语言: python
姓名: flyunicorninsky
学号: 12345678910
日期:2023/5/6


一、 问题重述

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


二、 问题分析

  这个代码以随机函数和文件处理为重点。越不来上课的人被点中概率越高想到在每次缺勤后对缺勤同学增加一定的权重,而点名的时候权重越高,点到的几率就越高。预警功能通过打印缺勤次数较多的同学名单来实现。还有就是可视化实现和交互。可视化就是点的名字的可视化,这个虽然在python的屏幕上也可以实现但是为了配合和鼠标的交互,便利点名的老师。我查找资料,使用了python库中的tkinter来实现可视化与交互。


三、 伪代码

选取随机同学的函数伪代码如下:

begin():    
    bad = 0
    sum = 0
    if len(unsign) == 0 then
        print("已全部点名")
        close()            #跳转到结束函数
        return
    for i <- 0 to len(unsign)):
        if unsign[i][1] == 0 then
            bad <- i
            break
        else
            sum += unsign[i][1]
    a <- random.randint(1, 999)
    if bad != 0 then
        if a % 3 == 0 then 
            lucky_dog <- random.randint(bad, len(unsign)-1)
        else:  
            a <- random.randint(0, sum - 1)
            for i in range(0, len(unsign)):
                a -= unsign[i][1]
                if a < 0:
                    lucky_dog <- i
                    break
    else:
        lucky_dog <- random.randint(0, len(unsign) - 1)


首先就是判断有无人缺勤过,如果没有直接按照等可能性来选择抽到的同学,如果有就使用另一种方法。这种方法就是先生成一个随机数,判断是否被三整除,被三整除即有三分之一的可能性抽查没缺勤过的同学,其他的就是三分之二的可能性抽查缺勤过的同学。没缺勤过的同学直接在其中使用等可能选取一位,缺勤过的同学则是按照缺勤次数的权重来决定可能性。


四、代码

代码如下:

import math
import random
from tkinter import *
from tkinter import font

# 创建窗口
win = Tk()
myfont = font.Font(size=20)
lucky_dog = 0  # 幸运儿
src_path = 'C:\\Users\\Lenovo\\Desktop\\names.txt'

def begin():
    global lucky_dog, content, bad, sum, unsign
    bad = 0
    sum = 0
    if len(unsign) == 0:
        print("已全部点名")
        close()
        return
    for i in range(0, len(unsign)):
        if unsign[i][1] == 0:
            bad = i
            break
        else:
            sum += unsign[i][1]
    a = random.randint(1, 999)
    if bad != 0:        # 还没人缺勤过,所有人等可能
        if a % 3 == 0:  # 1/3的概率是以前没缺勤过的
            lucky_dog = random.randint(bad, len(unsign)-1)
        else:  # 2/3的概率是以前缺勤过的
            a = random.randint(0, sum - 1)
            for i in range(0, len(unsign)):
                a -= unsign[i][1]
                if a < 0:
                    lucky_dog = i
                    break
    else:
        lucky_dog = random.randint(0, len(unsign) - 1)
    Label(text=unsign[lucky_dog][0], font=myfont).place(x=150, y=80)
    Button(text='结束点名', command=close).place(x=100, y=180, width=190)
    Button(text='出勤', command=yes).place(x=50, y=150, width=100)
    Button(text='未到', command=no).place(x=200, y=150, width=100)

def close():
    n = len(content)
    for i in range(n):
        for j in range(0, n - i - 1):
            if content[j][1] < content[j + 1][1]:
                content[j], content[j + 1] = content[j + 1], content[j]
    print("以下同学多次缺勤:")
    for i in range(n):
        if(content[i][1]>2):
            print(content[i][0]+"已经缺勤"+str(content[i][1])+"次")
    with open(src_path, 'w', encoding='utf-8') as file2:
        for i in range(0, len(content)):
            file2.write(content[i][0] + " " + str(content[i][1]) + '\n')
    win.destroy()
    
def yes():
    unsign.remove(unsign[lucky_dog])
    begin()

def no():
    for i in range(0, len(content)):
        if content[i][0]==unsign[lucky_dog][0]:
            content[i][1] += 1
            break
    unsign.remove(unsign[lucky_dog])
    begin()


with open(src_path, encoding='utf-8') as file:
    content = file.readlines()
    if(len(content)==0):
        print("文本空白!")
    for i in range(0, len(content)):
        content[i] = content[i].split(" ")
        content[i][1] = int(content[i][1])
    unsign = content.copy()
    # 设置窗口标题
    win.title('点名程序')
    # 设置窗口宽度和高度
    win.geometry('350x220')
    Button(text='开始点名', command=begin).place(x=100, y=180, width=190)
    win.mainloop()
    file.close()






五、 实验结果

输出大概如图(以下所有名字皆为实验测试需要随机生成名字,与现实无关)
运行程序后会出现:
开始点名
点击“开始点名”:
点名ing
此时点击“出勤”或者“未到”都会自动记录结果并转到下一个随机同学:
在这里插入图片描述
当想要结束点名时可以点击“结束点名”主动结束点名,或者是等到所有同学都点过一次名之后自动结束。
结束时
结束时会有“已全部点名”提示。并且打印出缺勤超过三次的同学名字以及其缺勤次数起到警示作用。


六、 遇到的一些问题

  一开始是想用网页实现,但是JS不太会,想到使用Java来写,因为他有便捷的交互页面,但是Java一直莫名其妙出现一些中文的乱码,尝试了一下解决不了,最后还是使用我大实验的老朋友python。
  其实遇到了很多问题,因为这个代码说实话没有什么真正难的地方,主要都是一些不熟悉的地方和一些粗心的点。这里我就只挑几个讲一下。
  有两个循环忘记range,单单就(0,len(content))结果就变成一个元组,就相当于只有两个元素,于是一直报超限的错误,debug了好一会。
  没有考虑到同学点到一次就不点,缺勤率高的人一直出现在一次点名里,然后几率变更高,最后就一直出现。相当于一个同学在一堂课上会被点到多次,这显然是不合理的。
  为了解决上面的问题我新建了一个unsign列表来表示未点到名的同学。我用unsign=content来表示。但是后面也是一直报错,后来才发现这样的数组相当于只是原数组换了一个名字而已,最后使用unsign=content.copy()才解决这个问题。


七、 总结

  基本实现了题目所要求的功能,可交互界面也使得对于老师等更加友善。可实现对本次课堂的缺勤数据的保存。
  交互界面做得有些粗糙,可以再进一步地完善美化界面;还可以完善一下缺勤次数权重的概率问题。
  本次实验更加了解了计算机中随机数的原理。学习了python中tkinter的一些操作。扩大了可视化领域的知识。扩展了思维,实现了将知识应用于实际。

做得很仓促,但是实现的效果还可以(得意)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值