How to write a simple lottery program in Python

I do not know how many people are being cheated come in this first map :)

It began like this, last week, some students asked Xiao Bian, looking at the sample code in the code knock small series, will feel that they wrote, if you do not look at it, seven thousand seven hundred eighty-eight may be written out, but once their own independent write a program, feel no start.

In fact, this is normal, just beginning to learn to write code, are following someone else's routine down to write, watch less routine, it is difficult to form their own routines, which are the same and do the math and do a question all wanted to be the title, this is extremely unlikely, is to groped their routines through a lot of practice.

Just New Year approached, each company will carry out some sweepstakes, Xiao Bian today to talk about, if you write a simple lottery program, Xiao Bian is how to write.

Analysis of demand

Let's organize your thoughts down, what is the objective?

The goal is to write a lottery program, lottery program What is the core?

Of course, is how to judge a person won the lottery. So how do you judge a person winning it?

It is not to be operated by a random function?

Winning method

Step by step, first by our random function to determine whether or not winning. Code is not possible to write the following:

import random

# 判断中奖函数
def lottery():
    flag = random.randint(0, 9)
    if flag < 2:
        return True
    else:
        return False

First, we obtain random between 0 to 9, a positive integer (not discussed here is not really random random, from the narrow sense and we believe that it is random), if the winning ratio of 20%, we can think of less than 2 as the winning numbers, and the rest is not winning. Then after winning return True, there is no winning return False.

We add an entry test function to test whether the above code to run correctly, and whether the winning rate can be maintained at about 20%.

if __name__ == '__main__':
    # 中奖次数
    a = 0
    # 没有中奖次数
    b = 0
    for i in range(1000000) :
        if (lottery()):
            a += 1
        else:
            b += 1

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

Results of the:

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

The above test a total circulation of 1 million, about the implementation takes about 2 to 3 seconds, the speed is pretty fast. We can see the winning result is indeed approaching 20%.

Dynamic winning rate

Is it to end here? Of course not, here is just a start.

If my boss says you can not adjust the probability ah, need to make the winning rate can be dynamically adjusted, activity started when the winning rate is higher, over time, the winning rate to come down.

This time Zezheng, dumbfounded it.

Since winning rate to be adjusted, then we will not be winning rate scheduled to die in the program, and the need to have a winning rate place to do it is stored in random every time when this will be taken out winning rate.

This simple method is to put the winning rate or database caching services, this to be based on actual business scenarios. Is generally carried out according to the size of the estimated access technology selection pressure, if the pressure is not particularly large, then placed in the database is also possible, if concurrency will be relatively high, the proposal is still in the cache.

Let's write a method to obtain the probability of winning from the database (for visual display, small series here directly using Mysql database for data storage), look at the data in the database:

Very simple design of a table, which has two meaningful field, a molecule used as part of the winning rate, used as a denominator winning rate. Preferably the denominator should be set as 100, 1000, 10,000 such, the winning rate thus calculated will be better calculated.

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()

Run this test method results are as follows:

(10, 100)

We can see that we get a tuple, which is what we take out of the content from the database numerator and denominator.

The method that we will change it in front of the lottery, get into a winning ratio from the database. The modified code as follows:

def lottery():
    rate = get_lottery_rate()
    flag = random.randint(1, rate[1])
    if flag < rate[0]:
        return True
    else:
        return False

Or run the above test methods, here to note down, because we now get data from the database, plus every method execution should establish links with the destruction of the database, it is recommended to modify the number of cycles within 1000, executed on time or else a little too long.

After this small series will modify the 1000 cycles, execution results are as follows:

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

So here, we can modify the data in the database in real-time operation of a winning rate. Of course, the problem of slow above we can use the database connection pool technology optimization.

Increase awards

So whether it is the end of it? no no no, we then add demand.

Now, we can only know in the end is not winning every time, only one award, but now want to become three awards, such as: first prize, second prize, third prize then how to do?

The method for the draw before changes a bit big, first of all let out additional configuration to increase two awards in the database:

Configuring the denominator here three awards had better be consistent, otherwise it will create more complexity in subsequent calculations.

That way we get to modify configuration:

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()

After the test calls the results are as follows:

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

In the first method that we have to do is winning this configuration you want to integrate into our previous in, not say, directly on the code:

# 判断中奖函数
def lottery():
    config = get_lottery_rate()
    flag = random.randint(1, config[0][2])
    if flag <= config[0][1]:
        return 1
    elif flag > config[0][1] and flag <= (config[1][1] + config[0][1]):
        return 2
    elif flag > (config[1][1] + config[0][1]) and flag <= (config[2][1] + config[1][1]):
        return 3
    else:
        return 0

Then do modify our test code:

def main():
    # 一等奖中奖次数
    a = 0
    # 二等奖中奖次数
    b = 0
    # 三等奖中奖次数
    c = 0
    # 未中奖次数
    d = 0
    # 循环次数
    e = 0
    for i in range(1000):
        e += 1
        print('当前循环次数:', e)
        result = lottery()
        print('当前中奖结果:', result)
        if (result == 1):
            a += 1
        elif (result == 2):
            b += 1
        elif (result == 3):
            c += 1
        else:
            d += 1

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

Call our testing methods:

if __name__ == '__main__':
    main()

Xiao Bian here operating results are as follows:

Increase membership judge

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

最终测试结果如下:

小编的人品还可以嘛,直接就能中三等奖。

那么,到这里,是不是一个简易的抽奖程序就算完成了呢?其实还能接着加,如果每个奖项都有数量限制,并且限制的数量是可以随时调整的等等等等,小编这里就不一一列举了。

整体代码写的稍微有些长了,小编就不贴出来了,上传到代码仓库各位感兴趣的同学自己访问吧。

注意: 本篇文章所使用代码,仅供演示讲解使用,不可用于生产环境,在访问量过大的情况下会产生严重的性能问题。

示例代码

示例代码-Github

示例代码-Gitee

Guess you like

Origin www.cnblogs.com/babycomeon/p/12005708.html