Как написать простую лотерейную программу на Python

Python

Я не знаю, сколько людей было обмануто этим заголовком :)

Причина этого вот в чем.На прошлой неделе одноклассник попросил редактора.Глядя на образец кода редактора и набирая код я почувствовал что напишу сам.Чтобы написать программу самостоятельно,чувствую что нет способ начать.

На самом деле это вполне нормально. Когда я впервые начал учиться писать код, я следовал чужим процедурам и записывал их. Я читал несколько процедур, и мне было трудно формировать свои собственные процедуры. Это то же самое, что решать математические задачи. ., такая вероятность очень мала, и все они находят свои собственные процедуры в результате большой практики.

Китайский Новый год не за горами, и различные компании будут проводить лотерейные мероприятия. Редактор расскажет об этом сегодня. Если вы хотите написать простую лотерейную программу, как ее написал редактор.

Анализ требований

Давайте сначала разберем наши идеи, какова цель?

Цель состоит в том, чтобы написать лотерейную программу, так что же является ядром лотерейной программы?

Конечно, как судить человека, выигравшего в лотерею. Итак, как узнать, выиграл ли кто-то в лотерею?

Можно ли работать через случайные функции?

Как победить

Шаг за шагом мы сначала используем случайную функцию, чтобы определить, выиграли ли мы в лотерею. Можно ли код написать так:

import random

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

Во-первых, мы получаем случайное положительное целое число от 0 до 9 (здесь не обсуждается, является ли случайное действительно случайным, мы можем считать его случайным в узком смысле), если коэффициент выигрыша составляет 20%, мы можем считать его менее 2 чисел являются выигрышами, остальные не являются выигрышами. Затем верните True после выигрыша в лотерею и верните False, когда лотереи нет.

Давайте добавим функцию входного теста, чтобы проверить, может ли приведенный выше код работать нормально и может ли процент выигрышей поддерживаться на уровне около 20%.

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

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

Результаты:

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

Приведенный выше тест повторяется в общей сложности 1 миллион раз, и его выполнение занимает от 2 до 3 секунд, что довольно быстро. Видно, что выигрышный результат действительно близок примерно к 20%.

Динамический коэффициент выигрыша

Это должно закончиться здесь? Конечно нет, это только начало.

Если босс говорит, что вы не можете настроить эту вероятность, вам нужно сделать так, чтобы коэффициент выигрыша можно было динамически регулировать.Когда событие только начинается, коэффициент выигрыша высок. Со временем коэффициент выигрыша будет падать.

Что делать в это время, ошарашенный.

Так как коэффициент выигрыша должен быть регулируемым, то наш коэффициент выигрыша не может быть зафиксирован в программе.Этот коэффициент выигрыша нужно хранить в каком-то месте, и этот коэффициент выигрыша вынимается каждый раз, когда мы делаем рандом.

Простой и удобный способ — занести коэффициент выигрыша в базу данных или кеш-сервис, который определяется в соответствии с реальным бизнес-сценарием. Как правило, выбор технологии основан на предполагаемом давлении доступа.Если давление не особенно велико, его также можно поместить в базу данных.Если параллелизм будет относительно высоким, рекомендуется поместить его в кеш.

Напишем метод для получения вероятности выигрыша из БД (чтобы показать интуицию, редактор напрямую использует БД Mysql как хранилище данных), сначала посмотрим на данные БД:

Очень просто создать таблицу с двумя значимыми полями: одно используется как часть числителя коэффициента выигрыша, а другое используется как часть знаменателя коэффициента выигрыша. В знаменателе лучше всего ставить 100, 1000, 10000, чтобы расчет выигрышной ставки был лучше.

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

Результаты тестирования этого метода следующие:

(10, 100)

Как видите, мы получаем кортеж с числителем и знаменателем, которые мы получили из базы данных.

Давайте изменим предыдущий метод лотереи, чтобы получить процент выигрыша из базы данных. Модифицированный код выглядит следующим образом:

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

Либо запустите вышеуказанный тестовый метод, обратите внимание, так как мы сейчас получаем данные из базы данных, и к каждому выполнению метода необходимо добавить установление и уничтожение связи с базой данных, рекомендуется изменить количество циклов в пределах 1000. , иначе время выполнения будет слишком большим.

После изменения количества циклов до 1000 раз результаты выполнения следующие:

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

Итак, здесь мы можем управлять коэффициентом выигрыша в режиме реального времени, изменяя данные в базе данных. Конечно, описанную выше проблему медленной работы можно оптимизировать с помощью таких технологий, как объединение соединений с базой данных.

добавить награды

Так все кончено? нет нет нет, давайте добавим требования.

Теперь мы можем только знать, выигрываем ли мы в лотерею каждый раз, есть только одна награда, но теперь мы хотим превратиться в 3 награды, такие как: первый приз, второй приз, третий приз, что нам делать?

Это большое изменение по сравнению с предыдущим методом лотереи Прежде всего, мы сначала добавляем конфигурацию двух других наград в базу данных:

Знаменатели трех наград лучше оставить в одной конфигурации, иначе последующий расчет усложнит.

Измените метод, который мы используем для получения конфигурации:

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, 10, 100), (2, 5, 100), (3, 1, 100))

Прежде всего, что нам нужно сделать, это интегрировать эту конфигурацию в наш предыдущий метод выигрыша, особо не говоря, переходим непосредственно к коду:

# 判断中奖函数
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

Затем измените наш тестовый код:

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)

Назовите наши методы тестирования:

if __name__ == '__main__':
    main()

Результаты операции здесь следующие:

Увеличьте суждение членов

Мы еще не закончили, и мы все еще можем увеличить спрос. Большинство веб-сайтов теперь основаны на членстве, например, участники со статусом Silver, Gold и Diamond. Если для разных уровней членства требуются разные коэффициенты выигрыша, это вполне нормально. 1. Дело в том, что редактор до сих пор хорошо помнит комментарий «бедный VIP (такой, какой дан событием)» в тогдашнем коде крупной интернет-компании.

Мы предполагаем, что коэффициент выигрыша для участников со статусом Diamond составляет 100% от общего коэффициента выигрыша, коэффициент выигрыша для участников уровня Gold составляет 50%, а коэффициент выигрыша для участников уровня Silver составляет 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()

Окончательные результаты испытаний следующие:

С характером редактора все в порядке, и я сразу могу выиграть третий приз.

Итак, на данный момент это простая программа лотереи завершена? На самом деле его можно добавить и дальше.Если каждая награда имеет ограничение по количеству, и лимит можно в любой момент скорректировать и т.д. и т.п., то редактор не будет перечислять их здесь по одной.

В целом код пишется несколько долго, а небольшие серии не выкладываются, а загружаются в репозиторий кода, который вам интересен, учащиеся получают доступ самостоятельно.

Уведомление:Код, используемый в этой статье, предназначен только для демонстрационных целей и не может использоваться в производственной среде, так как в случае чрезмерного трафика возникнут серьезные проблемы с производительностью.

образец кода

Пример кода — Гитхаб

Пример кода — Gitee

Если моя статья была вам полезна, отсканируйте код и подпишитесь на официальный аккаунт автора: Получите последние новости о галантерейных товарах :)