https://www.xin3721.com/eschool/pythonxin3721/

分析需求

我们先整理下思路,目标是什么?目标是要写一个抽奖程序,那么抽奖程序的核心是什么?当然是如何判断一个人中奖了。那么如何判断一个人中奖呢?是不是可以通过随机函数来操作呢?

中奖方法

一步一步来,我们先通过随机函数来判断是否中奖。代码是不是可以先写成下面这样:

1 importrandom2 ​3 #判断中奖函数

4 deflottery():5 flag = random.randint(0, 9)6 if flag < 2:7 returnTrue8 else:9 return False

首先,我们获取 0 ~ 9 之间的随机正整数(这里不讨论 random 是不是真随机,从狭义上来讲我们可以认为它是随机的),如果中奖率为 20% 的话,我们可以认为小于 2 的数字为中奖,其余的为没有中奖。然后中奖后返回 True ,没有中奖返回 False 。

我们加一个入口测试函数,测试一下上面的代码是否能正常运行,并且中奖率是否能维持在大约 20 % 左右。

1 if __name__ == '__main__':2 #中奖次数

3 a =04 #没有中奖次数

5 b =06 for i in range(1000000) :7 if(lottery()):8 a += 1

9 else:10 b += 1

11 ​12 print('共计中奖:', a, ',未中奖:', b)

执行结果:

共计中奖: 200145 ,未中奖: 799855

上面的测试总共循环了 1 百万次,大约执行需要 2 ~ 3 秒左右,速度还是蛮快的。可以看到,中奖结果确实接近 20% 左右。

动态中奖率

难道到这里就结束了么?当然不可能,这里只是刚刚开了个头。

如果这时老板说,你这个概率不能调整啊,需要让中奖率可以动态调整的,活动刚开始的时候中奖率要高,随着时间的推移,中奖率要降下来。

这时候咋整,傻眼了吧。

既然中奖率要可调整,那么我们中奖率就不能定死在程序中了,这个中奖率需要有一个地方去做存储,在每次做随机的时候将这个中奖率取出来。

简单易行的方法就是将这个中奖率放在数据库中或者缓存服务中,这个根据实际业务场景来定。一般是根据预估访问压力的大小来进行技术选型,如果压力不是特别大,那么放在数据库中也是可以的,如果并发会比较高的话,建议还是放在缓存中。

我们来写一个从数据库获取中奖概率的方法(为了展示直观,小编这里直接使用 Mysql 数据库用作数据存储),先看下数据库的数据:

很简单的设计了一张表,里面有意义的字段有两个,一个用作中奖率的分子部分,一个用作中奖率的分母部分。分母部分最好要设置成 100 、 1000 、 10000 这种,这样计算中奖率会比较好计算。

1 defget_lottery_rate():2 conn = pymysql.connect(host='localhost', user='root', password='password', database='test', charset='utf8mb4')3 try:4 sql = 'SELECT fenzi, fenmu FROM rate'

5 cursor =conn.cursor()6 cursor.execute(sql)7 result =cursor.fetchone()8 returnresult9 exceptException as ex:10 print(ex)11 finally:12 conn.close()

运行这个方法测试结果如下:

(10, 100)

可以看到,我们获得了一个元组,里面的内容就是我们从数据库取出来的分子和分母。

我们将前面的抽奖的那个方法改一下,改成从数据库获取中奖比例。修改后的代码如下:

1 deflottery():2 rate =get_lottery_rate()3 flag = random.randint(1, rate[1])4 if flag

还是运行上面的测试方法,这里要注意下,因为我们现在是从数据库获取数据,每次方法执行都要加上数据库链接的建立与销毁,建议将循环次数修改为 1000 以内,不然执行的时间就有点太长了。

小编这里将循环次数修改为 1000 次后,执行结果如下:

共计中奖: 92 ,未中奖: 908

