I was working on a subtype of list
in python that acts as a list that should never raise an IndexError (every key you input that's greater than the length of the list gets wrapped around). I was having quite a few problems however implementing it properly for slices, who have a LOT of base cases. I wrote the following code to handle slices the way I want to (with example slices commented out);
class Cycle:
def __getitem__(self, key):
_self = self._container
n = len(self)
if isinstance(key, slice):
s = key.start
e = key.stop
stp = key.step
r = False
if stp is None:
stp = 1
elif stp == 0:
raise ValueError()
elif stp < 0:
r = True
stp = abs(stp)
if s and not e:
sliced = []
_len = n - s #[3:]
if s < 0:
#[-1:]
_len = abs(s)
elif s >= n:
#[7:]
_len = n - s % n
for i in range(0, _len, stp):
index = (i + s) % n
sliced.append(_self[index])
elif e and not s:
sliced = []
_len = e #[:4]
if e <= 0:
#[:-1]
_len = n - abs(e) % n
for i in range(0, _len, stp):
index = i % n
sliced.append(_self[index])
elif s and e:
sliced = []
if s <= e:
if s < 0 and e < 0:
#[-3:-1]
#[-7:-1]
_len = abs(s) - abs(e)
elif s < 0 and 0 <= e:
#[-1:3]
#[-7:8]
if n + s % n > e:
_len = e - s
else:
_len = e - (n + s)
elif 0 <= s and 0 <= e:
#[1:3]
#[7:19]
_len = e - s
elif s > e:
if s < 0 and e < 0:
#[-1:-3]
raise ValueError()
elif s >= 0 and e < 0:
if n + e < s:
#[4:-3]
raise ValueError()
_len = (n + e) - s #[1:-1]
elif 0 <= s and 0 <= e:
if s >= n:
if s % n <= e:
#[7:1]
_len = e - s % n
else:
#[7:3]
_len = n - s % n + e
else:
#[4:2]
_len = (n - s % n) + e
for i in range(0, _len, stp):
index = (i + s) % n
sliced.append(_self[index])
elif not (s or e):
sliced = _self[::stp]
if r:
sliced = sliced[::-1]
return sliced
else:
key %= n
return _self[key]
I can't think of any other more compact way to test for all the different cases that can occur. Can someone help me out please?