From 4254e304269930f607c40db4ca9775b571dc5a7d Mon Sep 17 00:00:00 2001 From: Naveen M V Date: Mon, 17 Feb 2020 05:31:47 +0530 Subject: [PATCH 1/6] Implement basic dice simulation --- maths/monte_carlo_dice.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 maths/monte_carlo_dice.py diff --git a/maths/monte_carlo_dice.py b/maths/monte_carlo_dice.py new file mode 100644 index 000000000000..7d91e2bd4be1 --- /dev/null +++ b/maths/monte_carlo_dice.py @@ -0,0 +1,35 @@ +import random + +""" + +""" + +class Dice(): + NUM_SIDES = 6 + def __init__(self): + self.sides = [] + for i in range(1, 7): + self.sides.append(i) + self.odds = len(self.sides) + + def roll(self): + return random.choice(self.sides) + + def _str_(self): + return 'Fair Dice' + +def play_dice(num_dice, num_rolls): + dices = [Dice() for i in range(num_dice)] + occurrence = [0 for i in range(0, len(dices)*Dice.NUM_SIDES+1)] + + for i in range(num_rolls): + occurrence[sum([dice.roll() for dice in dices])] += 1 + + probability = [count/num_rolls for count in occurrence] + print(f"Number of rolls = {num_rolls}") + for idx, val in enumerate(probability): + print(f"{idx} {round(val*100, 2)}%") + +play_dice(1, 100000) +play_dice(2, 100000) +play_dice(3, 100000) \ No newline at end of file From e2d145bc1b9d961176e13bd91ea49bb42a008463 Mon Sep 17 00:00:00 2001 From: Naveen M V Date: Mon, 17 Feb 2020 11:17:03 +0530 Subject: [PATCH 2/6] Add tests to throw_dice --- maths/monte_carlo_dice.py | 56 ++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/maths/monte_carlo_dice.py b/maths/monte_carlo_dice.py index 7d91e2bd4be1..9c0faa11bf07 100644 --- a/maths/monte_carlo_dice.py +++ b/maths/monte_carlo_dice.py @@ -1,35 +1,47 @@ import random -""" -""" - -class Dice(): +class Dice: NUM_SIDES = 6 + def __init__(self): - self.sides = [] - for i in range(1, 7): - self.sides.append(i) - self.odds = len(self.sides) - + self.sides = list(range(1, Dice.NUM_SIDES + 1)) + def roll(self): return random.choice(self.sides) - + def _str_(self): - return 'Fair Dice' + return "Fair Dice" + + +def throw_dice(num_throws, num_dice=2): + """ + Return probability list of all possible sums when throwing dice. + + >>> random.seed(0) + >>> throw_dice(10, 1) + [10.0, 0.0, 30.0, 50.0, 10.0, 0.0] + >>> throw_dice(100, 1) + [19.0, 17.0, 17.0, 11.0, 23.0, 13.0] + >>> throw_dice(1000, 1) + [18.8, 15.5, 16.3, 17.6, 14.2, 17.6] + >>> throw_dice(10000, 1) + [16.35, 16.89, 16.93, 16.6, 16.52, 16.71] + >>> throw_dice(10000, 2) + [2.74, 5.6, 7.99, 11.26, 13.92, 16.7, 14.44, 10.63, 8.05, 5.92, 2.75] + """ -def play_dice(num_dice, num_rolls): dices = [Dice() for i in range(num_dice)] - occurrence = [0 for i in range(0, len(dices)*Dice.NUM_SIDES+1)] + count_of_sum = [0] * (len(dices) * Dice.NUM_SIDES + 1) + + for i in range(num_throws): + count_of_sum[sum([dice.roll() for dice in dices])] += 1 + + probability = [round((count * 100) / num_throws, 2) for count in count_of_sum] + return probability[num_dice:] # remove counts of sums that never appear - for i in range(num_rolls): - occurrence[sum([dice.roll() for dice in dices])] += 1 - probability = [count/num_rolls for count in occurrence] - print(f"Number of rolls = {num_rolls}") - for idx, val in enumerate(probability): - print(f"{idx} {round(val*100, 2)}%") +if __name__ == "__main__": + import doctest -play_dice(1, 100000) -play_dice(2, 100000) -play_dice(3, 100000) \ No newline at end of file + doctest.testmod() From c001165d3d19307d4201ba3f193cc5baa3b9451c Mon Sep 17 00:00:00 2001 From: Naveen M V Date: Mon, 17 Feb 2020 11:19:57 +0530 Subject: [PATCH 3/6] Fix comment --- maths/monte_carlo_dice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/monte_carlo_dice.py b/maths/monte_carlo_dice.py index 9c0faa11bf07..6ab18cbd0956 100644 --- a/maths/monte_carlo_dice.py +++ b/maths/monte_carlo_dice.py @@ -38,7 +38,7 @@ def throw_dice(num_throws, num_dice=2): count_of_sum[sum([dice.roll() for dice in dices])] += 1 probability = [round((count * 100) / num_throws, 2) for count in count_of_sum] - return probability[num_dice:] # remove counts of sums that never appear + return probability[num_dice:] # remove probability of sums that never appear if __name__ == "__main__": From f36edcfad741a2297bdc7c4dd647adcb9c169a01 Mon Sep 17 00:00:00 2001 From: Naveen M V Date: Mon, 17 Feb 2020 11:53:39 +0530 Subject: [PATCH 4/6] Add type hints --- maths/monte_carlo_dice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maths/monte_carlo_dice.py b/maths/monte_carlo_dice.py index 6ab18cbd0956..f503a3e39cb6 100644 --- a/maths/monte_carlo_dice.py +++ b/maths/monte_carlo_dice.py @@ -1,5 +1,5 @@ import random - +from typing import List class Dice: NUM_SIDES = 6 @@ -14,7 +14,7 @@ def _str_(self): return "Fair Dice" -def throw_dice(num_throws, num_dice=2): +def throw_dice(num_throws: int, num_dice: int=2) -> List[float]: """ Return probability list of all possible sums when throwing dice. From 0cd6c493f55d6e269bc58a98df8139223efc17fd Mon Sep 17 00:00:00 2001 From: Naveen M V Date: Mon, 17 Feb 2020 12:26:58 +0530 Subject: [PATCH 5/6] Add additional comments --- maths/monte_carlo_dice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/maths/monte_carlo_dice.py b/maths/monte_carlo_dice.py index f503a3e39cb6..bcbb0656f3b0 100644 --- a/maths/monte_carlo_dice.py +++ b/maths/monte_carlo_dice.py @@ -5,6 +5,7 @@ class Dice: NUM_SIDES = 6 def __init__(self): + """ Initialize a six sided dice """ self.sides = list(range(1, Dice.NUM_SIDES + 1)) def roll(self): From 86afd8c197d591007f3bc3e98ccf271856dd8d3b Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Mon, 17 Feb 2020 08:18:55 +0100 Subject: [PATCH 6/6] Update monte_carlo_dice.py --- maths/monte_carlo_dice.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/maths/monte_carlo_dice.py b/maths/monte_carlo_dice.py index bcbb0656f3b0..c045cc829213 100644 --- a/maths/monte_carlo_dice.py +++ b/maths/monte_carlo_dice.py @@ -31,13 +31,10 @@ def throw_dice(num_throws: int, num_dice: int=2) -> List[float]: >>> throw_dice(10000, 2) [2.74, 5.6, 7.99, 11.26, 13.92, 16.7, 14.44, 10.63, 8.05, 5.92, 2.75] """ - dices = [Dice() for i in range(num_dice)] count_of_sum = [0] * (len(dices) * Dice.NUM_SIDES + 1) - for i in range(num_throws): count_of_sum[sum([dice.roll() for dice in dices])] += 1 - probability = [round((count * 100) / num_throws, 2) for count in count_of_sum] return probability[num_dice:] # remove probability of sums that never appear