Tell us what’s happening:
My code fails the test_prob_experiment because it gives a probability higher than expected. I think it’s a problem with checking if the expected balls have been drawn but don’t understand why it counts more draws as “successful” than it should. Any help is appreciated!

Your code so far

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36

To get the draw function to pass the test I put the replacing in the experiment function but I still don’t get the right probability

class Hat:
def __init__(self, **balls):
self.contents = []
for i, j in balls.items():
for k in range(j):
self.contents.append(i)
def draw(self, num_balls_drawn):
if num_balls_drawn <= len(self.contents):
balls_drawn = []
for i in range(num_balls_drawn):
rand_int = random.randrange(len(self.contents))
balls_drawn.append(self.contents[rand_int])
self.contents.pop(rand_int)
return balls_drawn
else:
return self.contents
def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
expected = []
for i, j in expected_balls.items():
for k in range(j):
expected.append(i)
M = 0
content_copy = copy.deepcopy(hat.contents)
for i in range(num_experiments):
if all(item in hat.draw(num_balls_drawn) for item in expected):
M = M + 1
hat.contents = copy.deepcopy(content_copy)
return M/num_experiments

all(item in hat.draw(num_balls_drawn) for item in expected)

For each item there’s new draw made. And another point - for example in case where it is expected to draw two balls with the same color - would the answer be correct if in draw would be one ball with that color?

Thanks! I got it to work now!
Is there a neater way to check the balls (the way I thought all() would work) than what I did with two for loops just checking each ball?

def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
expected = []
for i, j in expected_balls.items():
for k in range(j):
expected.append(i)
M = 0
content_copy = copy.deepcopy(hat.contents)
for i in range(num_experiments):
drawn = hat.draw(num_balls_drawn)
hat.contents = copy.deepcopy(content_copy)
count = 0
for i in expected:
for j in drawn:
if i == j:
count += 1
drawn.pop(drawn.index(j))
break
if count == len(expected):
M += 1
return M/num_experiments

Depends what is considered neater. But one way could be counting/grouping wanted balls by the color in the expected, and then checking if number of balls with that color in drawn is at least the wanted number.