Kaydet (Commit) a70b1914 authored tarafından Alex Martelli's avatar Alex Martelli

Adding new built-in function sum, with docs and tests.

üst 060641d5
...@@ -897,6 +897,14 @@ class C: ...@@ -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, ...@@ -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__}: ...@@ -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): ...@@ -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? ...@@ -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, ...@@ -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[] = { ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment