练习:仿真模拟福彩双色球——中500w巨奖到底有多难?跑跑代码就晓得了。


Python 官网https://www.python.org/




  自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
            —— 华罗庚


等风来,不如追风去……



福彩双色球,中巨奖到底有多难?
仿真模拟双色球
试试 run 《仿真模拟双色球》代码就晓得了!




目 录

回目录

在这里插入图片描述

  看到这道题目,我生发用 python 循环语句来搞搞我以前喜欢的“双色球”,看看中500w巨奖到底有多难?🤩🤩
  都好久好久没碰“双色球”了,久到都不记得到底多久了。😝😝

搜搜“中奖规则”、“选号规则(点击蓝色文字查看规则详情)了解了解先。


模拟构想

  双色球真实操作是彩民先买彩开奖前先截止购买,封存已成交彩票数据,再行机器摇出中奖号码,再由彩民持票兑奖。
  我的模拟,只好“反行其道”,先随机生成中奖号码(生成方式类似真实机器摇号,目的只验头等巨奖,固蓝号始终只摇一个),再以机选“双色球”号码的方式模拟出票,直到中得500w巨奖。过程中记录所出彩票总数,最后打印输出。正学习 python class ,因而代码用 python 类实现。


回目录


更改构建

  最初设想,仅中得500w大奖才完结程序。太难了,完结不了。得改“兑奖”操作。


    def redeem_ticket(self, target):
        ''' 兑奖 '''

        for i in target:
            if i not in self.target[:-1]:
                return # 遍历红球未中,返回空值 None 。

        if taget[-1] != self.target[-1]:
            return # 蓝球没中,返回空值 None 。
        return True

  修改号码存储结构,代码操作实现更便利。

[[00, 00, 00, 00, 00, 00], 00] -> [00, 00, 00, 00, 00, 00, 00]

  我想实现“双色球”全部六个奖项的统计。最终,得以代码实现:1、字典存储中得奖级。奖级为 key ,累加中奖次数。初始字典为空,用 dict.get(key, 0) ,获取奖级累积的值,设置 get 方法第二参数为 0 ,防止奖级字典中没 key 时报错,同时也解决了初始奖级为 0 的工作。


    def write_lottery(self, flag):
        '''
        单注彩票中奖标识写入奖级存储字典。

        flag,中奖标识,str。 

        '''
        if flag == '61': # 特等奖,七球全中。
            key = 0
        elif flag == '60': # 二等奖,中六红球。
            key = 1
        elif flag == '51': # 三等奖, 中五红球+蓝球。
            key = 2
        elif flag == '50' or flag == '41': # 四等奖, 中五红球或者四红球+蓝球。
            key = 3
        elif flag == '40' or flag == '31': # 五等奖, 中四红球或者三红球+蓝球。
            key = 4
        elif flag == '01': # 六等奖,中蓝球。
            key = 5

        self.lottery[key] = self.lottery.get(key, 0) + 1 # 累加中奖奖级。


回目录


完整代码运行效果

在这里插入图片描述
最初效果


回目录


在这里插入图片描述

优化效果


回目录


在这里插入图片描述

模拟8000注
在这里插入图片描述

在这里插入图片描述

最终效果


回目录


SimulateDualColoredBall 文档


类实例调用


if __name__ == '__main__': # 直接执行本*.py文件,才执行后续语句。
    from mypythontools import inputnum # 载入自制工具:“数字输入”。

    while True:
        num = inputnum('请设置模拟买彩注数(n≥1)') # 调用数字输入工具,设置模拟双色球买票注数。
        if num < 1:
            continue
        break # num 大于等于 1。

    SimulateDualColoredBall(num) # 调用“双色球仿真模拟”,自动执行模拟。


回目录


