请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

如何用Python 写一个简易的抽奖程序,值得收藏

[复制链接]
查看: 26|回复: 0

2万

主题

2万

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
76556
发表于 2020-9-15 18:12 | 显示全部楼层 |阅读模式


我的关键词 如何用Python 写一个简易的抽奖程序,值得收藏  新闻咨询

不知道有多少人是被这个头图骗进来的:)
事情的起因是这样的,上周有同学问小编,看着小编的示例代码敲代码,感觉自己也会写了,如果不看的话,七七八八可能也写的出来,但是一旦自己独立写一段程序,感觉到无从下手。
其实这个很正常,刚开始学习写代码,都是跟着别人的套路往下写,看的套路少,很难形成自己的套路,这就和做数学题是一样的,做一道题就想会所有的题目,这个可能性微乎其微,都是通过大量的练习来摸索到自己的套路。
正好快过年了,各个公司都会搞一些抽奖活动,小编今天就来聊一下,如果要写一个简单的抽奖程序,小编是怎么写的。
注意:不管你是为了Python就业还是兴趣爱好,记住:项目开发经验永远是核心,如果你没有2020最新python入门到高级实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,里面很多新python教程项目,还可以跟老司机交流讨教!
分析需求

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

一步一步来,我们先通过随机函数来判断是否中奖。代码是不是可以先写成下面这样:
  1. import random# 判断中奖函数def lottery():    flag = random.randint(0, 9)    if flag < 2:        return True    else:        return False复制代码
复制代码
首先,我们获取 0 ~ 9 之间的随机正整数(这里不讨论 random 是不是真随机,从狭义上来讲我们可以认为它是随机的),如果中奖率为 20% 的话,我们可以认为小于 2 的数字为中奖,其余的为没有中奖。然后中奖后返回 True ,没有中奖返回 False 。
我们加一个入口测试函数,测试一下上面的代码是否能正常运行,并且中奖率是否能维持在大约 20 % 左右。
  1. if __name__ == '__main__':    # 中奖次数    a = 0    # 没有中奖次数    b = 0    for i in range(1000000) :        if (lottery()):            a += 1        else:            b += 1    print('共计中奖:', a, ',未中奖:', b)复制代码
复制代码
执行结果:
  1. 共计中奖: 200145 ,未中奖: 799855复制代码
复制代码
上面的测试总共循环了 1 百万次,大约执行需要 2 ~ 3 秒左右,速度还是蛮快的。可以看到,中奖结果确实接近 20% 左右。
动态中奖率

难道到这里就结束了么?当然不可能,这里只是刚刚开了个头。
如果这时老板说,你这个概率不能调整啊,需要让中奖率可以动态调整的,活动刚开始的时候中奖率要高,随着时间的推移,中奖率要降下来。
这时候咋整,傻眼了吧。
既然中奖率要可调整,那么我们中奖率就不能定死在程序中了,这个中奖率需要有一个地方去做存储,在每次做随机的时候将这个中奖率取出来。
简单易行的方法就是将这个中奖率放在数据库中或者缓存服务中,这个根据实际业务场景来定。一般是根据预估访问压力的大小来进行技术选型,如果压力不是特别大,那么放在数据库中也是可以的,如果并发会比较高的话,建议还是放在缓存中。
我们来写一个从数据库获取中奖概率的方法(为了展示直观,小编这里直接使用 Mysql 数据库用作数据存储),先看下数据库的数据:我的关键词 如何用Python 写一个简易的抽奖程序,值得收藏  新闻咨询
很简单的设计了一张表,里面有意义的字段有两个,一个用作中奖率的分子部分,一个用作中奖率的分母部分。分母部分最好要设置成 100 、 1000 、 10000 这种,这样计算中奖率会比较好计算。
  1. def get_lottery_rate():    conn = pymysql.connect(host='localhost', user='root', password='password', database='test', charset='utf8mb4')    try:        sql = 'SELECT fenzi, fenmu FROM rate'        cursor = conn.cursor()        cursor.execute(sql)        result = cursor.fetchone()        return result    except Exception as ex:        print(ex)    finally:        conn.close()复制代码
复制代码
运行这个方法测试结果如下:
  1. (10, 100)复制代码
复制代码
可以看到,我们获得了一个元组,里面的内容就是我们从数据库取出来的分子和分母。
我们将前面的抽奖的那个方法改一下,改成从数据库获取中奖比例。修改后的代码如下:
  1. def lottery():    rate = get_lottery_rate()    flag = random.randint(1, rate[1])    if flag < rate[0]:        return True    else:        return False复制代码
复制代码
还是运行上面的测试方法,这里要注意下,因为我们现在是从数据库获取数据,每次方法执行都要加上数据库链接的建立与销毁,建议将循环次数修改为 1000 以内,不然执行的时间就有点太长了。
小编这里将循环次数修改为 1000 次后,执行结果如下:
  1. 共计中奖: 92 ,未中奖: 908复制代码
复制代码
那么到这里,我们就可以通过修改数据库中数据实时的操作中奖率了。当然上面的慢的问题我们可以使用数据库连接池等技术进行优化。
增加奖项

那么是否就结束了呢?no no no,我们接着加需求。
现在,我们只能知道每次到底中不中奖,只有一个奖项,但是现在想变成 3 个奖项,如:一等奖、二等奖、三等奖那该怎么办?
这个对之前的抽奖方法改动就有点大了,首先我们先在数据库增加出来另外两个奖项的配置:
我的关键词 如何用Python 写一个简易的抽奖程序,值得收藏  新闻咨询
配置这里三个奖项的分母最好保持一致,否则后续计算会徒增复杂度。
修改我们获取配置的那个方法:
  1. def get_lottery_rate():    conn = pymysql.connect(host='localhost', port = 3306, user='root', password='password', database='test', charset='utf8mb4')    try:        sql = 'SELECT * FROM rate order by id asc '        cursor = conn.cursor()        cursor.execute(sql)        result = cursor.fetchall()        return result    except Exception as ex:        print(ex)    finally:        conn.close()复制代码
复制代码
测试调用后结果如下:
  1. ((1, 10, 100), (2, 5, 100), (3, 1, 100))复制代码
复制代码
先在我们要做的是要将这个配置融入进我们之前的中奖的那个方法中,不多说,直接上代码:
[code]# 判断中奖函数def lottery():    config = get_lottery_rate()    flag = random.randint(1, config[0][2])    if flag  config[0][1] and flag  (config[1][1] + config[0][1]) and flag </p>增加会员判断

到这里我们还没完,还能加需求,现在网站大多数都是会员制的,比如白银会员,黄金会员,钻石会员,如果不同的会员等级需要有不同的中奖率,这个是很正常的一件事儿,小编现在还清晰的记得当年某家大型互联网公司代码中的注释 “穷逼 VIP(活动送的那种)” 。
我们假设钻石会员的中奖率为整体中奖率的 100% ,黄金会员的中奖率为整体中奖率的 50% ,白银会员的中奖率为整体中奖率的 20% 。
最简单的实现方式是直接在最外层套一层会员中奖率的判断,不知道各位同学怎么想。
小编这里给出自己的解决方案:
[code]# 判断会员等级中奖率过滤# 会员等级 1.白银会员 2.黄金会员 3. 钻石会员def vip_lottery(level):    rate = random.randint(1, 10)    # 如果是钻石会员,直接进入抽奖函数    if level == 3:        return lottery()    # 如果是黄金会员, 50% 概率进入抽奖函数    elif level == 2:        if rate
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表