From f7a57d8087c336c48648c9d23a2765d1d201371f Mon Sep 17 00:00:00 2001 From: Peter Norvig Date: Sun, 31 Mar 2019 16:48:23 -0700 Subject: [PATCH] Add files via upload --- ipynb/Dice Baseball.ipynb | 80 ++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/ipynb/Dice Baseball.ipynb b/ipynb/Dice Baseball.ipynb index a4fdc9b..0442dca 100644 --- a/ipynb/Dice Baseball.ipynb +++ b/ipynb/Dice Baseball.ipynb @@ -27,7 +27,8 @@ "- I'll keep track of runners with a list of occupied bases; `runners = [1, 2]` means runners on first and second.\n", "- A runner who advances to base 4 or higher has scored a run (unless there are already 3 outs).\n", "- The function `inning` simulates a half inning and returns the number of runs scored.\n", - "- I'll run the simulation 1 million times and store the resulting scores in `innings`.\n", + "- I want to be able to test `inning` by feeding it specific events, and I also want to generate many innings worth of random events. So I'll make the interface be that I pass in an iterator of events.\n", + "- I'll random simulate 1 million innings and store the resulting scores in `innings`.\n", "- To simulate a game I just sample 9 elements of `innings` and sum them." ] }, @@ -48,14 +49,18 @@ "metadata": {}, "outputs": [], "source": [ - "def inning(events='2111111EEBBOOooooooofffffD334', strikes=7, verbose=False) -> int:\n", - " \"Simulate a random inning and return number of runs scored.\"\n", - " n = len(events) + strikes # With 2 dice, n = 36\n", - " PK = (strikes / n) ** 3 # The probability of a strikeout\n", - " outs = runs = 0 # Inning starts with no outs and no runs,\n", - " runners = [] # ... and with nobody on base\n", + "def our_national_ball_game():\n", + " \"An iterator of events sampled from the odds specified in `Our National Ball Game`.\"\n", + " events = '2111111EEBBOOooooooofffffD334'\n", " while True:\n", - " x = 'K' if random.random() <= PK else random.choice(events)\n", + " yield 'K' if random.random() < (7 / 36) ** 3 else random.choice(events)\n", + "\n", + "def inning(events=our_national_ball_game(), verbose=False) -> int:\n", + " \"Simulate a half inning based on events, and return number of runs scored.\"\n", + " outs = runs = 0 # Inning starts with no outs and no runs,\n", + " runners = [] # ... and with nobody on base\n", + " while True:\n", + " x = next(events)\n", " if verbose: print(f'outs: {outs}, runs: {runs}, runners: {runners}, event: {x}')\n", " if x in 'KODof': # strikeout, foul out, double play, out at first, fly out, \n", " outs += 1 # Batter is out\n", @@ -98,19 +103,18 @@ "name": "stdout", "output_type": "stream", "text": [ - "outs: 0, runs: 0, runners: [], event: O\n", - "outs: 1, runs: 0, runners: [], event: 1\n", + "outs: 0, runs: 0, runners: [], event: f\n", + "outs: 1, runs: 0, runners: [], event: B\n", "outs: 1, runs: 0, runners: [1], event: o\n", - "outs: 2, runs: 0, runners: [2], event: B\n", - "outs: 2, runs: 0, runners: [2, 1], event: 3\n", - "outs: 2, runs: 2, runners: [3], event: E\n", - "outs: 2, runs: 3, runners: [1], event: f\n" + "outs: 2, runs: 0, runners: [2], event: 1\n", + "outs: 2, runs: 1, runners: [1], event: 2\n", + "outs: 2, runs: 1, runners: [3, 2], event: o\n" ] }, { "data": { "text/plain": [ - "3" + "1" ] }, "execution_count": 3, @@ -132,17 +136,16 @@ "output_type": "stream", "text": [ "outs: 0, runs: 0, runners: [], event: 3\n", - "outs: 0, runs: 0, runners: [3], event: 1\n", - "outs: 0, runs: 1, runners: [1], event: 2\n", - "outs: 0, runs: 1, runners: [3, 2], event: D\n", - "outs: 1, runs: 1, runners: [3, 2], event: f\n", - "outs: 2, runs: 2, runners: [2], event: o\n" + "outs: 0, runs: 0, runners: [3], event: o\n", + "outs: 1, runs: 1, runners: [], event: O\n", + "outs: 2, runs: 1, runners: [], event: B\n", + "outs: 2, runs: 1, runners: [1], event: o\n" ] }, { "data": { "text/plain": [ - "2" + "1" ] }, "execution_count": 4, @@ -154,6 +157,13 @@ "inning(verbose=True)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we can feed in any events we want to test the code:" + ] + }, { "cell_type": "code", "execution_count": 5, @@ -163,25 +173,19 @@ "name": "stdout", "output_type": "stream", "text": [ - "outs: 0, runs: 0, runners: [], event: 4\n", - "outs: 0, runs: 1, runners: [], event: 1\n", - "outs: 0, runs: 1, runners: [1], event: B\n", - "outs: 0, runs: 1, runners: [2, 1], event: 1\n", - "outs: 0, runs: 2, runners: [2, 1], event: f\n", - "outs: 1, runs: 2, runners: [2, 1], event: 2\n", - "outs: 1, runs: 3, runners: [3, 2], event: 3\n", - "outs: 1, runs: 5, runners: [3], event: B\n", - "outs: 1, runs: 5, runners: [3, 1], event: B\n", - "outs: 1, runs: 5, runners: [3, 2, 1], event: 1\n", - "outs: 1, runs: 7, runners: [2, 1], event: 1\n", - "outs: 1, runs: 8, runners: [2, 1], event: o\n", - "outs: 2, runs: 8, runners: [3, 2], event: o\n" + "outs: 0, runs: 0, runners: [], event: 2\n", + "outs: 0, runs: 0, runners: [2], event: E\n", + "outs: 0, runs: 0, runners: [3, 1], event: B\n", + "outs: 0, runs: 0, runners: [3, 2, 1], event: D\n", + "outs: 2, runs: 1, runners: [3], event: 1\n", + "outs: 2, runs: 2, runners: [1], event: 2\n", + "outs: 2, runs: 2, runners: [3, 2], event: f\n" ] }, { "data": { "text/plain": [ - "8" + "2" ] }, "execution_count": 5, @@ -190,7 +194,7 @@ } ], "source": [ - "inning(verbose=True)" + "inning(iter('2EBD12f'), verbose=True)" ] }, { @@ -228,7 +232,7 @@ { "data": { "text/plain": [ - "14.457532" + "14.462798" ] }, "execution_count": 7, @@ -237,7 +241,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ]