Monday, November 15, 2010

allCombinations: leaveOut

leaveOut

Ok, on my previous post I brought up a small Python module I was inspired to throw together while writing tests. It's still sitting in a gist, though I'll probably move it to a real repo before too long:

https://gist.github.com/674715

So I admit, as I was posting it, it occurred to me that to a large extent this stuff could be replaced with a nested for loop. For instance, this:

for lst in allCombinations([1, 2, oneOf(3,4), oneOf(5,6)]):

can be pulled off with:

for x in (3, 4):
for y in (5, 6):
lst = [1, 2, x, y]

Not a huge gain necessarily on my part. So as I was using it in my testing I realized I once again had engineered something for a tiny use that, neat as it is, could have been done much faster by brute force. But then, I realized another thing I could add that would make my code much more concise. I've added another keyword called "leaveOut". It lets you opt to not have the element show up at all. Here's an example:

allCombinations([1,2, oneOf(3, leaveOut), oneOf(4, leaveOut)])

This will return:

[ [1, 2, 3, 4], [1, 2, 3], [1, 2, 4], [1, 2] ]
And of course, the "leaveOut" case will omit dictionary entries and object data members as well.

BTW

I should also mention another use case I thought of, "leaveOut" aside, that might be a real pain to do without an aide such as allCombinations, which is dynamically created structures, with an arbitrary amount of variables:

allCombinations( [ oneOf(1, 2) ] * x )

I've just generated all possible lists of either 1 or 2, of an arbitrary length, which can be set at runtime. Or how about something a bit more fun:

allCombinations( [ oneOf( *range(y) + [leaveOut] ) for y in range(x) ] )
Taking all combinations of lists of length x, where each element can equal any integer from zero to its index, and then adding combinations where items are omitted. Not horribly useful, but complicated.

To do these in a standard way you'd need x for loops, which you can't do directly. (I bet you could do it with recursion).

Fixes

I'll also mentione that I fixed a couple general errors. oneOf on Data members had a big bug. And now if you don't have oneOf in your structure, allCombinations just returns a list containing only the original structure, instead of looping to death.

No comments: