bpo-35431: Drop the k <= n requirement (GH-13798)

This commit is contained in:
Raymond Hettinger 2019-06-04 01:23:06 -07:00 committed by GitHub
parent 0fd2c300c2
commit 963eb0f473
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 38 deletions

View File

@ -41,12 +41,15 @@ Number-theoretic and representation functions
Return the number of ways to choose *k* items from *n* items without repetition
and without order.
Also called the binomial coefficient. It is mathematically equal to the expression
``n! / (k! (n - k)!)``. It is equivalent to the coefficient of the *k*-th term in the
polynomial expansion of the expression ``(1 + x) ** n``.
Evaluates to ``n! / (k! * (n - k)!)`` when ``k <= n`` and evaluates
to zero when ``k > n``.
Raises :exc:`TypeError` if the arguments not integers.
Raises :exc:`ValueError` if the arguments are negative or if *k* > *n*.
Also called the binomial coefficient because it is equivalent
to the coefficient of k-th term in polynomial expansion of the
expression ``(1 + x) ** n``.
Raises :exc:`TypeError` if either of the arguments not integers.
Raises :exc:`ValueError` if either of the arguments are negative.
.. versionadded:: 3.8
@ -212,10 +215,11 @@ Number-theoretic and representation functions
Return the number of ways to choose *k* items from *n* items
without repetition and with order.
It is mathematically equal to the expression ``n! / (n - k)!``.
Evaluates to ``n! / (n - k)!`` when ``k <= n`` and evaluates
to zero when ``k > n``.
Raises :exc:`TypeError` if the arguments not integers.
Raises :exc:`ValueError` if the arguments are negative or if *k* > *n*.
Raises :exc:`TypeError` if either of the arguments not integers.
Raises :exc:`ValueError` if either of the arguments are negative.
.. versionadded:: 3.8

View File

@ -1904,9 +1904,9 @@ class IsCloseTests(unittest.TestCase):
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)
# Returns zero if k is greater than n
self.assertEqual(perm(1, 2), 0)
self.assertEqual(perm(1, 2**1000), 0)
n = 2**1000
self.assertEqual(perm(n, 0), 1)
@ -1970,9 +1970,9 @@ class IsCloseTests(unittest.TestCase):
self.assertRaises(ValueError, comb, 1, -1)
self.assertRaises(ValueError, comb, 1, -2**1000)
# Raises value error if k is greater than n
self.assertRaises(ValueError, comb, 1, 2)
self.assertRaises(ValueError, comb, 1, 2**1000)
# Returns zero if k is greater than n
self.assertEqual(comb(1, 2), 0)
self.assertEqual(comb(1, 2**1000), 0)
n = 2**1000
self.assertEqual(comb(n, 0), 1)

View File

@ -644,10 +644,11 @@ PyDoc_STRVAR(math_perm__doc__,
"\n"
"Number of ways to choose k items from n items without repetition and with order.\n"
"\n"
"It is mathematically equal to the expression n! / (n - k)!.\n"
"Evaluates to n! / (n - k)! when k <= n and evaluates\n"
"to zero when k > n.\n"
"\n"
"Raises TypeError if the arguments are not integers.\n"
"Raises ValueError if the arguments are negative or if k > n.");
"Raises TypeError if either of the arguments are not integers.\n"
"Raises ValueError if either of the arguments are negative.");
#define MATH_PERM_METHODDEF \
{"perm", (PyCFunction)(void(*)(void))math_perm, METH_FASTCALL, math_perm__doc__},
@ -679,12 +680,15 @@ PyDoc_STRVAR(math_comb__doc__,
"\n"
"Number of ways to choose k items from n items without repetition and without order.\n"
"\n"
"Also called the binomial coefficient. It is mathematically equal to the expression\n"
"n! / (k! * (n - k)!). It is equivalent to the coefficient of k-th term in\n"
"polynomial expansion of the expression (1 + x)**n.\n"
"Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n"
"to zero when k > n.\n"
"\n"
"Raises TypeError if the arguments are not integers.\n"
"Raises ValueError if the arguments are negative or if k > n.");
"Also called the binomial coefficient because it is equivalent\n"
"to the coefficient of k-th term in polynomial expansion of the\n"
"expression (1 + x)**n.\n"
"\n"
"Raises TypeError if either of the arguments are not integers.\n"
"Raises ValueError if either of the arguments are negative.");
#define MATH_COMB_METHODDEF \
{"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL, math_comb__doc__},
@ -709,4 +713,4 @@ math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
/*[clinic end generated code: output=a82b0e705b6d0ec0 input=a9049054013a1b77]*/
/*[clinic end generated code: output=5004266613284dcc input=a9049054013a1b77]*/

View File

@ -3007,15 +3007,16 @@ math.perm
Number of ways to choose k items from n items without repetition and with order.
It is mathematically equal to the expression n! / (n - k)!.
Evaluates to n! / (n - k)! when k <= n and evaluates
to zero when k > n.
Raises TypeError if the arguments are not integers.
Raises ValueError if the arguments are negative or if k > 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=f71ee4f6ff26be24]*/
/*[clinic end generated code: output=e021a25469653e23 input=b2e7729d9a1949cf]*/
{
PyObject *result = NULL, *factor = NULL;
int overflow, cmp;
@ -3052,8 +3053,8 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k)
cmp = PyObject_RichCompareBool(n, k, Py_LT);
if (cmp != 0) {
if (cmp > 0) {
PyErr_SetString(PyExc_ValueError,
"k must be an integer less than or equal to n");
result = PyLong_FromLong(0);
goto done;
}
goto error;
}
@ -3121,18 +3122,21 @@ math.comb
Number of ways to choose k items from n items without repetition and without order.
Also called the binomial coefficient. It is mathematically equal to the expression
n! / (k! * (n - k)!). It is equivalent to the coefficient of k-th term in
polynomial expansion of the expression (1 + x)**n.
Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates
to zero when k > n.
Raises TypeError if the arguments are not integers.
Raises ValueError if the arguments are negative or if k > n.
Also called the binomial coefficient because it is equivalent
to the coefficient of k-th term in polynomial expansion of the
expression (1 + x)**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_comb_impl(PyObject *module, PyObject *n, PyObject *k)
/*[clinic end generated code: output=bd2cec8d854f3493 input=2f336ac9ec8242f9]*/
/*[clinic end generated code: output=bd2cec8d854f3493 input=9a05315af2518709]*/
{
PyObject *result = NULL, *factor = NULL, *temp;
int overflow, cmp;
@ -3173,9 +3177,8 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k)
}
if (Py_SIZE(temp) < 0) {
Py_DECREF(temp);
PyErr_SetString(PyExc_ValueError,
"k must be an integer less than or equal to n");
goto error;
result = PyLong_FromLong(0);
goto done;
}
cmp = PyObject_RichCompareBool(temp, k, Py_LT);
if (cmp > 0) {