Skip to content

Commit e119b3d

Browse files
authored
bpo-37178: Allow a one argument form of math.perm() (GH-13905)
1 parent 8cc605a commit e119b3d

File tree

6 files changed

+34
-9
lines changed

6 files changed

+34
-9
lines changed

Doc/library/math.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,17 @@ Number-theoretic and representation functions
210210
of *x* and are floats.
211211

212212

213-
.. function:: perm(n, k)
213+
.. function:: perm(n, k=None)
214214

215215
Return the number of ways to choose *k* items from *n* items
216216
without repetition and with order.
217217

218218
Evaluates to ``n! / (n - k)!`` when ``k <= n`` and evaluates
219219
to zero when ``k > n``.
220220

221+
If *k* is not specified or is None, then *k* defaults to *n*
222+
and the function returns ``n!``.
223+
221224
Raises :exc:`TypeError` if either of the arguments are not integers.
222225
Raises :exc:`ValueError` if either of the arguments are negative.
223226

Lib/test/test_math.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -1885,16 +1885,21 @@ def testPerm(self):
18851885
self.assertEqual(perm(n, 1), n)
18861886
self.assertEqual(perm(n, n), factorial(n))
18871887

1888+
# Test one argument form
1889+
for n in range(20):
1890+
self.assertEqual(perm(n), factorial(n))
1891+
self.assertEqual(perm(n, None), factorial(n))
1892+
18881893
# Raises TypeError if any argument is non-integer or argument count is
1889-
# not 2
1894+
# not 1 or 2
18901895
self.assertRaises(TypeError, perm, 10, 1.0)
18911896
self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
18921897
self.assertRaises(TypeError, perm, 10, "1")
18931898
self.assertRaises(TypeError, perm, 10.0, 1)
18941899
self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
18951900
self.assertRaises(TypeError, perm, "10", 1)
18961901

1897-
self.assertRaises(TypeError, perm, 10)
1902+
self.assertRaises(TypeError, perm)
18981903
self.assertRaises(TypeError, perm, 10, 1, 3)
18991904
self.assertRaises(TypeError, perm)
19001905

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
For math.perm(n, k), let k default to n, giving the same result as
2+
factorial.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Give math.perm() a one argument form that means the same as
2+
math.factorial().

Modules/clinic/mathmodule.c.h

+11-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/mathmodule.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -3002,26 +3002,32 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start)
30023002
math.perm
30033003
30043004
n: object
3005-
k: object
3005+
k: object = None
30063006
/
30073007
30083008
Number of ways to choose k items from n items without repetition and with order.
30093009
30103010
Evaluates to n! / (n - k)! when k <= n and evaluates
30113011
to zero when k > n.
30123012
3013+
If k is not specified or is None, then k defaults to n
3014+
and the function returns n!.
3015+
30133016
Raises TypeError if either of the arguments are not integers.
30143017
Raises ValueError if either of the arguments are negative.
30153018
[clinic start generated code]*/
30163019

30173020
static PyObject *
30183021
math_perm_impl(PyObject *module, PyObject *n, PyObject *k)
3019-
/*[clinic end generated code: output=e021a25469653e23 input=b2e7729d9a1949cf]*/
3022+
/*[clinic end generated code: output=e021a25469653e23 input=5311c5a00f359b53]*/
30203023
{
30213024
PyObject *result = NULL, *factor = NULL;
30223025
int overflow, cmp;
30233026
long long i, factors;
30243027

3028+
if (k == Py_None) {
3029+
return math_factorial(module, n);
3030+
}
30253031
n = PyNumber_Index(n);
30263032
if (n == NULL) {
30273033
return NULL;

0 commit comments

Comments
 (0)