I was trying to complete the probability calculator project but my code doesn’t produce the correct probability and I am not able to find the mistake. Can somebody help me?
import copy
import random
class Hat:
def __init__(self, **colors):
self.contents = []
for color, times in colors.items():
for t in range(times):
self.contents.append(color)
self.contents_copy = copy.deepcopy(self.contents)
def draw(self, number):
self.drawn = []
self.contents = copy.deepcopy(self.contents_copy)
for t in range(number):
self.drawn.append(
self.contents.pop(random.randint(0,
len(self.contents) - 1 - t)))
return self.drawn
def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
M = 0
for i in range(num_experiments):
hat.draw(num_balls_drawn)
drawn_balls = {}
for color in hat.drawn:
drawn_balls[color] = drawn_balls.get(color, 0) + 1
for color, times in expected_balls.items():
if drawn_balls.get(color, 0) >= times:
continue
break
else:
M += 1
return (M / num_experiments)
I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.
You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.
when the hat is created I also create a list of the colors and a copy of that list. For each iteration of the for loop, the draw method is called and inside that method at the beginning the list receives it’s original elements stored inside the copy since at the end of the method the list is modified and I need the original values for each iteration.
it keeps producing the wrong answer :(. Maybe there is something wrong with my logic?, i was trying to find the mistakes by using print statements but still it seems rigth for me.
import copy
import random
# Consider using the modules imported above.
class Hat:
def __init__(self, **colors):
self.contents = []
for color, times in colors.items():
for t in range(times):
self.contents.append(color)
self.contents_copy = copy.deepcopy(self.contents)
def draw(self, number):
self.drawn = []
self.contents = copy.deepcopy(self.contents_copy)
print("Contents:", self.contents_copy)
for t in range(number):
self.drawn.append(
self.contents.pop(random.randint(0,
len(self.contents) - 1 - t)))
print("Drawn: ", self.drawn)
return self.drawn
def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
M = 0
for i in range(num_experiments):
hat.draw(num_balls_drawn)
print("Expected balls:", expected_balls)
drawn_balls = {}
for color in hat.drawn:
drawn_balls[color] = drawn_balls.get(color, 0) + 1
print("Drawn_balls:", drawn_balls)
for color, times in expected_balls.items():
if drawn_balls.get(color, 0) >= times:
continue
break
else:
print("Right:", M)
M += 1
print("")
return float(M) / float(num_experiments)
Ok so I went through your code for a bit and I’ve been messing with it to find out what is wrong.
When I run my tests, I always get an answer that is similar (give or take some) to this output…I’ve shown 3 different outputs below…
535
Probability: 0.17833333333333334
497
Probability: 0.16566666666666666
551
Probability: 0.18366666666666667
The number above the probability is ‘M’.
Now I’ll show 3 outputs from your code below for a comparison…
850
Probability: 0.2833333333333333
858
Probability: 0.286
852
Probability: 0.284
When compared, we see that your test has roughly 300+ more ‘right’ draws than my tests. When I go back to check if your code compares the balls drawn and the expected balls correctly, there is no issue. It all works fine for the balls that are being drawn.
This means that…there is most likely an issue with your actual draw method or the way it is implemented within your experiment function. I would focus all of your efforts on that section of the code and see if anything can be tweaked or completely changed to correct the issue.
Personally, I took a completely different approach to the problem or else I’d give a little bit more insight. I hope this can help you figure it out! Good luck!