mirror of
https://github.com/python/cpython.git
synced 2025-07-24 19:54:21 +00:00
Adding new built-in function sum, with docs and tests.
This commit is contained in:
parent
060641d511
commit
a70b19147f
5 changed files with 98 additions and 1 deletions
|
@ -897,6 +897,14 @@ class C:
|
||||||
\versionadded{2.2}
|
\versionadded{2.2}
|
||||||
\end{funcdesc}
|
\end{funcdesc}
|
||||||
|
|
||||||
|
\begin{funcdesc}{sum}{sequence\optional{start=0}}
|
||||||
|
Sums up the items of a \var{sequence}, from left to right, and returns
|
||||||
|
the total. The \var{sequence}'s items are normally numbers, and are
|
||||||
|
not allowed to be strings. The fast, correct way to join up a
|
||||||
|
sequence of strings is by calling \code{''.join(\var{sequence})}.
|
||||||
|
\versionadded{2.3}
|
||||||
|
\end{funcdesc}
|
||||||
|
|
||||||
\begin{funcdesc}{super}{type\optional{object-or-type}}
|
\begin{funcdesc}{super}{type\optional{object-or-type}}
|
||||||
Return the superclass of \var{type}. If the second argument is omitted
|
Return the superclass of \var{type}. If the second argument is omitted
|
||||||
the super object returned is unbound. If the second argument is an
|
the super object returned is unbound. If the second argument is an
|
||||||
|
|
|
@ -1819,6 +1819,9 @@ item, then to the result and the next item, and so on. For example,
|
||||||
0
|
0
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
|
Don't use this example's definition of \code{sum}: since summing numbers
|
||||||
|
is such a common need, a built-in function \code{sum(\var{sequence})} is
|
||||||
|
already provided, and works exactly like this\versionadded{2,3}.
|
||||||
|
|
||||||
\subsection{List Comprehensions}
|
\subsection{List Comprehensions}
|
||||||
|
|
||||||
|
@ -2502,7 +2505,7 @@ standard module \module{__builtin__}\refbimodindex{__builtin__}:
|
||||||
'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min',
|
'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min',
|
||||||
'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit',
|
'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit',
|
||||||
'range', 'raw_input', 'reduce', 'reload', 'repr', 'round',
|
'range', 'raw_input', 'reduce', 'reload', 'repr', 'round',
|
||||||
'setattr', 'slice', 'staticmethod', 'str', 'string', 'super',
|
'setattr', 'slice', 'staticmethod', 'str', 'string', 'sum', 'super',
|
||||||
'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
|
'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
|
|
|
@ -1099,6 +1099,27 @@ class BuiltinTest(unittest.TestCase):
|
||||||
a[0] = a
|
a[0] = a
|
||||||
self.assertEqual(str(a), '{0: {...}}')
|
self.assertEqual(str(a), '{0: {...}}')
|
||||||
|
|
||||||
|
def test_sum(self):
|
||||||
|
self.assertEqual(sum([]), 0)
|
||||||
|
self.assertEqual(sum(range(2,8)), 27)
|
||||||
|
self.assertEqual(sum(iter(range(2,8))), 27)
|
||||||
|
self.assertEqual(sum(Squares(10)), 285)
|
||||||
|
self.assertEqual(sum(iter(Squares(10))), 285)
|
||||||
|
self.assertEqual(sum([[1], [2], [3]], []), [1, 2, 3])
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, sum)
|
||||||
|
self.assertRaises(TypeError, sum, 42)
|
||||||
|
self.assertRaises(TypeError, sum, ['a', 'b', 'c'])
|
||||||
|
self.assertRaises(TypeError, sum, ['a', 'b', 'c'], '')
|
||||||
|
self.assertRaises(TypeError, sum, [[1], [2], [3]])
|
||||||
|
self.assertRaises(TypeError, sum, [{2:3}])
|
||||||
|
self.assertRaises(TypeError, sum, [{2:3}]*2, {2:3})
|
||||||
|
|
||||||
|
class BadSeq:
|
||||||
|
def __getitem__(self, index):
|
||||||
|
raise ValueError
|
||||||
|
self.assertRaises(ValueError, sum, BadSeq())
|
||||||
|
|
||||||
def test_tuple(self):
|
def test_tuple(self):
|
||||||
self.assertEqual(tuple(()), ())
|
self.assertEqual(tuple(()), ())
|
||||||
t0_3 = (0, 1, 2, 3)
|
t0_3 = (0, 1, 2, 3)
|
||||||
|
|
|
@ -12,6 +12,10 @@ What's New in Python 2.3 beta 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- New builtin function sum(seq, start=0) returns the sum of all the
|
||||||
|
items in iterable object seq, plus start (items are normally numbers,
|
||||||
|
and cannot be strings).
|
||||||
|
|
||||||
- bool() called without arguments now returns False rather than
|
- bool() called without arguments now returns False rather than
|
||||||
raising an exception. This is consistent with calling the
|
raising an exception. This is consistent with calling the
|
||||||
constructors for the other builtin types -- called without argument
|
constructors for the other builtin types -- called without argument
|
||||||
|
|
|
@ -1798,6 +1798,66 @@ PyDoc_STRVAR(vars_doc,
|
||||||
Without arguments, equivalent to locals().\n\
|
Without arguments, equivalent to locals().\n\
|
||||||
With an argument, equivalent to object.__dict__.");
|
With an argument, equivalent to object.__dict__.");
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
builtin_sum(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *seq;
|
||||||
|
PyObject *result = NULL;
|
||||||
|
PyObject *temp, *item, *iter;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O|O:sum", &seq, &result))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
iter = PyObject_GetIter(seq);
|
||||||
|
if (iter == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (result == NULL) {
|
||||||
|
result = PyInt_FromLong(0);
|
||||||
|
if (result == NULL) {
|
||||||
|
Py_DECREF(iter);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* reject string values for 'start' parameter */
|
||||||
|
if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"can't sum strings [use ''.join(seq) instead]");
|
||||||
|
Py_DECREF(result);
|
||||||
|
Py_DECREF(iter);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
item = PyIter_Next(iter);
|
||||||
|
if (item == NULL) {
|
||||||
|
/* error, or end-of-sequence */
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
Py_DECREF(result);
|
||||||
|
result = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
temp = PyNumber_Add(result, item);
|
||||||
|
Py_DECREF(result);
|
||||||
|
Py_DECREF(item);
|
||||||
|
result = temp;
|
||||||
|
if (result == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Py_DECREF(iter);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(sum_doc,
|
||||||
|
"sum(sequence, start=0) -> value\n\
|
||||||
|
\n\
|
||||||
|
Returns the sum of a sequence of numbers (NOT strings) plus the value\n\
|
||||||
|
of parameter 'start'. When the sequence is empty, returns start.");
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
builtin_isinstance(PyObject *self, PyObject *args)
|
builtin_isinstance(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -2001,6 +2061,7 @@ static PyMethodDef builtin_methods[] = {
|
||||||
{"repr", builtin_repr, METH_O, repr_doc},
|
{"repr", builtin_repr, METH_O, repr_doc},
|
||||||
{"round", builtin_round, METH_VARARGS, round_doc},
|
{"round", builtin_round, METH_VARARGS, round_doc},
|
||||||
{"setattr", builtin_setattr, METH_VARARGS, setattr_doc},
|
{"setattr", builtin_setattr, METH_VARARGS, setattr_doc},
|
||||||
|
{"sum", builtin_sum, METH_VARARGS, sum_doc},
|
||||||
#ifdef Py_USING_UNICODE
|
#ifdef Py_USING_UNICODE
|
||||||
{"unichr", builtin_unichr, METH_VARARGS, unichr_doc},
|
{"unichr", builtin_unichr, METH_VARARGS, unichr_doc},
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue