使用Python可设置抽奖者权重的抽奖脚本代码
作者:Vincent__Lai 发布时间:2023-08-27 09:17:19
功能描述
抽奖系统包含如下特点:
1、可给不同抽奖者设置不同的权重
2、先从价值高的奖品开始抽
3、已经中奖的人,不再参与后续的抽奖
代码
第一个数字表示某一个用户的中奖编号,第二个数字表示该用户的中奖权重。名单.txt
内容为:
1:20
2:10
3:8
4:6
5:6
6:3
7:2
8:1
main.py
内容为:
# 抽奖工具
# -*- coding:utf-8 -*-
from random import choice
def read_name_list(txt_name):
with open(txt_name, 'r', encoding='utf-8') as f:
txt_list = f.readlines()
for i in range(len(txt_list)):
txt_list[i] = txt_list[i].rstrip('\n')
return txt_list
def lottery_draw(name_list, prize_box):
full_number = []
for name in name_list:
number, weight = name.split(':')
full_number += [number] * int(weight)
for prize in prize_box:
luck_number = choice(full_number)
print('【{}】的中奖用户编号为:{}'.format(prize, luck_number))
full_number = [i for i in full_number if i != luck_number]
if __name__ == '__main__':
# 导入名单
name_list = read_name_list('名单.txt')
# 设置奖项
prize_box = ['汽车', '电脑', '杯子', '香蕉', '5毛红包']
# 抽奖
lottery_draw(name_list, prize_box)
运行结果如下:
【汽车】的中奖用户编号为:5
【电脑】的中奖用户编号为:1
【杯子】的中奖用户编号为:3
【香蕉】的中奖用户编号为:2
【5毛红包】的中奖用户编号为:6
验证
加一个统计函数statistics
、修改下lottery_draw
的输入输出,然后抽奖1000000次,看看结果是否和我们设想的一样不同用户中奖权重不同。main.py
完整代码如下:
# 抽奖工具
# -*- coding:utf-8 -*-
from random import choice
from collections import Counter
def read_name_list(txt_name):
with open(txt_name, 'r', encoding='utf-8') as f:
txt_list = f.readlines()
for i in range(len(txt_list)):
txt_list[i] = txt_list[i].rstrip('\n')
return txt_list
def lottery_draw(name_list, prize_box, res):
full_number = []
for name in name_list:
number, weight = name.split(':')
full_number += [number] * int(weight)
for prize in prize_box:
luck_number = choice(full_number)
full_number = [i for i in full_number if i != luck_number]
res.append(prize+':'+luck_number)
return res
def statistics(res):
prize_cal = {'汽车':[], '电脑':[], '杯子':[], '香蕉':[], '5毛红包':[]}
for i in res:
prize, luck_number = i.split(':')
prize_cal[prize].append(luck_number)
for prize, number in prize_cal.items():
print('【{}】的各用户中奖次数:{}'.format(prize, Counter(number)))
if __name__ == '__main__':
# 导入名单
name_list = read_name_list('名单.txt')
# 设置奖项
prize_box = ['汽车', '电脑', '杯子', '香蕉', '5毛红包']
# 验证抽奖系统
res = []
for i in range(1000000):
# 抽奖
res = lottery_draw(name_list, prize_box, res)
# 统计数据
statistics(res)
结果为:
【汽车】的各用户中奖次数:Counter({'1': 356978, '2': 178116, '3': 143076, '5': 107189, '4': 107141, '6': 53638, '7': 35943, '8': 17919})
【电脑】的各用户中奖次数:Counter({'1': 262385, '2': 192168, '3': 160879, '5': 125696, '4': 125308, '6': 65905, '7': 44822, '8': 22837})
【杯子】的各用户中奖次数:Counter({'2': 189568, '1': 180131, '3': 173171, '4': 144363, '5': 143846, '6': 82818, '7': 56424, '8': 29679})
【香蕉】的各用户中奖次数:Counter({'3': 173540, '2': 170010, '4': 162484, '5': 162387, '1': 111469, '6': 104839, '7': 75181, '8': 40090})
【5毛红包】的各用户中奖次数:Counter({'5': 173954, '4': 173772, '3': 157203, '6': 139308, '2': 136231, '7': 103678, '1': 58633, '8': 57221})
可以看出以下结论:
通过第一行可以发现,数字之间出现的比例是和我们设置的权重是一样。例如
1
出现次数约等于2
的两倍、4
和5
的出现次数相近且均为6
的两倍。说明中奖数字出现的概率和预设权重是一样的。通过后面的行可以发现,对于权重大的数字(例如
1
),即使第一个奖品没中奖,大概率会在前几个奖品中奖,所以最后一个奖品里1
出现的次数很少,因为1
基本都是前面出现了。所以权重大的数字优先中价值高的奖品,和设想的一样。对于权重小的数字,例如
7
、8
,不管是哪一个奖品,出现次数都是最小的,说明这些数字中奖概率低。原因也很简单,因为中奖数字的个数是小于奖品数量的,所以权重小的数字中奖概率低,很可能5个奖品里都抽不到它们。如果设置为8个奖品的话,那么末尾的奖品7
、8
出现次数就会很高,因为此时中奖数字的个数等于奖品数量,所有数字都100%中奖,那么权重小的数字基本上都是中价值低的小奖。例如下面是8个奖品时的实验结果:
【汽车】的各用户中奖次数:Counter({'1': 357293, '2': 178396, '3': 142964, '4': 106969, '5': 106885, '6': 53787, '7': 35860, '8': 17846})
【电脑】的各用户中奖次数:Counter({'1': 262439, '2': 191894, '3': 160317, '4': 125823, '5': 125372, '6': 66868, '7': 44747, '8': 22540})
【杯子】的各用户中奖次数:Counter({'2': 189590, '1': 179792, '3': 172228, '4': 144894, '5': 144557, '6': 82114, '7': 57173, '8': 29652})
【香蕉】的各用户中奖次数:Counter({'3': 173294, '2': 170689, '4': 162112, '5': 162085, '1': 111105, '6': 105137, '7': 75643, '8': 39935})
【5毛红包】的各用户中奖次数:Counter({'5': 174098, '4': 173631, '3': 158224, '6': 138613, '2': 135805, '7': 103940, '1': 58826, '8': 56863})
【空气】的各用户中奖次数:Counter({'6': 201214, '7': 162491, '4': 156446, '5': 156151, '3': 117426, '8': 95013, '2': 87502, '1': 23757})
【垃圾】的各用户中奖次数:Counter({'7': 282600, '6': 225701, '8': 187694, '5': 99963, '4': 99165, '3': 60536, '2': 38211, '1': 6130})
【一巴掌】的各用户中奖次数:Counter({'8': 550457, '7': 237546, '6': 126566, '4': 30960, '5': 30889, '3': 15011, '2': 7913, '1': 658})
来源:https://blog.csdn.net/weixin_38705903/article/details/128065246
猜你喜欢
- 设计中文网站的朋友都会有这样的体会,Dreamweaver功能虽然强大,但要按照中文的行文习惯实现每个
- 一、题目内容给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的
- asp压缩access数据库(带密码)方法:以下是一个类文件,下面的注解是调用类的方法 注意:如果系统不支持建立Scripting
- 注:所有文字,除注明网站类型外,其他均针对企业站点.请随时注意留言,若修改则会在首页提示文字里标注.若牵扯到业务方面的问题,我可能不会做过多
- 前言在编程开发中,个人觉得,只要按照规范去做,很少会出问题。刚开始学习一门技术时,的确会遇到很多的坑。踩的坑多了,这是好事,会学到更多东西,
- pyinstaller 库的使用PyInstaller是一个十分有用的第三方库,它能够在Windows、Linux、Mac OS X 等操作
- requests安装和使用下载安装:pip install requests#requests模块import requests#发送请求
- 一、name_scopewith tf.name_scope(name):name_scope: 为了更好地管理变量的命名空间而提出的。比如
- 使用pyinstaller可以把.py文件打包为.exe可执行文件,命令为:pyinstaller hello.py打包后有两个文件夹,一个
- 本文实例为大家分享了python视频按帧截取图片工具的具体代码,供大家参考,具体内容如下描述:将一个视频流按帧数截取大量的图片用途:AI的数
- 前言python 文件操作、文件读写(write、read、readlines、readline)、文件的相关操作,简单易懂1 文件操作文件
- 学会了FSO提取文件值,也学会了将信息输入到文件中,那下面就再来应用应用下。不知道你有没有这样的习惯:看到一个文件,不自觉的右键选择用记事本
- 过滤器过滤器的本质就是函数。有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用
- 原型:EventManager是一个重要的原型,它用来赋予对象自定义事件的能力当对象类型的原型继承EventManager时,对象具有定义、
- PyQt5是强大的GUI工具之一,通过其可以实现优秀的桌面应用程序。希望通过一个简单的登录页面可以让大家顺利入坑,如有不妥之处还请大佬指点改
- 新一代GPT4发布了,今年GPT不断给大家带来惊喜。在OpenAI的官网,也公开了GPT的Python调用第三方库:openai。今天我们就
- PyCharm 光标变成了黑块,不能编辑代码。光标变黑块是因为输入方式变成了改写方式,INSERT可以切换 插入/改写模式。插入模式:把输入
- 本文较为详细的分析了Python解释执行的原理,对于深入理解Python可以起到一定的帮助作用。具体分析如下:首先,这里的解释执行是相对于编
- 1、调用字符映射表输入特殊符号在键盘上按win+R,在打开的对话框中输入“charmap”,会出现字符映射表:2、利用字符编码输入特殊符号#
- 在Python 3.10发布之前,Python是没有类似于其他语言中switch语句的,要实现类似的功能最简单的方法就是通过if ... e