initial commit

This commit is contained in:
Randell Dawson 2020-09-29 10:13:24 -07:00
commit dbf6eb1ac1
4 changed files with 109 additions and 0 deletions

52
README.md Normal file
View File

@ -0,0 +1,52 @@
### Assignment
Suppose there is a hat containing 5 blue balls, 4 red balls, and 2 green balls. What is the probability that a random draw of 4 balls will contain at least 1 red ball and 2 green balls? While it would be possible to calculate the probability using advanced mathematics, an easier way is to write a program to perform a large number of experiments to estimate an approximate probability.
For this project, you will write a program to determine the approximate probability of drawing certain balls randomly from a hat.
First, create a `Hat` class in `prob_calculator.py`. The class should take a variable number of arguments that specify the number of balls of each color that are in the hat. For example, a class object could be created in any of these ways:
```
hat1 = Hat(yellow=3, blue=2, green=6)
hat2 = Hat(red=5, orange=4)
hat3 = Hat(red=5, orange=4, black=1, blue=0, pink=2, striped=9)
```
A hat will always be created with at least one ball. The arguments passed into the hat object upon creation should be converted to a `contents` instance variable. `contents` should be a list of strings containing one item for each ball in the hat. Each item in the list should be a color name representing a single ball of that color. For example, if your hat is `{"red": 2, "blue": 1}`, `contents` should be `["red", "red", "blue"]`.
The `Hat` class should have a `draw` method that accepts an argument indicating the number of balls to draw from the hat. This method should remove balls at random from `contents` and return those balls as a list of strings. The balls should not go back into the hat during the draw, similar to an urn experiment without replacement. If the number of balls to draw exceeds the available quantity, return all the balls.
Next, create an `experiment` function in `prob_calculator.py` (not inside the `Hat` class). This function should accept the following arguments:
* `hat`: A hat object containing balls that should be copied inside the function.
* `expected_balls`: An object indicating the exact group of balls to attempt to draw from the hat for the experiment. For example, to determine the probability of drawing 2 blue balls and 1 red ball from the hat, set `expected_balls` to `{"blue":2, "red":1}`.
* `num_balls_drawn`: The number of balls to draw out of the hat in each experiment.
* `num_experiments`: The number of experiments to perform. (The more experiments performed, the more accurate the approximate probability will be.)
The `experiment` function should return a probability.
For example, let's say that you want to determine the probability of getting at least 2 red balls and 1 green ball when you draw 5 balls from from a hat containing 6 black, 4 red, and 3 green. To do this, we perform `N` experiments, count how many times `M` we get at least 2 red balls and 1 green ball, and estimate the probability as `M/N`. Each experiment consists of starting with a hat containing the specified balls, drawing a number of balls, and checking if we got the balls we were attempting to draw.
Here is how you would call the `experiment` function based on the example above with 2000 experiments:
```
hat = Hat(black=6, red=4, green=3)
probability = experiment(hat=hat,
expected_balls={"red":2,"green":1},
num_balls_drawn=5,
num_experiments=2000)
```
Since this is based on random draws, the probability will be slightly different each time the code is run.
*Hint: Consider using the modules that are already imported at the top of `prob_calculator.py`.*
### Development
Write your code in `prob_calculator.py`. For development, you can use `main.py` to test your code. Click the "run" button and `main.py` will run.
### Testing
The unit tests for this project are in `test_module.py`. We imported the tests from `test_module.py` to `main.py` for your convenience. The tests will run automatically whenever you hit the "run" button.
### Submitting
Copy your project's URL and submit it to freeCodeCamp.

15
main.py Normal file
View File

@ -0,0 +1,15 @@
# This entrypoint file to be used in development. Start by reading README.md
import prob_calculator
from unittest import main
hat = prob_calculator.Hat(blue=4, red=2, green=6)
probability = prob_calculator.experiment(
hat=hat,
expected_balls={"blue": 2,
"red": 1},
num_balls_drawn=4,
num_experiments=3000)
print("Probability:", probability)
# Run unit tests automatically
main(module='test_module', exit=False)

8
prob_calculator.py Normal file
View File

@ -0,0 +1,8 @@
import copy
import random
# Consider using the modules imported above.
class Hat:
def experiment(hat, expected_balls, num_balls_drawn, num_experiments):

34
test_module.py Normal file
View File

@ -0,0 +1,34 @@
import unittest
import prob_calculator
prob_calculator.random.seed(95)
class UnitTests(unittest.TestCase):
def test_hat_class_contents(self):
hat = prob_calculator.Hat(red=3,blue=2)
actual = hat.contents
expected = ["red","red","red","blue","blue"]
self.assertEqual(actual, expected, 'Expected creation of hat object to add correct contents.')
def test_hat_draw(self):
hat = prob_calculator.Hat(red=5,blue=2)
actual = hat.draw(2)
expected = ['blue', 'red']
self.assertEqual(actual, expected, 'Expected hat draw to return two random items from hat contents.')
actual = len(hat.contents)
expected = 5
self.assertEqual(actual, expected, 'Expected hat draw to reduce number of items in contents.')
def test_prob_experiment(self):
hat = prob_calculator.Hat(blue=3,red=2,green=6)
probability = prob_calculator.experiment(hat=hat, expected_balls={"blue":2,"green":1}, num_balls_drawn=4, num_experiments=1000)
actual = probability
expected = 0.272
self.assertAlmostEqual(actual, expected, delta = 0.01, msg = 'Expected experiemnt method to return a different probability.')
hat = prob_calculator.Hat(yellow=5,red=1,green=3,blue=9,test=1)
probability = prob_calculator.experiment(hat=hat, expected_balls={"yellow":2,"blue":3,"test":1}, num_balls_drawn=20, num_experiments=100)
actual = probability
expected = 1.0
self.assertAlmostEqual(actual, expected, delta = 0.01, msg = 'Expected experiment method to return a different probability.')
if __name__ == "__main__":
unittest.main()