Probability calculator assignment

Tell us what’s happening:

Hi! I’m having trouble with the Probability Calculator assignment. The problem arises in the following line of code:
for color in expected_balls.contents: (Line 52) in the link I shared

The error says: ‘dict’ object has no attribute 'contents’

Nevertheless, when I run the code in my computer (not on the Replit starter code), I don’t get such error. I don’t know what’s going on, since I’ve already checked that expected_balls.contents is a List, not a dictionary.

Maybe the problem arises in the first lines of code, where I define contents as a class variable (an empty list -line 6-) and in line 9 as an instance variable self.contents = . I did this to assure this list is cleaned every time an experiment is initialized. But maybe there’s another way, I don’t know.

Can anyone help me? thanks!

Your code so far

import copy
import random

class Hat: #*args define una cantidad de argumentos variable

    contents= []

    def __init__ (self, **kwargs):
        self.contents = []  #The list contents is "cleaned" when a new instance of
                            #the class is initialized

       #Conversion of the dictionary kwargs into a list with format:
       # Example: (yellow=3, blue=2) ----> ['yellow','yellow','yellow,'blue','blue']
        for key,value in kwargs.items():
            for j in range (value):
                self.contents.append(key)

        def draw (self, n_balls):
        #The method withdraws balls from self.contents
        
        balls_taken= []

        if n_balls > len(self.contents)-1: #balls extracted greater than available
            balls_taken = self.contents
            self.contents = []
            return self.contents, balls_taken

        for i in range(n_balls):
            rand_extraction = random.randint(0, len(self.contents)-1)
            extracted = self.contents.pop(rand_extraction)
            balls_taken.append(extracted)

        return balls_taken #is a list

#---------------------------------------------------------------------------------------------------------

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

    experiment_count = 0

    for i in range(num_experiments):
        hat_copy = copy.deepcopy(hat) #Copy of the hat object inside the function to avoid
        #modifying the original object (DEEP COPY)

        expected_balls_dict= dict()
        #Dictionary expected_balls_dict is filled
        for color in expected_balls.contents:
            expected_balls_dict[color] = expected_balls_dict.get(color,0) + 1 #OK, es un diccionario, como count_balls

        count_balls = dict()
        #Balls are extracted and the dictionary count_balls is filled:
        extracted_balls = hat_copy.draw(num_balls_drawn) # ['blue', 'yellow', 'yellow',...] List format OK
        for color in extracted_balls:
            count_balls[color] = count_balls.get(color,0) + 1  # {'yellow': 3, 'green': 3, 'blue': 2}  Dictionary format OK

        #Comparision between dictionaries count_balls and extracted_balls_dict
        aux = 0
        for color in expected_balls_dict:
            if color not in count_balls:
                break #Experiment ends
            if count_balls[color] >= expected_balls_dict[color]:
                aux += 1
            if aux == len(expected_balls_dict):
                experiment_count += 1

    probability= experiment_count/num_experiments

    return probability

Your browser information:

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

Challenge: Probability Calculator

Link to the challenge:
boilerplate-probability-calculator-1 - Replit

“expected_balls” is provided as argument to the function and in the test-module.py it’s clearly a dictionairy. I don’t know what you run on your local machine, but you NEVER define “expected_ball” in the code. Thus it will be whatever was in the test_module: a dict.

2 Likes

When you run the code on your home system, are you executing the main.py code, or are you just executing the prob_calculator code?

expected_balls in the provided code is never initiated as a “Hat” object, and therefore wouldn’t contain a contents attribute.

1 Like

This line has bad indentation.

Side note, the space between the function name and the () is a violation of the Python style guide, fyi

1 Like

Defenetly, the prob_calculator code.
I’ll take a look again taking this into account, thanks!

I see what the problem was. In main.py, expected_balls is a dictionary, as you said. On the other hand, in the problem assignment, the following is said about this variable:

  • expected_balls : An object indicating the exact group of balls to attempt to draw from the hat for the experiment. For example, to determine the probability of drawing 2 blue balls and 1 red ball from the hat, set expected_balls to {"blue":2, "red":1} .

So, as it says it is an object, I used the object hat to create an instance of the hat object to produce the expected balls. I think there’s ambiguity there. Nevertheless, I get it now.

I’ll look again the whole program to see if I can fix it, considering this. Thank you

I see it has the same indentation as the line
def init (self, **kwargs):

can you tell me why is it wrong? And if it’s no bother, can you tell me where can I see more about python style guidelines? Thank to you and to everyone :smiley:

It is showing as different levels


Style guide:

1 Like

Parodiadrian, yeah, thats what I thought… when testing you’re code to verify it passes the test you need to run main.py… that is what the Replit is running as that has all the test code. Running just the prob_calculator code verifies there are no parsing errors, but it doesn’t actually execute the function or the tests to verify all is good.

Also, just fyi, a dict() is an object… so is a list and a string.