diff options
author | Alex Martelli <aleaxit@gmail.com> | 2003-04-22 08:12:33 (GMT) |
---|---|---|
committer | Alex Martelli <aleaxit@gmail.com> | 2003-04-22 08:12:33 (GMT) |
commit | a70b19147fd163744be34745d393af7be603629f (patch) | |
tree | 8ec1a2ae14cfae5fb3a3f14af05a9c9f60b3d739 | |
parent | 060641d51160f6bf49a049bb677f8412b5a19de3 (diff) | |
download | cpython-a70b19147fd163744be34745d393af7be603629f.zip cpython-a70b19147fd163744be34745d393af7be603629f.tar.gz cpython-a70b19147fd163744be34745d393af7be603629f.tar.bz2 |
Adding new built-in function sum, with docs and tests.
-rw-r--r-- | Doc/lib/libfuncs.tex | 8 | ||||
-rw-r--r-- | Doc/tut/tut.tex | 5 | ||||
-rw-r--r-- | Lib/test/test_builtin.py | 21 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Python/bltinmodule.c | 61 |
5 files changed, 98 insertions, 1 deletions
diff --git a/Doc/lib/libfuncs.tex b/Doc/lib/libfuncs.tex index 323a516..50f22f8 100644 --- a/Doc/lib/libfuncs.tex +++ b/Doc/lib/libfuncs.tex @@ -897,6 +897,14 @@ class C: \versionadded{2.2} \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}} Return the superclass of \var{type}. If the second argument is omitted the super object returned is unbound. If the second argument is an diff --git a/Doc/tut/tut.tex b/Doc/tut/tut.tex index 71d3f60..b227576 100644 --- a/Doc/tut/tut.tex +++ b/Doc/tut/tut.tex @@ -1819,6 +1819,9 @@ item, then to the result and the next item, and so on. For example, 0 \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} @@ -2502,7 +2505,7 @@ standard module \module{__builtin__}\refbimodindex{__builtin__}: 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', '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'] \end{verbatim} diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 3956214..e5c9770 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1099,6 +1099,27 @@ class BuiltinTest(unittest.TestCase): a[0] = a 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): self.assertEqual(tuple(()), ()) t0_3 = (0, 1, 2, 3) @@ -12,6 +12,10 @@ What's New in Python 2.3 beta 1? 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 raising an exception. This is consistent with calling the constructors for the other builtin types -- called without argument diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index adefba2..0eb8357 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1798,6 +1798,66 @@ PyDoc_STRVAR(vars_doc, Without arguments, equivalent to locals().\n\ 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 * builtin_isinstance(PyObject *self, PyObject *args) { @@ -2001,6 +2061,7 @@ static PyMethodDef builtin_methods[] = { {"repr", builtin_repr, METH_O, repr_doc}, {"round", builtin_round, METH_VARARGS, round_doc}, {"setattr", builtin_setattr, METH_VARARGS, setattr_doc}, + {"sum", builtin_sum, METH_VARARGS, sum_doc}, #ifdef Py_USING_UNICODE {"unichr", builtin_unichr, METH_VARARGS, unichr_doc}, #endif |