1、“魔术方法”自主执行(init)

  调用“出票”方法取得一注随机号作为开奖号码,并调用“彩票展示”方法展示。打印最后输出界面“头部”信息。调用“买彩”方法,进行“双色球仿真模拟”。这一切都是一实例类 SimulateDual-coloredBall() 就自主执行的。


    def __init__(self, num):
        ''' 自动启动“魔术方法”,需要自动完成的事儿,都在这里。 

        num, 模拟买彩注数设置,int。
        target,开奖号码,list。
        lottery,中奖记录字典,dict。

        '''
        
        import time # 加载时间模块
        from python_color import color # 加载自制打印颜色控制输出工具。
        from mypythontools import localtime_show # 加载自制当前时间格式化字符串工具。
        self.color = color # 设置本 class 内部全局都能使用 color 。

        self.num = num # 模拟注数变量类内全局设置
        self.target = self.choice_ticket()        
        self.lottery = {} # 初始化中奖字典。

        start_sec = time.time() # 记录程序开始时间。
        print(f"\n\n{localtime_show().center(61, '=')}\n\n{'':>4}开奖号码:")
        self.show_ticket(self.target) # 调用彩票打印方法列印开奖号码。
        print() # 打印空行。
        self.buy_ticket() # 调用方法模拟买票。
        print(f" 用时 {self.color(f'{time.time()-start_sec:.2f}', 'f_green')} 秒。".center(55, '='))
        print('\n'*2) # 打印空行。


回目录


