經過二分查找實現抽獎活動

1、項目背景前端

最近開始找工做了,從新梳理一下以前作的抽獎活動項目;
1、 後臺設置好獎品信息以及獎品機率;
二、 而後對獎品進行排序,好比獎品1:'電動車'  34 獎品2:'毛巾一條', 18,獎品3:'麪粉一袋', 20 獎品4:'肥皂一塊', 12   獎品5:'自行車', 15 獎品6: '奔馳車', 1
3、 按照獎品1  獎品2  獎品3  獎品4  獎品5 獎品6 這種順序進行依次入庫,這樣是保證前端生成抽獎頁面時,獎品是按照咱們的獎品順序進行順時針填充信息;
四、 當前端抽獎頁面抽獎按鈕時,異步請求後端獲取到獎品,而後進行頁面展現;

2、後端功能代碼python

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:supery

import bisect, random
class WeightRandom:
    def __init__(self, items):
        print('數據庫取出的格式化的獎品信息:', items)
        items.sort(key=self.prize_sort)
        print('快排以後的獎品信息: ', items)
        weights = [w for _, w in items]
        print('機率做爲權重:',weights)
        self.prize = [x for x, _ in items]
        self.total = sum(weights)
        self.acc = list(self.accumulate(weights))

    def accumulate(self, weights):  # 累和.如accumulate([10,40,50])->[10,50,100]
        cur = 0
        for w in weights:
            cur = cur + w
            print('累加:',cur)
            yield cur

    def prize_sort(self,elem):
        return elem[1]

    def __call__(self):
        rn = random.uniform(0, self.total)
        ran = bisect.bisect_right(self.acc, rn)
        print('隨機生成的浮點數: ',rn,)
        print('索引位置: ',ran,)
        return self.prize[ran]

def takeSecond(elem):
    return elem[1]



if __name__ == '__main__':
    """
    [
        (獎品, 機率),
        (獎品, 機率),
        (獎品, 機率),
        (獎品, 機率),
    ]
    """

    wr = WeightRandom([
        ('電動車', 34),
        ('毛巾一條', 18),
        ('麪粉一袋', 20),
        ('肥皂一塊',12 ),
        ('自行車', 15),
        ('奔馳車', 1),
    ])
    print('累加以後的權重列表: ',wr.acc)
    print('權重對應的獎品信息: ',wr.prize)
    print('得到的獎品獲獎: 【%s】'%wr.__call__())

3、執行結果數據庫

C:\Python3\python.exe D:/xxx.py
數據庫取出的格式化的獎品信息: [('電動車', 34), ('毛巾一條', 18), ('麪粉一袋', 20), ('肥皂一塊', 12), ('自行車', 15), ('奔馳車', 1)]
快排以後的獎品信息:  [('奔馳車', 1), ('肥皂一塊', 12), ('自行車', 15), ('毛巾一條', 18), ('麪粉一袋', 20), ('電動車', 34)]
機率做爲權重: [1, 12, 15, 18, 20, 34]
累加: 1
累加: 13
累加: 28
累加: 46
累加: 66
累加: 100
累加以後的權重列表:  [1, 13, 28, 46, 66, 100]
權重對應的獎品信息:  ['奔馳車', '肥皂一塊', '自行車', '毛巾一條', '麪粉一袋', '電動車']
隨機生成的浮點數:  88.83932955637896
索引位置:  5
得到的獎品獲獎: 【電動車】

Process finished with exit code 0

 

4、代碼說明後端

1. 首先從數據庫獲取到該活動的全部獎品信息,將獎品名稱做爲元組一個元素,獎勵機率做爲元組第二個元素;
2. 以後經過sort進行元組排序,從小到大進行排序,這樣後續進行累加權重獎品機率最小的必定是在第一位,機率越大的獎品排列越靠後;
3. 經過列表表達式,分別獲取到獎品名稱和獎品機率,生成獎品列表和權重列表;
4. 經過迭代器累和將獎品的機率進行累加生成一個列表,默認值爲0 好比accumulate([10,40,50])->[10,50,100]  0+10=10  10+40=50 50+50=100
   這樣是保證隨機生成一個浮點數時必定是在權限累和列表中;
5. 而後經過random uniform方法隨機生成一個浮點數,範圍是0~100隨機不包含100
6. 最後經過二分查找將將累和列表做爲查詢列表,浮點數做爲比較的值,從右往左依次進行比較,浮點數小於右側的數值時則返回其索引位置;
7. 獲取到索引在獎品列表中進行查找獎品名稱,整個抽獎過程完成!
相關文章
相關標籤/搜索