(self)
| 369 | self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1) |
| 370 | |
| 371 | def test_permutations(self): |
| 372 | self.assertRaises(TypeError, permutations) # too few arguments |
| 373 | self.assertRaises(TypeError, permutations, 'abc', 2, 1) # too many arguments |
| 374 | self.assertRaises(TypeError, permutations, None) # pool is not iterable |
| 375 | self.assertRaises(ValueError, permutations, 'abc', -2) # r is negative |
| 376 | self.assertEqual(list(permutations('abc', 32)), []) # r > n |
| 377 | self.assertRaises(TypeError, permutations, 'abc', 's') # r is not an int or None |
| 378 | self.assertEqual(list(permutations(range(3), 2)), |
| 379 | [(0,1), (0,2), (1,0), (1,2), (2,0), (2,1)]) |
| 380 | |
| 381 | def permutations1(iterable, r=None): |
| 382 | 'Pure python version shown in the docs' |
| 383 | pool = tuple(iterable) |
| 384 | n = len(pool) |
| 385 | r = n if r is None else r |
| 386 | if r > n: |
| 387 | return |
| 388 | indices = list(range(n)) |
| 389 | cycles = list(range(n-r+1, n+1))[::-1] |
| 390 | yield tuple(pool[i] for i in indices[:r]) |
| 391 | while n: |
| 392 | for i in reversed(range(r)): |
| 393 | cycles[i] -= 1 |
| 394 | if cycles[i] == 0: |
| 395 | indices[i:] = indices[i+1:] + indices[i:i+1] |
| 396 | cycles[i] = n - i |
| 397 | else: |
| 398 | j = cycles[i] |
| 399 | indices[i], indices[-j] = indices[-j], indices[i] |
| 400 | yield tuple(pool[i] for i in indices[:r]) |
| 401 | break |
| 402 | else: |
| 403 | return |
| 404 | |
| 405 | def permutations2(iterable, r=None): |
| 406 | 'Pure python version shown in the docs' |
| 407 | pool = tuple(iterable) |
| 408 | n = len(pool) |
| 409 | r = n if r is None else r |
| 410 | for indices in product(range(n), repeat=r): |
| 411 | if len(set(indices)) == r: |
| 412 | yield tuple(pool[i] for i in indices) |
| 413 | |
| 414 | for n in range(7): |
| 415 | values = [5*x-12 for x in range(n)] |
| 416 | for r in range(n+2): |
| 417 | result = list(permutations(values, r)) |
| 418 | self.assertEqual(len(result), 0 if r>n else fact(n) / fact(n-r)) # right number of perms |
| 419 | self.assertEqual(len(result), len(set(result))) # no repeats |
| 420 | self.assertEqual(result, sorted(result)) # lexicographic order |
| 421 | for p in result: |
| 422 | self.assertEqual(len(p), r) # r-length permutations |
| 423 | self.assertEqual(len(set(p)), r) # no duplicate elements |
| 424 | self.assertTrue(all(e in values for e in p)) # elements taken from input iterable |
| 425 | self.assertEqual(result, list(permutations1(values, r))) # matches first pure python version |
| 426 | self.assertEqual(result, list(permutations2(values, r))) # matches second pure python version |
| 427 | if r == n: |
| 428 | self.assertEqual(result, list(permutations(values, None))) # test r as None |
nothing calls this directly
no test coverage detected