同じ問題でも、今ではたくさんの質問があることは知っていますが、少し違うアプローチを試みたと思います。
タスクは、100フリップのサンプルを10.000にして、すべてのサンプルにわたって6xのヘッドまたはテールのストリークの確率を計算することです(私が理解している限り)。しかし、以前の質問では、コーディングの問題は少しあいまいであると説明されていました。したがって、コード内のエラーを指摘するだけでいいのであれば、それは素晴らしいことです:)
私はできるかぎり怠惰にしようとしました。その結果、私のMacbookは本当に一生懸命働いていました。これは私のコードです。現在の値と前の値の比較の最初の反復で問題がありますか(私が理解している限り、インデックス-1(インデックス100)と現在の値を比較しますか?)
import random
#variable declaration
numberOfStreaks = 0
CoinFlip = []
streak = 0
for experimentNumber in range(10000):
# Code that creates a list of 100 'heads' or 'tails' values.
for i in range(100):
CoinFlip.append(random.randint(0,1))
#does not matter if it is 0 or 1, H or T, peas or lentils. I am going to check if there is multiple 0 or 1 in a row
# Code that checks if there is a streak of 6 heads or tails in a row.
for i in range(len(CoinFlip)):
if CoinFlip[i] == CoinFlip[i-1]: #checks if current list item is the same as before
streak += 1
else:
streak = 0
if streak == 6:
numberOfStreaks += 1
print('Chance of streak: %s%%' % (numberOfStreaks / 100))
どこで混乱を起こしましたか?本当に見えない!
以下は、推定値を正しく計算する、最初に提供されたコードへのマイナーな変更のセットです。
_####
_で始まるコメントを使用して変更をマークし、以下の説明を参照してそれらに番号を付けました。
_import random
#variable declaration
numberOfStreaks = 0
for experimentNumber in range(10000):
# Code that creates a list of 100 'heads' or 'tails' values.
CoinFlip = [] #### (1) create a new, empty list for this list of 100
for i in range(100):
CoinFlip.append(random.randint(0,1))
#does not matter if it is 0 or 1, H or T, peas or lentils. I am going to check if there is multiple 0 or 1 in a row
#### # (6) example / test
#### # if uncommented should be 100%
#### CoinFlip = [ 'H', 'H', 'H', 'H', 'H', 'H', 'T', 'T', 'T', 'T', 'T', 'T' ]
# Code that checks if there is a streak of 6 heads or tails in a row.
streak = 1 #### (2, 4) any flip is a streak of (at least) 1; reset for next check
for i in range(1, len(CoinFlip)): #### (3) start at the second flip, as we will look back 1
if CoinFlip[i] == CoinFlip[i-1]: #checks if current list item is the same as before
streak += 1
else:
streak = 1 #### (2) any flip is a streak of (at least) 1
if streak == 6:
numberOfStreaks += 1
break #### (5) we've found a streak in this CoinFlip list, skip to next experiment
#### if we don't, we get percentages above 100, e.g. the example / test above
#### this makes some sense, but is likely not what the book's author intends
print('Chance of streak: %s%%' % (numberOfStreaks / 100.0))
_
これらの変更点の説明
以下は、これらの変更の簡単な説明です。それぞれがほぼ独立しており、コードの異なる問題を修正しています。
'H'
_または_'T'
_(または_1
_または_0
_)であっても、フリップが1 のストリークを表すことの確認if streak == 6:
_を_if streak == 5:
_で置き換えることです)range(1, len(CoinFlip))
を使用して2番目のフリップからチェックを開始します(n.b.リストにはゼロからインデックスが付けられます)range()
を含むfor
ループは、インデックス_0
_をインデックス_-1
_と誤って比較します( リストの最後の要素 )streak
カウンターをリセットします本のこの質問はやや不十分に指定されており、最後の部分は「--[少なくとも?]かどうかを確認する[single?]ストリークのいずれかを意味すると解釈できます- [precisely?] 6 [or more?]が見つかりました "。このソリューションはcheckをブール評価として解釈し(つまり、このリストにストリークが含まれていたか含まれていないことのみを記録し)、aを非排他的に解釈します(つまり、長い縞または複数の縞を数える;質問で提供されたコードでそうだったように)。
(オプション6.)コードのテスト
コメントアウトされた「例/テスト」を使用すると、通常ランダムに生成されるフリップを、すべての実験で同じ既知の値に切り替えることができます。この場合、100%として計算される固定リスト。タスク仕様の解釈に同意せず、(5。)で説明されているチェックの終了を無効にすると、すべての実験で6つの2つの異なる縞があるので、プログラムは200%を報告すると期待できます。この入力と組み合わせてbreak
を無効にすると、それが正確に報告されます。
このタイプの手法(既知の入力を使用し、出力を確認する)を常に使用して、コードが主張どおりまたは期待どおりに機能するか機能しないかを納得させる必要があります。
固定入力_CoinFlip = [ 'H', 'H', 'H', 'H', 'T', 'T', 'T' ]
_を使用して、(4。)で修正された問題を強調表示できます。元に戻すと、コードは6つの連続するH
またはT
のストリークを含む実験(すべてこの入力を使用)の割合を50%として計算します。 (5.)は独立した問題を修正しますが、追加されたbreak
を削除すると、エラーがさらに悪化し、計算されたパーセンテージが99.99%に上がります。この入力の場合、ストリーク6を含む計算されたパーセンテージは0%になります。
ここに提供されているように、完全なコードは約80%の推定値を生成します。これは意外かもしれませんが、 book の作成者は、これが事実である可能性があることを示唆しています。
本当にランダムなコインフリップで発生する可能性が非常に高いとしても、人間は6つの頭または6つの尾の連続をほとんど書きません。
-Al Sweigart、 Coin Flip Streaks
追加のソースを検討することもできます。 WolframAlpha は、「100枚のコインフリップで6頭の連なり」が発生する可能性がおよそ1 in 2であることを計算します。ここでは、6(以上)の頭のストリークor 6(以上)の尾のストリークが発生する可能性を推定しています。あなたはさらに可能性が高いと期待することができます。この累積的な効果のより簡単で独立した例として、通常のトランプのパックからハートを選ぶ確率は52分の13ですが、ハートを選ぶorダイヤモンドは52分の26になると考えてください。 。
計算上の注意
また、作者がパーセンテージの計算に近道を取っていることを理解するのにも役立ちます。これは、初心者が最終的な計算を見るのを混乱させるかもしれません。
パーセントが計算されます:
total実行する実験の数は10000になることがわかっています
したがって
Postscript:最後の行で_100
_を_100.0
_に変更する自由をとった。これにより、コードはPython 2でパーセンテージを正しく計算できます。これは、質問と本で指定されているPython 3では必要ありません。
私のアマチュアの試み
import random
#reset strakes
numberOfStreaks = 0
#main loop
for experimentNumber in range(10000):
# Code that creates a list of 100 'heads' or 'tails' values.
# assure the list is empty and all counters are 0
coinFlip=[]
H=0
T=0
for fata in range(100):
# generate random numbers for head / tails
fata = random.randint(0,1)
#if head, append 1 head and reset counter for tail
if fata == 0:
coinFlip.append('H')
H += 1
T = 0
#else if tail append 1 tail and reset counter for head
Elif fata == 1:
coinFlip.append('T')
T += 1
H = 0
# Code that checks if there is a streak of 6 heads or tails in a row.
# when head and tail higher than 6 extract floored quotient and append it to numberOfStreaks,
# this should take into consideration multiple streaks in a row.
if H > 5 or T > 5:
numberOfStreaks += (H // 6) or (T // 6)
print('Chance of streak: %s%%' % (numberOfStreaks / 100))
出力:
Chance of streak: 3.18%
import random
numStreaks = 0
test = 0
flip = []
#running the experiment 10000 times
for exp in range(10000):
for i in range(100): #list of 100 random heads/tails
if random.randint(0,1) == 0:
flip.append('H')
else:
flip.append('T')
for j in range(100): #checking for streaks of 6 heads/tails
if flip[j:j+6] == ['H','H','H','H','H','H']:
numStreaks += 1
Elif flip[j:j+6] == ['T','T','T','T','T','T']:
numStreaks += 1
else:
test += 1 #just to test the prog
continue
print (test)
chance = numStreaks / 10000
print("chance of streaks of 6: %s %%" % chance )