那么到这里,我们就可以通过修改数据库中数据实时的操作中奖率了。当然上面的慢的问题我们可以使用数据库连接池等技术进行优化。

增加奖项

那么是否就结束了呢?no no no,我们接着加需求。

现在,我们只能知道每次到底中不中奖,只有一个奖项,但是现在想变成 3 个奖项,如:一等奖、二等奖、三等奖那该怎么办?

这个对之前的抽奖方法改动就有点大了,首先我们先在数据库增加出来另外两个奖项的配置:

配置这里三个奖项的分母最好保持一致,否则后续计算会徒增复杂度。

修改我们获取配置的那个方法:

1 defget_lottery_rate():2 conn = pymysql.connect(host='localhost', port = 3306, user='root', password='password', database='test', charset='utf8mb4')3 try:4 sql = 'SELECT * FROM rate order by id asc'

5 cursor =conn.cursor()6 cursor.execute(sql)7 result =cursor.fetchall()8 returnresult9 exceptException as ex:10 print(ex)11 finally:12 conn.close()

测试调用后结果如下:

((1, 10, 100), (2, 5, 100), (3, 1, 100))

先在我们要做的是要将这个配置融入进我们之前的中奖的那个方法中,不多说,直接上代码:

1 #判断中奖函数

2 deflottery():3 config =get_lottery_rate()4 flag = random.randint(1, config[0][2])5 if flag <= config[0][1]:6 return 1

7 elif flag > config[0][1] and flag <= (config[1][1] + config[0][1]):8 return 2

9 elif flag > (config[1][1] + config[0][1]) and flag <= (config[2][1] + config[1][1]):10 return 3

11 else:12 return 0

接着修改我们的做测试的代码:

1 defmain():2 #一等奖中奖次数

3 a =04 #二等奖中奖次数

5 b =06 #三等奖中奖次数

7 c =08 #未中奖次数

9 d =010 #循环次数

11 e =012 for i in range(1000):13 e += 1

14 print('当前循环次数:', e)15 result =lottery()16 print('当前中奖结果:', result)17 if (result == 1):18 a += 1

19 elif (result == 2):20 b += 1

21 elif (result == 3):22 c += 1

23 else:24 d += 1

25

26 print('一等奖中奖:', a, ',二等奖中奖次数:', b, ',三等奖中奖次数:', c, ',未中奖次数:', d)

调用我们的测试方法:

if __name__ == '__main__':

main()

小编这里的运行结果如下:

增加会员判断

到这里我们还没完,还能加需求,现在网站大多数都是会员制的,比如白银会员,黄金会员,钻石会员,如果不同的会员等级需要有不同的中奖率,这个是很正常的一件事儿,小编现在还清晰的记得当年某家大型互联网公司代码中的注释 “穷逼 VIP(活动送的那种)” 。

我们假设钻石会员的中奖率为整体中奖率的 100% ,黄金会员的中奖率为整体中奖率的 50% ,白银会员的中奖率为整体中奖率的 20% 。

最简单的实现方式是直接在最外层套一层会员中奖率的判断,不知道各位同学怎么想。

小编这里给出自己的解决方案:

# 判断会员等级中奖率过滤

# 会员等级 1.白银会员 2.黄金会员 3. 钻石会员

def vip_lottery(level):

rate = random.randint(1, 10)

# 如果是钻石会员,直接进入抽奖函数

if level == 3:

return lottery()

# 如果是黄金会员, 50% 概率进入抽奖函数

elif level == 2:

if rate <= 5:

return lottery()

else:

return 0

# 如果是白银会员, 20% 概率进入抽奖函数

elif level == 1:

if rate <= 2:

return lottery()

else:

return 0

# 如果是其他,直接返回未中奖

else:

return 0

我们新增一个测试增加会员过滤的测试方法:

# 会员制中奖测试方法

def test_vip():

print('请输入您当前的会员等级:1.白银会员 2.黄金会员 3. 钻石会员')

level = input()

