Probability Calculator

import copy
import random


class Hat:
    def __init__(self, red=0, yellow=0, orange=0, blue=0, black=0, pink=0, green=0, striped=0):
        contents = {
            'red': red,
            'yellow': yellow,
            'orange': orange,
            'blue': blue,
            'black': black,
            'pink': pink,
            'green': green,
            'striped': striped
        }
        self.contents = [k for k, v in contents.items() for _ in range(v)]
        print(f'{self.contents = }')

    def random_mix(self, num_balls_drawn):
        if num_balls_drawn > len(self.contents):
            raise ValueError('Input a number that is within the number of balls in the Hat')

        contents = copy.deepcopy(self.contents)
        balls_drawn = []

        for _ in range(num_balls_drawn):
            ball_choice = random.choice(contents)
            balls_drawn.append(ball_choice)
            contents.remove(ball_choice)

        return balls_drawn

    def draw(self, expected_balls, num_balls_drawn, num_experiments):
        passes = 0
        for _ in range(num_experiments):
            balls_drawn = self.random_mix(num_balls_drawn)
            drawn_dict = {color: balls_drawn.count(color) for color in set(balls_drawn)}
            success = True
            for color, count in expected_balls.items():
                if drawn_dict.get(color, 0) < count:
                    success = False
                    break
            if success:
                passes += 1
        pass_percent = passes / num_experiments
        return pass_percent


def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
    return hat.draw(expected_balls, num_balls_drawn, num_experiments)


hat = Hat(black=6, red=4, green=3)

expected_balls = {'red' : 2, 'green': 1}
num_balls_drawn = 5
num_experiments = 2000

success_chance_hat = experiment(hat, expected_balls, num_balls_drawn, num_experiments)
print("Success Chance for Hat:", success_chance_hat)

The last condition where it says that function [experiment] must return a different probability works in the code but does not register as done in the task list im not sure whats wrong wo what to do

Hi @screw

Your code is printing , not returning it.

Happy coding

This isn’t what the draw method is supposed to do. It shouldn’t have a number of experiments

in the example it states num experiments tho

import copy
import random


class Hat:
    def __init__(self, red=0, yellow=0, orange=0, blue=0, black=0, pink=0, green=0, striped=0):
        contents = {
            'red': red,
            'yellow': yellow,
            'orange': orange,
            'blue': blue,
            'black': black,
            'pink': pink,
            'green': green,
            'striped': striped
        }
        self.contents = [k for k, v in contents.items() for _ in range(v)]
        print(f'{self.contents = }')

    def random_mix(self, num_balls_drawn):
        if num_balls_drawn > len(self.contents):
            raise ValueError('Input a number that is within the number of balls in the Hat')

        contents = copy.deepcopy(self.contents)
        balls_drawn = []

        for _ in range(num_balls_drawn):
            ball_choice = random.choice(contents)
            balls_drawn.append(ball_choice)
            contents.remove(ball_choice)

        return balls_drawn

    def draw(self, expected_balls, num_balls_drawn):
        balls_drawn = self.random_mix(num_balls_drawn)
        drawn_dict = {color: balls_drawn.count(color) for color in set(balls_drawn)}
        success = True
        for color, count in expected_balls.items():
            if drawn_dict.get(color, 0) < count:
                success = False
        return success


def experiment(hat, expected_balls, num_balls_drawn):
    return hat.draw(expected_balls, num_balls_drawn)


hat = Hat(black=6, red=4, green=3)

expected_balls = {'red' : 2, 'green': 1}
num_balls_drawn = 5

success_chance_hat = experiment(hat, expected_balls, num_balls_drawn)
print("Success Chance for Hat:", success_chance_hat)

i removed the use of number of experiments so success returns true or false and its working properly with true or false replies but its still not checking the box

if you press F12 you see more of the errors
for example:

pyodide.asm.js:9   File "/home/pyodide/test_module.py", line 13, in test_prob_experiment
pyodide.asm.js:9     probability = probability_calculator.experiment(hat=hat, expected_balls={"blue":2,"green":1}, num_balls_drawn=4, num_experiments=1000)
pyodide.asm.js:9                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pyodide.asm.js:9 TypeError: experiment() got an unexpected keyword argument 'num_experiments'

your experiment method should have place for num_experiments to be set

Nope, that is only for ‘experiment’, not ‘draw’

Ok so i have done what u did and this is the response of the F12
pyodide.asm.js:9 AssertionError: False != 0.272 within 0.01 delta (0.272 difference) : Expected experiment method to return a different probability.
i used the example in the question as the arguments and the probability should be 0.356 which i achieved but they insisted im guessing 0.272 ± 0.01 difference.
i have followed jeremyLT advice and changed the functions 'functionality’where draw is not the function to use num_experiments but its still not working
My code currently is:

import copy
import random


class Hat:
    def __init__(self, red=0, yellow=0, orange=0, blue=0, black=0, pink=0, green=0, striped=0):
        contents = {
            'red': red,
            'yellow': yellow,
            'orange': orange,
            'blue': blue,
            'black': black,
            'pink': pink,
            'green': green,
            'striped': striped
        }
        self.contents = [k for k, v in contents.items() for _ in range(v)]
        print(f'{self.contents = }')

    def draw(self, num_balls_drawn):
        if num_balls_drawn > len(self.contents):
            raise ValueError('Input a number that is within the number of balls in the Hat')

        contents = copy.deepcopy(self.contents)
        balls_drawn = []

        for _ in range(num_balls_drawn):
            ball_choice = random.choice(contents)
            balls_drawn.append(ball_choice)
            contents.remove(ball_choice)

        return balls_drawn


def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
    passes = 0
    for _ in range(num_experiments):
        balls_drawn = hat.draw(num_balls_drawn)
        drawn_dict = {color: balls_drawn.count(color) for color in set(balls_drawn)}
        success = True
        for color, count in expected_balls.items():
            if drawn_dict.get(color, 0) < count:
                success = False
                break
        if success:
            passes += 1
    pass_percent = passes / num_experiments
    return pass_percent


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)

print(probability)

i switched between returning a float as a response or a bool as a response and its still not working so im not sure if im the one focusing on the wrong thing to fix

Why are you making this copy inside of the draw method?

i had to find a way to use copy cause it was in the starting code and just making a deepcopy so that the original wont be affected by anything that is being done to the copy like taking out the ball after its drawn

I think that you should reread the instructions carefully, paying attention to where the instructions tell you to do various things. This is the second major error you have had mixing together parts of the instructions, but the tests expect your code to operate a certain way.

here the first is your output, the second is the expected