自动化无聊的东西-第4章:抛硬币解决方案



我正在为python编程"自动化无聊的东西"第4章末尾的"抛硬币"实践项目的解决方案而苦苦挣扎。
我有两个解决方案,都产生了完全不同的结果(第一个显然是错误的)。我不确定,什么才是正确的答案。

解决方案1:

import random
nextFlip = []
numberOfStreaks = 0
# Code that creates a list of 10000 'heads' or 'tails' values.
for expNum in range(10000):                
select = random.randint(0,1)
if select == 0:
nextFlip.append('H')
elif select == 1:
nextFlip.append('T')

# Code that checks if there is a streak of 6 heads or tails in a row.
for i in range(0,(len(nextFlip)-6)):
if nextFlip[i] == nextFlip[i+1] == nextFlip[i+2] == nextFlip[i+3] == nextFlip[i+4] == nextFlip[i+5] != nextFlip[i+6]:
numberOfStreaks +=1

print('Chance of streak: %s%%' % ((numberOfStreaks / 10000)*100)) 

解决方案2:

import random
nextFlip = []
hlist = 0
tlist = 0
numberOfStreaks = 0
# Code that creates a list of 10000 'heads' or 'tails' values.
for expNum in range(10000):                
select = random.randint(0,1)
if select == 0:
nextFlip.append('H')
elif select == 1:
nextFlip.append('T')

# Code that checks if there is a streak of 6 heads or tails in a row.
for i in range(0,(len(nextFlip)-6)):
if nextFlip[i] == 'H':
hlist += 1
if hlist == 6:
numberOfStreaks +=1

elif nextFlip[i] == 'T':
tlist += 1
if tlist == 6:
numberOfStreaks +=1
print('Chance of streak: %s%%' % ((numberOfStreaks / 10000)*100))

也许有人能帮助我,告诉我我做错了什么。

我也在用同一本书学习。我发现它更容易被视为字符串,而不是列表。我认为问题是要求你找出连续6次或更多次正面或连续6次或更多次反面是否在投掷100次硬币中出现。对于每100次投掷,结果是0或1(我不认为你计算多次连胜)。10,000次运行是为了获得合理的精度并避免抽样误差。

import random
number_of_streaks = 0
for experiment_number in range(10000):

# Code that creates a list of 100 'heads' or 'tails' values
coin_list = ''
for i in range(100):
if random.randint(0, 1) == 0:
coin_list = coin_list + 'H' # heads
else:
coin_list = coin_list + 'T' # tails

# Code that checks if there is a streak of 6 heads or tails in a row
if 'HHHHHH' in coin_list or 'TTTTTT' in coin_list:
number_of_streaks +=1
print('Chance of streak: %s%%' % (number_of_streaks / 100))

进一步建议在评论@rchome,我添加了一个简单的计时器到这个原始代码(https://stackoverflow.com/a/1557584/17555691),它给出了以下响应:

连染几率:80.06%——0.8480644226074219秒——

接下来,我做了一个小的改变,使用append到一个列表,然后转换成一个字符串:

# Code that creates a list of 100 'heads' or 'tails' values
coin_list = []
for i in range(100):
if random.randint(0, 1) == 0:
coin_list.append('H') # heads
else:
coin_list.append('T') # tails
# Code that checks if there is a streak of 6 heads or tails in a row
coin_string = ''.join(coin_list)
if 'HHHHHH' in coin_string or 'TTTTTT' in coin_string:
number_of_streaks +=1

此版本的输出:

连胜几率:80.26%——0.739051342010498秒——

然后使用@Alain T: 的建议进行了更改。
# Code that creates a list of 100 'heads' or 'tails' values
flips   = "".join(random.choice('HT') for _ in range(100))
# Code that checks if there is a streak of 6 heads or tails in a row
if 'HHHHHH' in flips or 'TTTTTT' in flips:
number_of_streaks +=1

这个版本的输出:连胜几率:80.74%——0.4248924255371094秒——

上述结果在重复执行时非常典型。

这似乎可行:-

import random
N = 10_000
S = 6
HEAD = 'H'
TAIL = 'T'
T = [HEAD if random.randint(0, 1) else TAIL for _ in range(N)]
c = T[0]
s = 1
STREAKS = 0
for t in T[1:]:
if t == c:
s += 1
if s == S:
STREAKS += 1
s = 0
else:
c = t
s = 1
print(STREAKS)

您可以使用推导式生成随机翻转,并将其存储在字符串中,以使条纹的处理更容易。由于条纹可以重叠,您需要检查从每个位置开始的子区域:

flips   = "".join(random.choice("HT") for _ in range(1000))
streaks = sum(flips[i:i+6] in ('HHHHHH','TTTTTT') for i in range(1000))

sum()函数将布尔值转换为1或0 (True为1),因此将条纹条件的结果相加产生总数。

#Defining Inputs and importing modules
import random
numberOfStreaks = 0
mylist=[]
countH=0
countT=0
conuterTail=[]
conuterHead=[]
for experimentNumber in range(10000):
# Code that creates a list of 10000 'heads' or 'tails' values.
rndnum=random.randint(0,1);
if rndnum==0:
countH=0 # if the random number is "0" then "HEAD" counts will be reset
mylist.append(['T'])
countT+=1
else:
countT=0 # if the random number is "1" then "TAIL" counts will be reset
mylist.append(['H'])
countH+=1
# Code that checks if there is a streak of 6 heads or tails in a row.
if countT==6:
conuterTail.append(countT)
elif  countH==6:
conuterHead.append(countH);

numberOfStreaks=len(conuterHead)+len(conuterTail)
print('Chance of streak: %s%%' % (numberOfStreaks / 100))

我理解这个问题是在问:有多大的机会连续6次像扔硬币一样被控制住在100次随机抛硬币的范围内。我认为这应该包括在同一组抛球中出现多个连投的实例。每当连续值达到6时,计数为重置为零,以便捕捉下一个连胜。一些迭代不包含条纹,而其他包含多条。一个大的对迭代次数进行平均以平滑方差。平均返回值为158-160%,表示非常可能。

import random
numberOfStreaks = 0
countH = 0
countT = 0
iterations_of_experiment = 10000
for experimentNumber in range(iterations_of_experiment):
#Code that creates a list of 100 'heads' or 'tails' values
setOfHundred = [] #set list to empty each iteration

for i in range(100):
if random.randint(0, 1) == 0:
countT = 0  #Set Tails count to zero on head flip
setOfHundred.append('H')
countH += 1
if countH == 6:
numberOfStreaks += 1
countH = 0 #Reset counter to zero to capture -
else:              #multiple streaks
countH = 0
setOfHundred.append('T')
countT += 1
if countT == 6: 
numberOfStreaks += 1
countT = 0
print('In ' + str(iterations_of_experiment) + 
' iterations of 100 coin tosses, there were ' + str(numberOfStreaks) + 
' streaks of 6 consecutive like coin flips.')
print('Chance of streak: ' + str(numberOfStreaks / iterations_of_experiment * 100) + '%')

最新更新