mirror of
https://github.com/python/cpython.git
synced 2025-10-09 08:31:26 +00:00
bpo-37128: Add math.perm(). (GH-13731)
This commit is contained in:
parent
d71f3170ac
commit
5ae299ac78
5 changed files with 244 additions and 3 deletions
|
@ -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():
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue