Python 官网:https://www.python.org/
-
Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单……
- My CSDN主页、My HOT博、My Python 学习个人备忘录
- 好文力荐、 老齐教室
自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
—— 华罗庚
- 1、最初构想
- 2、更改构想
- 3、完整代码运行效果
- a. 最初效果
- b. 初步优化效果
- c. 最终效果
- 4、仿真模拟类 SimulateDualColorBall 说明文档
- a. “魔术方法”自主执行(init)——在这里设置模拟购买注数
- b. 仿真模拟购票
- c. 机选单注彩票
- d. 单注号码展示
- e. 单注模拟兑奖
- f. 中得奖级累加
- g. 完成模拟,输出本次中奖状况
- 5、本练习完整源码(含所有用到的自制工具模块)
看到这道题目,我生发用 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 = 0elif flag == '60': # 二等奖,中六红球。key = 1elif flag == '51': # 三等奖, 中五红球+蓝球。key = 2elif flag == '50' or flag == '41': # 四等奖, 中五红球或者四红球+蓝球。key = 3elif flag == '40' or flag == '31': # 五等奖, 中四红球或者三红球+蓝球。key = 4elif flag == '01': # 六等奖,中蓝球。key = 5self.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:continuebreak # 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, 0for i in target[:-1]: # 红球兑奖。if i in self.target[:-1]:red += 1 # 记录红球中奖个数。if target[-1] == self.target[-1]: # 蓝球兑奖。blue += 1flag = ''.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博:
- 练习:银行复利计算(用 for 循环解一道初中小题)(1043阅读)
- pandas 数据类型之 DataFrame(1267阅读)
- 班里有人和我同生日难吗?(概率probability、蒙特卡洛随机模拟法)(2069阅读)
- Python字符串居中显示(1416阅读)
- 练习:求偶数和、阈值分割和求差( list 对象的两个基础小题)(1634阅读)
- 用 pandas 解一道小题(1957阅读)
- 可迭代对象和四个函数(1062阅读)
- “快乐数”判断(1225阅读)
- 罗马数字转换器(构造元素取模)(1923阅读)
- Hot:罗马数字(转换器|罗生成器)(3453阅读)
- Hot:让QQ群昵称色变的代码(25567阅读)
- Hot:斐波那契数列(递归| for )(3981阅读)
- 柱状图中最大矩形(1639阅读)
- 排序数组元素的重复起止(1232阅读)
- 电话拨号键盘字母组合(1338阅读)
- 密码强度检测器(1785阅读)
- 求列表平衡点(1806阅读)
- Hot: 字符串统计(4227阅读)
- Hot:尼姆游戏(聪明版首发)(3406阅读)尼姆游戏(优化版)(977阅读)
推荐条件 点阅破千
精品文章:
- 好文力荐:《python 完全自学教程》齐伟书稿免费连载
- OPP三大特性:封装中的property
- 通过内置对象理解python'
- 正则表达式
- python中“*”的作用
- Python 完全自学手册
- 海象运算符
- Python中的 `!=`与`is not`不同
- 学习编程的正确方法
来源:老齐教室
Python 入门指南【Python 3.6.3】
好文力荐:
-
全栈领域优质创作者——寒佬(还是国内某高校学生)好文:《非技术文—关于英语和如何正确的提问》,“英语”和“会提问”是学习的两大利器。
-
【8大编程语言的适用领域】先别着急选语言学编程,先看它们能干嘛
-
靠谱程序员的好习惯
CSDN实用技巧博文:
- 8个好用到爆的Python实用技巧
- python忽略警告
- Python代码编写规范
- Python的docstring规范(说明文档的规范写法)