For the purposes of unit-testing in Python, I've written a very simple function for generating variable-length lists populated with random objects:
constructors = [
object,
dict,
lambda: bool(randint(0, 1)),
lambda: randint(1, 1000),
lambda: ''.join(choice(digits) for _ in range(randint(1, 10)))
]
choices = (
lambda _: choice(constructors)(),
lambda off: fake_list(off),
lambda off: tuple(fake_list(off))
)
def fake_list(off = None):
'''Creates a list populated with random objects.'''
off = (off or 0) + 1
return [choice(choices)(off) for _ in range(max(randint(1, 10) - off, 0))]
List generated with this function typically look something like this:
[(269, '6'), [{}, 990, 347, <object object at 0x7f51b230b130>, {}, [{}, '91921063', 302, '0047953', {}, ()], True], '70262', True]
Do you see any problems with it? Is there a more efficient/elegant way of doing this that you could suggest?
Quality of the generated primitives (strings, integers) is not of priority (i.e. string.digits should be enough).
offreduces readability - it is a bit hard to follow what(None or 0) + 1might be. it is not documented in the docstring either. what is the intent ofoff? \$\endgroup\$offserves as an "annealing factor". That is, because the function may call itself, I need to ensure that I'm not calling forever.offis subtracted from randomly generated length of the list, so that it's shorter on each call. \$\endgroup\$recursion_depthsuit better?offis very generic to understand its meaning easily \$\endgroup\$