《Python编程快速上手——让繁琐工作自动化 第2版》
4.11 实践项目
4.11.2 掷硬币的连胜
如果你掷硬币一百次,并在每次正面时写下“H”,在每次反面时写下“T”,就会创建一个看起来像“T T T T T H H H H T T ”这样的列表。编写一个程序,查找随机生成的正面和反面列表中连续出现6个正面或6个反面的频率。你的程序将实验分为两部分:第一部分生成随机选择的“正面”和“反面”值的列表,第二部分检查其中是否有连胜。将所有代码放入一个循环中,重复该实验10000次,这样我们就可以找出掷硬币中包含连续六个正面或反面的百分比
运行代码:
import random
repetitionsNumber = 6
completeList = []
completeStringList = []
numberOfStreaks = 0
# 生成值的列表
for experimentNumber in range(10000):
tryList = []
tryString = ''
for try_nums in range(100):
if random.randint(0, 1) == 0:
tryList.append('H')
tryString += 'H'
else:
tryList.append('T')
tryString += 'T'
completeList.append(tryList)
completeStringList.append(tryString)
# 检查是否连胜
if ('H' * repetitionsNumber in tryString) or ('T' * repetitionsNumber in tryString):
numberOfStreaks += 1
print("repetitionsNumber is ", repetitionsNumber)
print("numberOfStreaks is ", numberOfStreaks)
# print("completeList is ",completeList)
print('Chance of streak: %.2f%%' % ((numberOfStreaks / 10000) * 100))
运行结果:
repetitionsNumber is 6
numberOfStreaks is 8116
Chance of streak: 81.16%
题干个人理解:
1.要求保存“正面”和“反面”值的列表
2.检查其中是否有连胜
3.将所有代码放入一个循环中(除了打印)
扩展
修改下方代码中repetitionsNumber的值,可以得到从连续重复1次到连续重复repetitionsNumber次会出现的概率
运行代码:
# 结果关联
import random
repetitionsNumber = 25
completeList = []
completeStringList = []
# 生成值的列表
for experimentNumber in range(10000):
tryList = []
tryString = ''
for try_nums in range(100):
if random.randint(0, 1) == 0:
tryList.append('H')
tryString += 'H'
else:
tryList.append('T')
tryString += 'T'
completeList.append(tryList)
completeStringList.append(tryString)
# 检查是否连胜
for repeatNum in range(1, repetitionsNumber + 1):
numberOfStreaks = 0
for String in completeStringList:
if ('H' * repeatNum in String) or ('T' * repeatNum in String):
numberOfStreaks += 1
print("repeatNum is ", repeatNum)
print("numberOfStreaks is ", numberOfStreaks)
# print("completeList is ",completeList)
print('Chance of streak: %.2f%%' % ((numberOfStreaks / 10000) * 100))
print()
运行结果(节选):
repeatNum is 4
numberOfStreaks is 9996
Chance of streak: 99.96%
repeatNum is 5
numberOfStreaks is 9688
Chance of streak: 96.88%
repeatNum is 6
numberOfStreaks is 8105
Chance of streak: 81.05%
结果具有关联性,即使用同一套数据,不会出现连续19次的次数比连续出现18次的多的情况
使用numpy验证:
# numpy计算结果,结果独立
import numpy as np
repetitionsNumber = 25
for j in range(1, repetitionsNumber + 1):
NUM_EXER = 10000
count_max = 0
for i in range(NUM_EXER):
L = []
for i in range(100): # throw coins
if np.random.rand() > 0.5:
L.append(1)
else:
L.append(0)
C = []
count = 1
L.append(-1) # sentinel node
for i in range(len(L) - 1):
if L[i + 1] == L[i]:
count += 1
else:
if count > 1:
C.append(count)
count = 1
if np.max(C) >= j:
count_max += 1
print("repetitionsNumber is ", j)
print((count_max / NUM_EXER) * 100, '%')
print()
运行结果(节选):
repetitionsNumber is 4
99.98 %
repetitionsNumber is 5
97.02 %
repetitionsNumber is 6
81.3 %
上述代码结果不具有关联性,即不使用同一套数据,可能会出现连续19次的次数比连续出现18次的多的情况
numpy思路参考:
python数学小实验(5)——掷硬币出现连续正面的概率
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/houhuipeng/article/details/91443188