2、“双色球”仿真模拟——出票兑奖中得奖级记录

  用 for 循环进行“出票示票、[兑奖(#redeem_ticket)]”、记录中得奖级操作,直到完成设置的彩票注数。


    def buy_ticket(self):
        ''' 循环模拟出票、兑奖,并统计中奖奖级,直到完成设定购买彩票数量。'''
        print(f"{'-'*50}\n\n\n{self.color(' 正在模拟“双色球” …… ', 'f_green').center(52)}\n\n")

        for n in range(1, self.num+1): # 模拟设定买票注数。
            ticket = self.choice_ticket() # 调用出票方法机选一注单注(6红+1蓝)。
            self.show_ticket(ticket) # 调用方法打印彩票号码。
            self.redeem_ticket(ticket) # 调用兑奖方法兑奖。

        self.show_lottery() # 调用方法打印中奖状况。


出票


    def choice_ticket(self):
        '''
        摇号(出票),每次一组单注(6红+1蓝)

        red_ball, 红球预选号列表 01~33 , list。
        blue_ball, 蓝球预选号列表 01~16 , list。
        target,单注彩票号码列表, list。

        '''
        from random import choice, shuffle # 加载随机选择、随机洗牌方法。

        red_ball = list(range(1, 34))
        blue_ball = list(range(1, 17))
        target = [] # 初始单注彩票号码存储列表。
        for i in range(6): # 每次一个机选6个红球。
            shuffle(red_ball) # 随机“洗牌”备选红球。
            target.append(choice(red_ball))

        shuffle(blue_ball) # 随机“洗牌”备选蓝球。
        target.append(choice(blue_ball)) # 机选蓝球1。
        return target # 返回单注彩票号码列表(前6红,末尾蓝)。


单注彩票展示


    def show_ticket(self, ticket):
        '''
        彩票号码列印

        ticket,单注彩票号码列表,list。

        '''        
        ticket_str = ' '.join([f"{i:02d}" for i in ticket]) # 格式化彩票号码字符串(每个号码占两个字位符,相邻间1半角空格,也就是英文空格。)
        print(f"{self.color(ticket_str[:-3], 'f_red')} {self.color(ticket_str[-2:], 'f_blue')}".center(68), end='\r') # 加色回车不换行打印号码字符串,'\r' 。


回目录


兑奖


    def redeem_ticket(self, target):
        '''
        兑奖

        red, blue 红蓝球中奖数量,int。
        flag 单注彩票中奖标识,str。

        '''
        red, blue = 0, 0
        
        for i in target[:-1]: # 红球兑奖。
            if i in self.target[:-1]:
                red += 1 # 记录红球中奖个数。

        if target[-1] == self.target[-1]: # 蓝球兑奖。
            blue += 1
        
        flag = ''.join([str(red), str(blue)])
        if flag in ('61', '60', '50', '41', '40', '31', '01'): # 中奖标识在中奖标识列表中,记录中奖奖级。
            self.write_lottery(flag) # 调用方法写入奖级。


打印模拟中奖状况

  打印本次仿真模拟双色球中奖情况:各奖级获奖个数。最后加入了低等奖(除特等奖、二等奖外)总金额统计输出。


        sum_money = (3000*self.lottery.get(2, 0)
        	         + 200*self.lottery.get(3, 0)
        	         + 10*self.lottery.get(4, 0)
        	         + 5*self.lottery.get(5, 0))

        if sum_money <= 10000:
            sum_money_str = ' 低等奖(除特等奖、二等奖外)奖金总额 ' + self.color(f"¥{sum_money}", 'f_green') + ' 元'
        else:
            sum_money_str = ' 低等奖(除特等奖、二等奖外)奖金总额 ' + self.color(f"¥{sum_money/10000:.2f}w", 'f_green') + ' 元'

        print(f"{sum_money_str.center(40, '~')}\n\n") # 打印本次仿真模拟中得低等奖奖金总额。

“模拟中奖情况打印”完整代码


    def show_lottery(self):
        '''
        打印中奖状况:从奖级字典读取并格式输出所有信息。
        (最后一行奖级字典整个输出,可选。勿需列印,在行首加“#”就好)
        '''
        from os import system # 加载机器操作系统命令容器。
        system('clear') # linux 清屏。

        if self.num > 10000:
            num = f"{self.num/10000}w"
        else:
            num = str(self.num)

        print(f"\n\n{self.localtime_show().center(61, '=')}")
        print(f"\n\n{'':>6}模拟购买“双色球” {self.color(num, 'f_green')} 注,共中奖 {self.color(str(sum(self.lottery.values())), 'f_green')} 注。\n{self.color('~'*50, 'f_green')}\n\n")
        print(f"{'':>16}特等奖:{self.color(str(self.lottery.get(0, 0)), 'f_red'):>15} 注")
        print(f"{'':>16}二等奖:{self.color(str(self.lottery.get(1, 0)), 'f_yellow'):>15} 注")
        print(f"{'':>16}三等奖:{self.color(str(self.lottery.get(2, 0)), 'f_green'):>15} 注")
        print(f"{'':>16}四等奖:{self.color(str(self.lottery.get(3, 0)), 'f_blue'):>15} 注")
        print(f"{'':>16}五等奖:{self.color(str(self.lottery.get(4, 0)), 'f_gray'):>15} 注")
        print(f"{'':>16}六等奖:{self.color(str(self.lottery.get(5, 0)), 'f_gray'):>15} 注\n\n")
        sum_money = (3000*self.lottery.get(2, 0)
        	         + 200*self.lottery.get(3, 0)
        	         + 10*self.lottery.get(4, 0)
        	         + 5*self.lottery.get(5, 0))

        if sum_money <= 10000:
            sum_money_str = ' 低等奖(除特等奖、二等奖外)奖金总额 ' + self.color(f"¥{sum_money}", 'f_green') + ' 元'
        else:
            sum_money_str = ' 低等奖(除特等奖、二等奖外)奖金总额 ' + self.color(f"¥{sum_money/10000:.2f}w", 'f_green') + ' 元'

        print(f"{sum_money_str.center(40, '~')}\n\n") # 打印本次仿真模拟中得低等奖奖金总额。
        #print(f"{' 中奖奖级存储字典 '.center(42, '~')}\n{self.color(self.lottery, 'f_green').center(59)}\n\n") # 打印中奖级存储字典。


回首页


中奖规则:
  双色球中奖规则及奖金分别是:一等奖中奖规则为6+1全中,单注奖金最高限额封顶500万元。二等奖中奖规则为6+0,奖金总额为当期高等奖奖金的30%。三等奖中奖规则是5+1,单注奖金固定为3000元。四等奖中奖规则是5+0或者4+1,单注奖金固定为200元。


选号规则:
  双色球投注区分为红色球号码区和蓝色球号码区,红色球号码区由1-33共三十三个号码组成,蓝色球号码区由1-16共十六个号码组成。投注时选择6个红色球号码和1个蓝色球号码组成一注进行单式投注,每注金额人民币2元。
  购买者可选择胆拖投注。胆拖投注是指选择少于单式投注号码个数的号码作为每注都有的号码作为胆码,再选取除胆码以外的号码作为拖码,由胆码和拖码组合成多注投注。



练习源码

  本练习完整源码有些“篇幅”,不宜在此展示。已打包(连同用到的自制工具模块)上传在“我的资源”:https://download.csdn.net/download/m0_57158496/85738693


回首页


My Up and Down
__上一篇:__ 单词记忆系统一:菜单循环和菜单确认(Python 自定义类、自定义模块的相对路径import)

__下一篇:__ “语法糖”——我的编程新知

我的HOT博:
推荐条件 点阅破千

回目录


老齐漫画头像

精品文章:

来源:老齐教室


回目录

Python 入门指南【Python 3.6.3】

好文力荐:

CSDN实用技巧博文:


  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦幻精灵_cq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值