diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-06-02 08:16:49 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-02 08:16:49 (GMT) |
commit | 5ae299ac78abb628803ab7dee0997364547f5cc8 (patch) | |
tree | 243cb704ac7c8421e7406722912cc50e20b5ebad /Lib/test/test_math.py | |
parent | d71f3170ac9c850f6d1f9bffaa628dc473df5e75 (diff) | |
download | cpython-5ae299ac78abb628803ab7dee0997364547f5cc8.zip cpython-5ae299ac78abb628803ab7dee0997364547f5cc8.tar.gz cpython-5ae299ac78abb628803ab7dee0997364547f5cc8.tar.bz2 |
bpo-37128: Add math.perm(). (GH-13731)
Diffstat (limited to 'Lib/test/test_math.py')
-rw-r--r-- | Lib/test/test_math.py | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index e27092e..96e0cf2 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -240,6 +240,9 @@ def result_check(expected, got, ulp_tol=5, abs_tol=0.0): else: return None +class IntSubclass(int): + pass + # Class providing an __index__ method. class MyIndexable(object): def __init__(self, value): @@ -1862,6 +1865,64 @@ class IsCloseTests(unittest.TestCase): self.assertAllClose(fraction_examples, rel_tol=1e-8) self.assertAllNotClose(fraction_examples, rel_tol=1e-9) + def testPerm(self): + perm = math.perm + factorial = math.factorial + # Test if factorial defintion is satisfied + for n in range(100): + for k in range(n + 1): + self.assertEqual(perm(n, k), + factorial(n) // factorial(n - k)) + + # Test for Pascal's identity + for n in range(1, 100): + for k in range(1, n): + self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k)) + + # Test corner cases + for n in range(1, 100): + self.assertEqual(perm(n, 0), 1) + self.assertEqual(perm(n, 1), n) + self.assertEqual(perm(n, n), factorial(n)) + + # Raises TypeError if any argument is non-integer or argument count is + # not 2 + self.assertRaises(TypeError, perm, 10, 1.0) + self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0)) + self.assertRaises(TypeError, perm, 10, "1") + self.assertRaises(TypeError, perm, 10.0, 1) + self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1) + self.assertRaises(TypeError, perm, "10", 1) + + self.assertRaises(TypeError, perm, 10) + self.assertRaises(TypeError, perm, 10, 1, 3) + self.assertRaises(TypeError, perm) + + # Raises Value error if not k or n are negative numbers + self.assertRaises(ValueError, perm, -1, 1) + self.assertRaises(ValueError, perm, -2**1000, 1) + self.assertRaises(ValueError, perm, 1, -1) + self.assertRaises(ValueError, perm, 1, -2**1000) + + # Raises value error if k is greater than n + self.assertRaises(ValueError, perm, 1, 2) + self.assertRaises(ValueError, perm, 1, 2**1000) + + n = 2**1000 + self.assertEqual(perm(n, 0), 1) + self.assertEqual(perm(n, 1), n) + self.assertEqual(perm(n, 2), n * (n-1)) + self.assertRaises((OverflowError, MemoryError), perm, n, n) + + for n, k in (True, True), (True, False), (False, False): + self.assertEqual(perm(n, k), 1) + self.assertIs(type(perm(n, k)), int) + self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20) + self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20) + for k in range(3): + self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int) + self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int) + def testComb(self): comb = math.comb factorial = math.factorial @@ -1925,8 +1986,11 @@ class IsCloseTests(unittest.TestCase): for n, k in (True, True), (True, False), (False, False): self.assertEqual(comb(n, k), 1) self.assertIs(type(comb(n, k)), int) + self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10) self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10) - self.assertIs(type(comb(MyIndexable(5), MyIndexable(2))), int) + for k in range(3): + self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int) + self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int) def test_main(): |