result = vip_lottery(int(level))

if (result == 1):

print('恭喜您中了一等奖')

elif (result == 2):

print('恭喜您中了二等奖')

elif (result == 3):

print('恭喜您中了三等奖')

else:

print('未中奖,谢谢惠顾')

在我们的入口函数中调用这个方法:

if __name__ == '__main__':

test_vip()

最终测试结果如下:小编的人品还可以嘛,直接就能中三等奖。

1 importrandom2 importpymysql3 ​4 #获取中奖配置

5 defget_lottery_rate():6 conn = pymysql.connect(host='114.67.111.196', port = 3306, user='root', password='wsy@123456', database='test', charset='utf8mb4')7 try:8 sql = 'SELECT * FROM rate order by id asc'

9 cursor =conn.cursor()10 cursor.execute(sql)11 result =cursor.fetchall()12 returnresult13 exceptException as ex:14 print(ex)15 finally:16 conn.close()17 ​18 #判断中奖函数

19 deflottery():20 config =get_lottery_rate()21 flag = random.randint(1, config[0][2])22 if flag <= config[0][1]:23 return 1

24 elif flag > config[0][1] and flag <= (config[1][1] + config[0][1]):25 return 2

26 elif flag > (config[1][1] + config[0][1]) and flag <= (config[2][1] + config[1][1]):27 return 3

28 else:29 return030 ​31 #判断会员等级中奖率过滤

32 #会员等级 1.白银会员 2.黄金会员 3. 钻石会员

33 defvip_lottery(level):34 rate = random.randint(1, 10)35 #如果是钻石会员,直接进入抽奖函数

36 if level == 3:37 returnlottery()38 #如果是黄金会员, 50% 概率进入抽奖函数

39 elif level == 2:40 if rate <= 5:41 returnlottery()42 else:43 return044 #如果是白银会员, 20% 概率进入抽奖函数

45 elif level == 1:46 if rate <= 2:47 returnlottery()48 else:49 return050 #如果是其他,直接返回未中奖

51 else:52 return053 ​54 #批量测试方法

55 deftest():56 #一等奖中奖次数

57 a =058 #二等奖中奖次数

59 b =060 #三等奖中奖次数

61 c =062 #未中奖次数

63 d =064 #循环次数

65 e =066 for i in range(1000):67 e += 1

68 print('当前循环次数:', e)69 result =lottery()70 print('当前中奖结果:', result)71 if (result == 1):72 a += 1

73 elif (result == 2):74 b += 1

75 elif (result == 3):76 c += 1

77 else:78 d += 1

79 ​80 print('一等奖中奖:', a, ',二等奖中奖次数:', b, ',三等奖中奖次数:', c, ',未中奖次数:', d)81 ​82 #会员制中奖测试方法

83 deftest_vip():84 print('请输入您当前的会员等级:1.白银会员 2.黄金会员 3. 钻石会员')85 level =input()86 result =vip_lottery(int(level))87 if (result == 1):88 print('恭喜您中了一等奖')89 elif (result == 2):90 print('恭喜您中了二等奖')91 elif (result == 3):92 print('恭喜您中了三等奖')93 else:94 print('未中奖,谢谢惠顾')95 ​96 if __name__ == '__main__':97 test_vip()

