I rarely ask people to check my finished projects, but in this case I am quite dissatisfied with my solution to the problem.
The reason is that, in order to arrive at a solution to the problem, I had to make two different ‘draw()’ methods (draw and draw_2). I did this for the following cases:
draw: used for tests where they give you a hat with x balls and draw some balls out of the hat, where the numbers of balls drawn in each iteration is lower than x
draw_2: used for that final test where they give you a hat with 19 balls but tell you that in each iteration you will draw 20 balls out of the hat
Do you know of a more efficient solution to tackle that one case where the number of balls to be drawn is larger than the number of balls in the hat? Also, why would they suggest this case in the first place, it would seem like an odd experiment to perform…
The spec says to return all the balls if more than are available are requested to be drawn, so a simple conditional on the number of balls to be drawn should be sufficient. It also appears the code is not always drawing without replacement, as in the draw() method:
which is the cause of the problem. Your draw_2() will only work up to draws of twice the number of balls available as well. But, since the tests pass by the magic of collections, I guess this is a good example of TDD, especially since the tests pass even though the specs have not completely been followed.
The reason is straightforward; if you have 19 balls, you can only draw 19, so if 20 are requested, it should not affect the probability. And if you return 20, the tests know you are not drawing without replacement.
The way you create self.contents seems very complicated. You make a long string, append text to that string in a loop and then split up the string into a list… why not just make a list?
The need for 2 helper functions AND an additional draw_2 method also seems excessive to essentially compare two lists.
In the experiment, first condition if num_balls_drawn > len(hat.contents): means in every single draw, ALL BALLS from the hat are drawn. So either I will ALWAYS draw the expected balls (because they are in the hat) or NEVER. This should be easier to calculate… plus is it possible the else-branch contains the exact same code?