Probability Calculator - stuck in last step

My results are as follows:

  • Creation of hat object should add correct contents.
  • Passed:The draw method in hat class should reduce number of items in contents.
  • Failed:The experiment method should return a different probability.

When printing the probability, I get a number very close, but I still can’t find the error.

def experiment(hat, expected_balls, num_balls_drawn, num_experiments):

    M=0

    #Iteration
    for _ in range(num_experiments):
        aux = copy.deepcopy(hat)            

        # Draw  
        draw=(aux.draw(num_balls_drawn)) 
        dict_draw = {}
        for color in draw:
            if color in dict_draw:
                dict_draw[color] += 1
            else:
                dict_draw[color] = 1

        #Comparation        
        color_coincidence=True
        for color in expected_balls:            
            if not color in dict_draw:
                color_coincidence=False        
    
        min_cant=True
        if color_coincidence:
            for color in expected_balls:
                if expected_balls[color]>dict_draw[color]:
                    min_cant=False  

        #Favorable cases    
        if min_cant==True and color_coincidence==True:
            M+=1 
        
    prob =  M/num_experiments
    return(prob)

With this values:

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)

Output must be:

>>> 0.356

Insted a have:

>>> 0.3665

Could you share your Hat class implementation as well?

This is the class hat

class Hat:
    def __init__(self, **dict):
        L=[]
        for item in dict:
            for color in range(dict[item]):
                color=item
                L.append(color)
        self.contents = L
    
    def draw(self, n):
        L=[]
        max_index=len(self.contents)-1       
        for _ in range(n):
            x = random.randint(0, max_index)   
            L.append(self.contents.pop(x))
            max_index-=1
        return L

There’s error when running the test, if you take a look at the browser’s console:

----------------------------------------------------------------------
Traceback (most recent call last):
   File "/home/pyodide/test_module.py", line 18, in test_prob_experiment
     probability = probability_calculator.experiment(hat=hat, expected_balls={"yellow":2,"blue":3,"test":1}, num_balls_drawn=20, num_experiments=100)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/pyodide/probability_calculator.py", line 32, in experiment
     draw=(aux.draw(num_balls_drawn))
          ^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/pyodide/probability_calculator.py", line 18, in draw
     x = random.randint(0, max_index)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/lib/python311.zip/random.py", line 362, in randint
     return self.randrange(a, b+1)
            ^^^^^^^^^^^^^^^^^^^^^^
   File "/lib/python311.zip/random.py", line 345, in randrange
     raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
 ValueError: empty range for randrange() (0, 0, 0)
 ----------------------------------------------------------------------

This suggests, the draw method is not handling correctly situation when more balls should be drawn than number of the balls in hat.

Regarding the different results with the example, generally it’s hard to compare them,
after all, there’s randomness involved, and drawn balls can be completely different. You might wonder then how test can check anything in such case. Tests are using specific number to seed the random module, this allows to reproduce the exact values.

It was a very silly mistake.

Thanks. You help me to earn my certification :smiley:

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.