diff options
author | Raymond Hettinger <rhettinger@users.noreply.github.com> | 2019-06-08 15:58:11 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-08 15:58:11 (GMT) |
commit | e119b3d136bd94d880bce4b382096f6de3f38062 (patch) | |
tree | 241356f01ba320f5b0b342e004902e1e40314a17 | |
parent | 8cc605acdda5aff250ab4c9b524a7560f90ca9f3 (diff) | |
download | cpython-e119b3d136bd94d880bce4b382096f6de3f38062.zip cpython-e119b3d136bd94d880bce4b382096f6de3f38062.tar.gz cpython-e119b3d136bd94d880bce4b382096f6de3f38062.tar.bz2 |
bpo-37178: Allow a one argument form of math.perm() (GH-13905)
-rw-r--r-- | Doc/library/math.rst | 5 | ||||
-rw-r--r-- | Lib/test/test_math.py | 9 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst | 2 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst | 2 | ||||
-rw-r--r-- | Modules/clinic/mathmodule.c.h | 15 | ||||
-rw-r--r-- | Modules/mathmodule.c | 10 |
6 files changed, 34 insertions, 9 deletions
diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 28ed5d21..ff937d2 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -210,7 +210,7 @@ Number-theoretic and representation functions of *x* and are floats. -.. function:: perm(n, k) +.. function:: perm(n, k=None) Return the number of ways to choose *k* items from *n* items without repetition and with order. @@ -218,6 +218,9 @@ Number-theoretic and representation functions Evaluates to ``n! / (n - k)!`` when ``k <= n`` and evaluates to zero when ``k > n``. + If *k* is not specified or is None, then *k* defaults to *n* + and the function returns ``n!``. + Raises :exc:`TypeError` if either of the arguments are not integers. Raises :exc:`ValueError` if either of the arguments are negative. diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 86e3923..adefa07 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1885,8 +1885,13 @@ class IsCloseTests(unittest.TestCase): self.assertEqual(perm(n, 1), n) self.assertEqual(perm(n, n), factorial(n)) + # Test one argument form + for n in range(20): + self.assertEqual(perm(n), factorial(n)) + self.assertEqual(perm(n, None), factorial(n)) + # Raises TypeError if any argument is non-integer or argument count is - # not 2 + # not 1 or 2 self.assertRaises(TypeError, perm, 10, 1.0) self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0)) self.assertRaises(TypeError, perm, 10, "1") @@ -1894,7 +1899,7 @@ class IsCloseTests(unittest.TestCase): self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1) self.assertRaises(TypeError, perm, "10", 1) - self.assertRaises(TypeError, perm, 10) + self.assertRaises(TypeError, perm) self.assertRaises(TypeError, perm, 10, 1, 3) self.assertRaises(TypeError, perm) diff --git a/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst b/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst new file mode 100644 index 0000000..77b8723 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst @@ -0,0 +1,2 @@ +For math.perm(n, k), let k default to n, giving the same result as +factorial. diff --git a/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst b/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst new file mode 100644 index 0000000..500ef54 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst @@ -0,0 +1,2 @@ +Give math.perm() a one argument form that means the same as +math.factorial(). diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index cdf4305..966b99b 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -639,7 +639,7 @@ exit: } PyDoc_STRVAR(math_perm__doc__, -"perm($module, n, k, /)\n" +"perm($module, n, k=None, /)\n" "--\n" "\n" "Number of ways to choose k items from n items without repetition and with order.\n" @@ -647,6 +647,9 @@ PyDoc_STRVAR(math_perm__doc__, "Evaluates to n! / (n - k)! when k <= n and evaluates\n" "to zero when k > n.\n" "\n" +"If k is not specified or is None, then k defaults to n\n" +"and the function returns n!.\n" +"\n" "Raises TypeError if either of the arguments are not integers.\n" "Raises ValueError if either of the arguments are negative."); @@ -661,13 +664,17 @@ math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *n; - PyObject *k; + PyObject *k = Py_None; - if (!_PyArg_CheckPositional("perm", nargs, 2, 2)) { + if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) { goto exit; } n = args[0]; + if (nargs < 2) { + goto skip_optional; + } k = args[1]; +skip_optional: return_value = math_perm_impl(module, n, k); exit: @@ -713,4 +720,4 @@ math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=5004266613284dcc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0eb1e76a769cdd30 input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 9a9a815..ed11476 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -3002,7 +3002,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) math.perm n: object - k: object + k: object = None / Number of ways to choose k items from n items without repetition and with order. @@ -3010,18 +3010,24 @@ Number of ways to choose k items from n items without repetition and with order. Evaluates to n! / (n - k)! when k <= n and evaluates to zero when k > n. +If k is not specified or is None, then k defaults to n +and the function returns n!. + Raises TypeError if either of the arguments are not integers. Raises ValueError if either of the arguments are negative. [clinic start generated code]*/ static PyObject * math_perm_impl(PyObject *module, PyObject *n, PyObject *k) -/*[clinic end generated code: output=e021a25469653e23 input=b2e7729d9a1949cf]*/ +/*[clinic end generated code: output=e021a25469653e23 input=5311c5a00f359b53]*/ { PyObject *result = NULL, *factor = NULL; int overflow, cmp; long long i, factors; + if (k == Py_None) { + return math_factorial(module, n); + } n = PyNumber_Index(n); if (n == NULL) { return NULL; |