python抽奖教程_利用Python写一个抽奖程序,解密游戏内抽奖的秘密|python基础教程|python入门|python教程...相关推荐

  1. python抽奖游戏_利用Python写一个抽奖程序,解密游戏内抽奖的秘密

    原标题:利用Python写一个抽奖程序,解密游戏内抽奖的秘密 前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 极客 ...

  2. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  3. python是一门面向什么的语言用词语填空_使用pygame写一个古诗词填空通关游戏

    之前写的诗词填空的游戏支持python2,现在对程序进行了修改,兼容支持python2和python3,附下效果图. 下面是两个主程序 idiom_lib.py代码: # -*- coding=utf ...

  4. wx.checkjsapi是写在config里面吗_用Python写一个程序,解密游戏内抽奖的秘密

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 极客挖掘机 PS:如有需要Python学习资料的小伙伴可以加点击下 ...

  5. 用Python写一个程序,解密游戏内抽奖的秘密

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 分析需求 我们先整理下思路,目标是什么? 目标是要写一个抽奖程序,那么抽奖 ...

  6. 使用python加PyQt5,利用QMediaPlayer写一个简易的音乐播放器(进度条拖动,音量改变,播放停止切换,歌曲列表))

    当你学习了python之后,总想着利用它去做些什么,无论是制作小工具还是小游戏,都是一种锻炼. 那么,利用python加上PyQt5写一个简单的音乐播放器,可能会是一个有趣的体验. 下面我会分享一下如 ...

  7. python数字华容道算法_用React写一个数字华容道,你需要知道的秘密

    还在上班?很无聊? 这个叫前言 年末了.哦,不,要过年了.以前只能一路站到公司的我,今早居然是坐着过来的.新的一年,总要学一个新东西来迎接新的未来吧,所以选择了一直未碰的那个据说是全宇宙最牛逼的前端框 ...

  8. python程序是由一系列代码组成的_0基础7日入门Python

    Python是世界上最容易学的编程语言,从没接触过编程的人也能搞定. 从现在开始跟随极客学院成长计划,每天进取,怒赞自己. 给大家整理的这套 python 学习路线图,按照此教程一步步的学习来,肯定会 ...

  9. 用python写一个小程序,解决买水果的问题?

    问题: 商店总共有三种水果,香蕉/苹果/葡萄,单价分别为3.5/5.0/3.0元/500克. 写一个小程序实现: 1.输出一个菜单:打印每种水果的价格: 2.寻问客户欲购买水果? 3.客户想购买的克数 ...

最新文章

  1. vuex 闲置状态重置方案
  2. rsync - 远程同步工具
  3. java线程安全性_Java并发-线程安全性
  4. python【Matlibplot绘图库】-绘制三维图像
  5. 微信公众号开发入门教程第一篇
  6. sql server在执行批处理时出现错误。错误消息为: 目录名无效
  7. shiro学习(7):shiro连接数据库 方式二
  8. 数据保护伞—为MaxCompute平台数据安全保驾护航
  9. 管理动物园动物c++_《过山车大亨》开发商公开新作 建立自己的动物园
  10. 鸿蒙轻内核源码分析:MMU协处理器
  11. 【英语学习】【WOTD】largesse 释义/词源/示例
  12. php mysql查询例子_php mysqli多个查询的例子
  13. 古希腊之争(一)详解(C++)
  14. 03-SSH server config
  15. Vue报错信息Module not found: Error: Can‘t resolve ‘vue/types/umd‘ in
  16. 注册表编辑器,任务管理器,己被系统管理员停用----应急响应
  17. HTML5和CSS3 API文档分享
  18. 奇迹mu选区后就一直显示连接服务器,奇迹mu双开
  19. 数据结构与算法--图的广度优先搜索 (BFS)
  20. PHP 十六大魔术方法学习

热门文章

  1. 使用Vue将两张图片叠加再保存为一张图片下载
  2. c++双向列表释放_VOC气候舱 学校人造草TVOC释放检测气候舱T/JYBZ 012—2019
  3. 美化微信公众号图文内容,修饰边框
  4. 初级程序员进大厂必刷的100道算法题
  5. 生活不止眼前的苟且,还有python和远方——认识Python
  6. 密码学系列(四):整理世界性网络安全相关组织、企业的网站【持更】
  7. 计算机组装的具体步骤,电脑装机教程,详细教您怎么组装电脑
  8. 从装配式建筑流行看云原生技术中台价值 (二)
  9. BP-Tool 功能介绍,下载地址
  10. boost库随机数使用详解