Probability Calc - only getting 0.0

Tell us what’s happening:
Code is only generating a probability of 0.0

From console:
python main.py
Probability: 0.0
..F
======================================================================
FAIL: test_prob_experiment (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-probability-calculator/test_module.py", line 27, in test_prob_experiment
    self.assertAlmostEqual(actual, expected, delta = 0.01, msg = 'Expected experiment method to return a different probability.')
AssertionError: 0.001 != 0.272 within 0.01 delta (0.271 difference) : Expected experiment method to return a different probability.


Ran 3 tests in 0.049s

FAILED (failures=1)

Your code so far

import copy
import random
# Consider using the modules imported above.

class Hat:
  def __init__(self, **kwargs):
    self.contents = []
# Assumes key is always color and value is integer, creates a list of colors mulitplied by thier frequncy listed in value. 
    for key, value in kwargs.items(): 
      self.contents += [key] * value
    
  def draw (self, num):
    if num > len(self.contents):
      return self.contents
    # Random ball selector
    balls = random.sample(copy.deepcopy(self.contents), num)
    # .remove() to use items, .pop() only works with index
    for ball in balls:
      self.contents.remove(ball)   
    return balls

def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
  #deepcopy
  hat2 = copy.deepcopy(hat)
  expected = copy.deepcopy(expected_balls)
  #num_balls is a list of the color of balls drawn
  num_balls = hat2.draw(num_balls_drawn)
  
  #calculating probability - this was the most dificult part
  for e in range(num_experiments):
    list = []
    count = 0
    # was not working because I did not use .item on expected to return the pair
    # This creates a list from the dictionary of the keys based on the value
    for k, v in expected.items():
      list += v * [k]
    #From GeeksforGeeks: all() function is an inbuilt function in Python which returns true if all the elements of a given iterable( List, Dictionary, Tuple, set, etc) are True else it returns False.
    if all(x in num_balls for x in list):
      count += 1
   
  return count / num_experiments

Your browser information:

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

Challenge: Probability Calculator

Link to the challenge:

Are you sure that this count = 0 should be inside the for loop?
count is going to be set as 0 every time the for runs.

1 Like

You are correct and more so I just realized the other variables need to be in the first for loop so they are reset with each experiment. However, now I am getting the wrong probability.

First thank you. Getting closer.

Second, thoughts?

What I am getting:

python main.py
Probability: 0.4563333333333333
..F
======================================================================
FAIL: test_prob_experiment (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-probability-calculator/test_module.py", line 27, in test_prob_experiment
    self.assertAlmostEqual(actual, expected, delta = 0.01, msg = 'Expected experiment method to return a different probability.')
AssertionError: 0.787 != 0.272 within 0.01 delta (0.515 difference) : Expected experiment method to return a different probability.

----------------------------------------------------------------------
Ran 3 tests in 0.191s

FAILED (failures=1)
 

New code:

import copy
import random
# Consider using the modules imported above.

class Hat:
  def __init__(self, **kwargs):
    self.contents = []
# Assumes key is always color and value is integer, creates a list  of colors mulitplied by #their frequncy listed in value. 
    for key, value in kwargs.items(): 
      self.contents += [key] * value
    
  def draw (self, num):
    if num > len(self.contents):
      return self.contents
    # Random ball selector
    balls = random.sample(copy.deepcopy(self.contents), num)
    # .remove() to use items, .pop() only works with index
    for ball in balls:
      self.contents.remove(ball)   
    return balls

def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
 # moved to outside the for loops to prevent reset
  count = 0
  #calculating probability - this was the most dificult part
  for e in range(num_experiments):
    list = []
    # Variables moved into first for loop
    hat2 = copy.deepcopy(hat)
    expected = copy.deepcopy(expected_balls)
    #num_balls is a list of the color of balls drawn
    num_balls = hat2.draw(num_balls_drawn)

    # was not working because I did not use .item on expected to return the pair
    # This creates a list from the dictionary of the keys based on the value
    for k, v in expected.items():
      list += v * [k]

    #From GeeksforGeeks: all() function is an inbuilt function in Python which          
    #returns true if all the elements of a given iterable( List, Dictionary, Tuple,      
   #  set, etc)  are True else it returns False.
    if all(x in num_balls for x in list):
      count += 1
  
  #Return probability 
  return count / num_experiments

Can you print the count and num_experiments and see if they make sense?

The list, num_balls, and count all seem to make sense. From what I read the ‘all’ function should work, and seems like an ideal function. However, I also tried collections as well as .sort method, interestingly, those gave me a 0.0 match. So maybe the issue is with how I am comparing lists?

So I am confused as to how I am getting either way to high or none at all.

import collections

if collections.Counter(num_balls)==collections.Counter(list):
    count += 1
if num_balls.sort==list.sort
    count +=1

What I’m going to suggest is a very simple (brute-force) way to do it, but I think is worth trying.

How about you loop over the list like:

for e in list:
    if e:
        count += 1

In the end, you want to get the non-zeros values right?

I want to get the number of times that list has exactly the same objects as num_balls, then I am returning the percentage of the time they match, dividing it by the number in num_experiments. The lists will not always be in the same order, but must have the same objects.

For example if list contains ‘green’, ‘red’, ‘red’ ,‘blue’, then num_balls must have those exact objects in any order. So num_balls must have both of the ‘red’ objects, having only one should disqualify it.

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