Python模拟抽奖机制(年会抽奖,上课点名,商家活动…)
一、背景
1、用途
日常生活中,我们总会参与各种各样的抽奖活动,想通过这种方式实现一种相对公平的现象(虽然这种人为写的代码也未必有多公平,哈哈),但是只要是主办方相对公平也是可以去实现的。我们可以通过这种抽奖的方式来参与比如公司年会上的抽奖环节,大学课堂上老师抽名签到,店家为反馈用户进行德的抽奖活动等等。
2、意义
我们今天通过Python去模拟这样的一个抽奖系统,既能帮助我们增长知识,展示才能,明白其工作原理;在课堂上可以帮助老师节省时间,增加乐趣;对于商家来说,可以更好的回馈用户,实现商品的推广意义。接下来废话少说,直接走起。
二、代码展示
在展示代码之前先简单列一下代码实现逻辑:
1、环境展示
在这里我是把用户信息放在了一个excel中,方便我们对数据的处理:D:\CSDN\花名册.xlsx
,内容如下:
2、完整代码:注意文件路径及格式文件
import random
import pandas as pd
file_path = 'D:\CSDN\花名册.xlsx' #本地文件所放的路径
data = pd.read_excel(file_path, header=0) #读取文件中的内容,不需要读第一行表头数据
length = len(data.to_dict()['姓名']) #获取数据的行数
dict_name = data.to_dict()['姓名'] #将数据转成字典形式,获取姓名这一列
dict_number = list(data.to_dict()['编号']) #获取索引(以0开始)数据,并转为列表类型,用来做数据处理
status = 0 #自定义状态码,用来控制抽奖进程
while status != -1:
inputa = input('请输入你想抽取的人数:') #通过数据输入的方式来抽取获奖人数
if inputa!='':
inputa=int(inputa)
if length >= inputa > 0: # 判断输入的人数小于未抽奖的人数,并且大于0,则正常进行循环抽奖
select_number_list = random.sample(dict_number, k=inputa) # 随机在名称中抽选,k为抽奖的人数
for name in range(0, len(select_number_list)): #此时len(select_number_list))=k
select_name_str = data.to_dict()['姓名'][select_number_list[name]] # 通过for循环获取抽选的名称
print(select_name_str, end=' ') # 输出抽选到的人员名称
for number in dict_name.copy(): # 通过copy()函数处理数据的增加删除,满足抽中的人员不会参与下轮抽奖的需求,这个根据实际需求还咋是否添加
if dict_name[number] == select_name_str:
dict_name.pop(number) # pop()函数 从字典中删除数据
dict_number = list(set(dict_name)) # 重新排序,删除掉的去除,字典类型转换为列表类型
length = len(dict_name) #此时因为删除了已抽选到的数据,长度已经改变,重新获取,以免超限
print('---->还有' + str(length) + '个人没有中奖哦!')
elif inputa == 0:
print(('抽取的人数不能为0哦!'))
elif length > 0 and inputa > 0:
print("中奖机会没有那么多了哦!")
else:
status = -1
print('此次抽奖活动结束啦!')
else:
print('输入的数值不能为空哦!')
3、结果展示
D:\WorkPlace\venv\Scripts\python.exe D:\WorkPlace\Qtp5\抽奖系统.py
请输入你想抽取的人数:10
李小宇 李小儒 张小杰 王小鹏 杜小萌 佟小阁 黄小 岳小明 李小洋 贾小丽 ---->还有54个人没有中奖哦!
请输入你想抽取的人数:5
姜小兆 黄小然 文小 孙小雪 高小阳 ---->还有49个人没有中奖哦!
请输入你想抽取的人数:20
何小彤 贺小玉 杨小淇 荣小惠 汤小芸 史小霜 张小铭 张小源 陈小宇 王小 谭小 陈小 王小旭 李小齐 曾小杰 胡小鉴 杨小如 蒋小帆 刘小春 陶小岩 ---->还有29个人没有中奖哦!
请输入你想抽取的人数:0
抽取的人数不能为0哦!
请输入你想抽取的人数:-1
此次抽奖活动结束啦!
Process finished with exit code 0
三、代码解析
pandas函数以及下面的read_excel(),数据的转换提取可参考此文章:Python修改Excel中某一列的值。在这里我还是简单的解释一下但是不做演示处理。
①pd.read_excel()
pandas函数用来做数据处理的函数,其中pd.excel_excel函数为读取excel文件内容的函数,格式为<class 'pandas.core.frame.DataFrame'>
。
②data.to_dict()
因为上面读取出来的数据为DataFrame
数据,因此无法直接使用,在这里我通过to.dict()
函数将数据转为字典类型,这样就可以方便进行数据的处理了。
③len()
len()函数获取数据的长度,在这里获取实际excel的行数。data.to_dict()['姓名']
表示获取姓名那列的所有数值。data.to_dict()['姓名'][1]
获取姓名那列数据的第一个数据(索引从0开始)。list(data.to_dict()['编号'])
代表将字典类型转为列表类型数据,因为下面我会利用这个编号进行数据的遍历及随机抽取,很明显字典类型的数据无法操作。
④random.sample()
.sample()
不放回的方式随机抽取数据,这也是我们模拟抽奖所用到的关键函数之一。具体可以参考这篇文章详细了解:模拟彩票随机抽选机制,它的区别以及生活中我们也常碰到这样的工作原理。因为我们要保证公平公正,一人只有一次机会,奖项有限,所以采用不放回式的抽奖方式。
⑤dict_name.pop(number)
说上面用到的是核心技术,那么此函数的应用帮助我们实现逻辑的升华。我们实现的逻辑是每人一次抽奖机会那也就意味着抽中的人就要在抽奖名单中剔除。此函数的含义是用于删除字典给定键key及对应的值,返回值为被删除的值。这里的number
为字典的key
值,因此相应的value
(姓名也删除)。
⑥dict_name.copy()
因为像上面的情况我们进行数据的处理没了就没了,因此我们通过copy()函数,对姓名数据进行浅复制,这样在原数据被修改时,我们仍然不会受影响,正常按照编号返回抽取的姓名,要是不这样做,索引就会乱掉,导致抽取的找不到。
实际在原来的基础上就会报这个错误提示:
Traceback (most recent call last):
File "D:\WorkPlace\Qtp5\抽奖系统.py", line 20, in <module>
for number in dict_name: # 通过copy()函数处理数据的增加删除,满足抽中的人员不会参与下轮抽奖的需求,这个根据实际需求还咋是否添加
RuntimeError: dictionary changed size during iteration
⑦set(dict_name)
将删除后的数据重新整理,重新赋值给dic_number
。
结论分享
上面就是全部的内容啦,之后有时间的话我会把这个加上UI界面,真正意义上的抽奖系统,其实看起来这个抽奖系统也没啥难得,无法就是利用前端把页面搭建起来,就可以实现了。由于也是在学习的过程中,大家可以一起讨论,一起完善开发。😁