Kaydet (Commit) ee33b27e authored tarafından Raymond Hettinger's avatar Raymond Hettinger

Make deque.rotate() smarter. Beef-up related tests.

üst 3b6d025d
...@@ -41,16 +41,50 @@ class TestBasic(unittest.TestCase): ...@@ -41,16 +41,50 @@ class TestBasic(unittest.TestCase):
self.assertEqual(list(d), list(reversed('abcd'))) self.assertEqual(list(d), list(reversed('abcd')))
def test_rotate(self): def test_rotate(self):
s = 'abcde' s = tuple('abcde')
n = len(s)
d = deque(s)
d.rotate(1) # verify rot(1)
self.assertEqual(''.join(d), 'eabcd')
d = deque(s)
d.rotate(-1) # verify rot(-1)
self.assertEqual(''.join(d), 'bcdea')
d.rotate() # check default to 1
self.assertEqual(tuple(d), s)
for i in xrange(n*3):
d = deque(s)
e = deque(d)
d.rotate(i) # check vs. rot(1) n times
for j in xrange(i):
e.rotate(1)
self.assertEqual(tuple(d), tuple(e))
d.rotate(-i) # check that it works in reverse
self.assertEqual(tuple(d), s)
e.rotate(n-i) # check that it wraps forward
self.assertEqual(tuple(e), s)
for i in xrange(n*3):
d = deque(s)
e = deque(d)
d.rotate(-i)
for j in xrange(i):
e.rotate(-1) # check vs. rot(-1) n times
self.assertEqual(tuple(d), tuple(e))
d.rotate(i) # check that it works in reverse
self.assertEqual(tuple(d), s)
e.rotate(i-n) # check that it wraps backaround
self.assertEqual(tuple(e), s)
d = deque(s) d = deque(s)
d.rotate(2) e = deque(s)
self.assertEqual(''.join(d), 'deabc') e.rotate(BIG+17) # verify on long series of rotates
d.rotate(3) dr = d.rotate
self.assertEqual(''.join(d), s) for i in xrange(BIG+17):
d.rotate(-3) dr()
self.assertEqual(''.join(d), 'deabc') self.assertEqual(tuple(d), tuple(e))
d.rotate(-15)
self.assertEqual(''.join(d), 'deabc')
def test_len(self): def test_len(self):
d = deque('ab') d = deque('ab')
......
...@@ -247,14 +247,21 @@ PyDoc_STRVAR(extendleft_doc, ...@@ -247,14 +247,21 @@ PyDoc_STRVAR(extendleft_doc,
static PyObject * static PyObject *
deque_rotate(dequeobject *deque, PyObject *args) deque_rotate(dequeobject *deque, PyObject *args)
{ {
int i, n; int i, n=1, len=deque->len, halflen=(len+1)>>1;
PyObject *item, *rv; PyObject *item, *rv;
if (!PyArg_ParseTuple(args, "i:rotate", &n)) if (!PyArg_ParseTuple(args, "|i:rotate", &n))
return NULL; return NULL;
if (n == 0 || deque->len == 0) if (len == 0)
Py_RETURN_NONE; Py_RETURN_NONE;
if (n > halflen || n < -halflen) {
n %= len;
if (n > halflen)
n -= len;
else if (n < -halflen)
n += len;
}
for (i=0 ; i<n ; i++) { for (i=0 ; i<n ; i++) {
item = deque_pop(deque, NULL); item = deque_pop(deque, NULL);
...@@ -280,7 +287,7 @@ deque_rotate(dequeobject *deque, PyObject *args) ...@@ -280,7 +287,7 @@ deque_rotate(dequeobject *deque, PyObject *args)
} }
PyDoc_STRVAR(rotate_doc, PyDoc_STRVAR(rotate_doc,
"Rotate the deque n steps to the right. If n is negative, rotates left."); "Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
static int static int
deque_len(dequeobject *deque) deque_len(dequeobject *deque)
......
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