Skip to content

Commit

Permalink
More thorough testing of islice_extended
Browse files Browse the repository at this point in the history
  • Loading branch information
bbayles committed Jun 9, 2017
1 parent 343ed0f commit 523b99b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 54 deletions.
58 changes: 35 additions & 23 deletions more_itertools/more.py
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,11 @@ def islice_extended(iterable, *args):
j = max(len_iter + stop, 0)

# Slice the cache
for index, item in islice(cache, None, j - i, step):
n = j - i
if n <= 0:
return

for index, item in islice(cache, None, n, step):
yield item
elif (stop is not None) and (stop < 0):
# Advance to the start position
Expand All @@ -1464,34 +1468,42 @@ def islice_extended(iterable, *args):
for item in islice(it, start, stop, step):
yield item
else:
if (stop is not None) and (stop < 0):
# Consume all but the last -stop items
cache = deque(enumerate(it, 1), maxlen=-stop)
if ((start is None) or (start < 0)) and ((stop is None) or (stop < 0)):
# Consume all but the last items
n = None if (stop is None) else -stop - 1
cache = deque(enumerate(it, 1), maxlen=n)
len_iter = cache[-1][0] if cache else 0

# Adjust the index of the start to be negative and then slice
if start is None:
i = None
elif start >= 0:
i = None if (start >= len_iter) else start - len_iter
else:
i = start
for index, item in list(cache)[start:stop:step]:
yield item
elif ((start is None) or (start < 0)) and (stop >= 0):
# Advance to the stop position
n = stop + 1
next(islice(it, n, n), None)

for index, item in list(cache)[i:stop:step]:
for item in list(it)[start::step]:
yield item
elif (start >= 0) and ((stop is None) or (stop < 0)):
# Consume all but the last items
n = None if (stop is None) else -stop - 1
cache = deque(enumerate(it, 1), maxlen=n)
len_iter = cache[-1][0] if cache else 0

# Adjust start to be negative
i = min(start - len_iter, -1)

for index, item in list(cache)[i::step]:
yield item
else:
# Advance to the stop position
if stop is not None:
i = stop + 1
next(islice(it, i, i), None)
i = stop + 1
next(islice(it, i, i), None)

# Grab n items and reverse them
if (start is None) or (start < 0):
n = None
else:
n = start - stop
cache = reversed(list(islice(it, n)))
# Grab n items
n = start - stop
if n <= 0:
return
cache = list(islice(it, n))

# Slice the reversed cache
for item in islice(cache, None, None, -step):
for item in cache[::step]:
yield item
39 changes: 8 additions & 31 deletions more_itertools/tests/test_more.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from fractions import Fraction
from functools import reduce
from io import StringIO
from itertools import chain, count, groupby, permutations, repeat
from itertools import chain, count, groupby, permutations, product, repeat
from operator import itemgetter
from unittest import TestCase

Expand Down Expand Up @@ -1266,37 +1266,14 @@ def test_math(self):
class IsliceExtendedTests(TestCase):
def test_all(self):
iterable = ['0', '1', '2', '3', '4', '5']
indexes = list(range(-3, len(iterable) + 3))
steps = [1, 1]
for slice_args in product(indexes, indexes, steps):
try:
actual = list(islice_extended(iterable, *slice_args))
except Exception as e:
self.fail((slice_args, e))

for slice_args in [
(None, None, None),
(0, None, None),
(0, 0, None),
(0, 5, None),
(0, 6, None),
(None, 1, None),
(0, 2, None),
(0, -3, None),
(0, 4, None),
(0, -1, None),
(0, 6, None),
(1, None, None),
(2, 6, None),
(3, 6, None),
(-2, None, None),
(-1, None, None),
(1, -1, None),
(2, -2, None),
(3, -3, None),
(-5, 5, None),
(None, None, -1),
(None, None, 1),
(None, None, 2),
(None, None, 3),
(1, -1, 2),
(5, 1, -1),
(5, 1, -2),
]:
actual = list(islice_extended(iterable, *slice_args))
expected = iterable[slice(*slice_args)]
self.assertEqual(actual, expected, slice_args)

Expand Down

0 comments on commit 523b99b

Please sign in to comment.