I am currently working on this assignment and I am trying to understand one of the tests.
I have copied the code below. If this method requires to select random balls. How is it possible the expected answer is blue and red? I mean sometimes the response will be that but others it will be blue, blue and others red, red. What I am missing? to me it seems a contradiction test.

def test_hat_draw(self):
hat = prob_calculator.Hat(red=5,blue=2)
actual = hat.draw(2)
expected = ['blue', 'red']
self.assertEqual(actual, expected, 'Expected hat draw to return two random items from hat contents.')
actual = len(hat.contents)
expected = 5
self.assertEqual(actual, expected, 'Expected hat draw to reduce number of items in contents.')

Despite of the name of the random module, it not really random, but just pseudo-random. It uses seed value to initialize random number generator, but when using known seed value, generated results are reproducible.

This is what happens in tests, random module is seeded. This allows to know what balls to expect in tests.

Thanks sanity, that makes sense. However, for some reason I am not getting the same result.

Is the seeding the same for all functions within random? Perhaps I am using a different random function that the one the test is looking? This is the one I am using:

random.randrange(0, number, 1)

(number is the argument passed on the number of times it should be drawn)

Without seeing the whole code it might be hard, if not impossible to say where might problem be.

However that description of the number argument for the randrange doesn’t seem to be right. For example for number == 4, the random.randrange(0, number, 1) will return number between 0 and 3, inclusive.

Yes that is what I want 0, 3 (for n == 4) as I am using indexes to get the ball (index 4 would be an error).

This is the code I have put together so far:

class Hat:
def __init__(self, **kwargs):
self.contents = []
for k, v in kwargs.items():
for i in range(v):
self.contents.append(k)
def draw(self, number):
if number > len(self.contents):
return self.contents
else:
self.balls = []
for i in range(number):
ball_draw = random.randrange(0, number,1)
self.balls.append(self.contents[ball_draw])
self.contents.pop(ball_draw)
return self.balls

Let me make another example. In the hat there’s 8 balls, 2 balls are to be drawn. random.randrange(0, number, 1) will return 0 or 1 for the first draw and 0 or 1 for the second draw.