当前位置: 首页 > 后端技术 > Python

如何用Python写一个简单的抽奖程序

时间:2023-03-25 20:20:13 Python

不知道有多少人被这张头图骗了:)原因是这样的。上周有同学问小编。代码,感觉自己可以写。如果不看,我可能会七七八八地写出来,但是一旦我独立写了一个程序,我就觉得无从下手。其实,这是很正常的。刚开始学写代码的时候,我是跟着别人的套路,写下来的。我看到的套路很少,很难形成自己的套路。这个题目的可能性很小,可以通过大量的练习找到自己的套路。恰好临近春节,各家公司都会举办一些抽奖活动。小编今天就来说说。如果要写一个简单的抽奖程序,小编是怎么写的。分析需求,我们先梳理一下思路。目标是什么?目标是写一个抽奖程序,那么抽奖程序的核心是什么?当然,如何判断一个人中了彩票。那么你怎么知道有人中了彩票呢?是否可以通过随机函数进行操作?获胜方法是循序渐进。我们先用random函数来判断是否中奖了。代码能不能这样写:importrandom#判断中奖函数deflottery():flag=random.randint(0,9)ifflag<2:returnTrueelse:returnFalse首先我们得到0到9之间的数字随机正整数(这里不讨论随机是否真的随机,狭义上可以认为是随机),如果中奖率为20%,我们可以认为小于2的数为中奖,其余为不中奖.然后中奖返回True,没中奖返回False。下面我们添加一个入口测试函数,测试一下上面的代码是否可以正常运行,中奖率是否可以保持在20%左右。if__name__=='__main__':#中奖次数a=0#无中奖次数b=0foriinrange(1000000):if(lottery()):a+=1else:b+=1print('total中奖:',a,',未中奖:',b)执行结果:总中奖:200145,未中奖:799855以上测试一共循环了100万次,执行时间大概2~3秒,而且速度还是挺快的。可见中奖结果确实接近20%左右。动态胜率就到此为止了吗?当然不是,这仅仅是个开始。如果这时候老板说,你的概率不能调整,需要动态调整胜率。活动开始时中奖率应该很高,但随着时间的推移,中奖率会降低。这时候怎么回事,我傻眼了。由于中奖率应该是可调的,所以我们无法在程序中固定中奖率。这个胜率需要有个地方存起来,我们每次做随机的时候就把它拿出来。简单易行的方法是将中奖率放在数据库中,或者放在缓存服务中,这要看实际业务场景。通常,技术选择基于估计的访问压力。如果压力不是特别大,放在数据库里也是可以的。如果并发比较高,建议放在缓存中。下面写一个从数据库获取中奖概率的方法(为了直观展示,小编直接使用Mysql数据库作为数据存储),先看数据库中的数据:简单设计了一张表,里面有有意义的字段它有两种,一种用作中奖率的分子部分,另一种用作中奖率的分母部分。分母部分最好设置为100、1000、10000,这样会更容易计算中奖率。defget_lottery_rate():conn=pymysql.connect(host='localhost',user='root',password='password',database='test',charset='utf8mb4')try:sql='SELECTfenzi,fenmuFROMrate'cursor=conn.cursor()cursor.execute(sql)result=cursor.fetchone()returnresultexceptExceptionasex:print(ex)finally:conn.close()运行该方法的测试结果如下如下:(10,100)可以看出我们得到了一个元组,元组的内容就是我们从数据库中取出的分子和分母。我们把之前抽奖的方法改一下,从数据库中获取中奖率。修改后的代码如下:deflottery():rate=get_lottery_rate()flag=random.randint(1,rate[1])ifflagconfig[0][1]andflag<=(config[1][1]+config[0][1]):return2elifflag>(config[1][1]+config[0][1])andflag<=(config[2][1]+config[1][1]):return3else:return0然后修改我们的测试代码:defmain():#一等奖中奖次数a=0#二等奖中奖次数b=0#三等奖中奖次数c=0#未中奖次数d=0#循环次数e=0foriinrange(1000):e+=1print('当前循环次数:',e)result=lottery()print('当前winningresult:',result)if(result==1):a+=1elif(result==2):b+=1elif(result==3):c+=1else:d+=1打印('一等奖中奖次数:',a,',二等奖中奖次数:',b,',三等奖中奖次数:',c,',未中奖次数:',d)调用我们的测试方法:if__name__=='__main__':main()这里编辑器的运行结果如下:添加成员判断到这里还没完,我们还可以添加需求。现在大部分网站都是会员制的,比如银卡会员、金卡会员、钻石卡会员,如果不同的会员级别需要有不同的中奖率,这是很正常的事情。小编还清楚记得当年某大型互联网公司代码中的评论“可怜的VIP(活动给的那种)”我们假设钻石会员的中奖率是整体中奖率的100%,黄金会员胜率占总胜率的50%,银牌会员胜率占总胜率的20%,最简单的实现方式是直接将会员胜率的判断设置在最外层layer.不知道大家怎么看。小编在这里给出自己的解决方案:#判断会员等级中奖率过滤器#会员等级1.白银会员2.黄金会员3.钻石会员defvip_lottery(level):rate=random.randint(1,10)#如果如果你是钻石会员,直接进入抽奖函数iflevel==3:returnlottery()#如果是金卡会员,有50%的概率进入抽奖函数eliflevel==2:ifrate<=5:returnlottery()else:return0#如果是银卡会员,有20%的概率进入抽奖功能eliflevel==1:ifrate<=2:returnlottery()else:return0#If是其他的,直接returnnotwinningelse:return0我们新增一个测试添加一个会员过滤的测试方法:#会员中奖测试方法deftest_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('没有中奖,谢谢patronage')在我们的入口函数中调用这个方法:if__name__=='__main__':test_vip()最终测试结果如下:小编的人品还不错,可以直接中三等奖。那么,至此,是不是完成了一个简单的抽奖程序呢?其实还可以多加。如果每个奖项都有数量限制,限制的数量可以随时调整等等,小编就不一一列举了。整体代码有点长,就不贴了,上传到代码仓库。有兴趣的同学可以自行参观。注意:本文中使用的代码仅用于演示和解释,不能用于生产环境。当流量过大时会出现严重的性能问题。示例代码示例代码-Github示例代码-Gitee如果我的文章对您有帮助,请扫码关注作者的公众号:获取最新干货推送:)