Convert a string containing a column number range (unit-based slice) into a Python zero-based slice tuple (start, stop, step)
class ZeroBasedIndexWarning(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
mesg = 'unit-based slice indices start at 1, not 0'
return "'{}', {}.".format(self.value, mesg)
def getint(s):
"""
Unit-based integer (neg or pos, but not zero)
:raises: ValueError, ZeroBasedIndexWarning
"""
if s.strip() == '':
return None
value = int(s)
if value == 0:
raise ZeroBasedIndexWarning(value)
return value
def unit_to_zero_base_slice(slicestr):
"""
Convert a unit-based (not zero-indexed) slice string into a slice tuple
:returns: (start, stop, step) used to create a slice object
:raises: ValueError, ZeroBasedIndexWarning
>>> unit_to_zero_base_slice('2:9:2')
[1:9:2]
"""
# get unit-based slice indicies
slice_ = [_getint(s) for s in slicestr.split(':')]
# --- slice single item from sequence ---
if len(slice_) == 1:
if slice_[0] and slice_[0] > 0:
slice_.insert(0, slice_[0] - 1)
elif slice_[0] == -1:
slice_.append(None)
elif slice_[0]:
slice_.append(slice_[0] + 1)
# --- slice range notation ---
elif len(slice_) > 1:
if slice_[0] and slice_[0] > 0:
slice_[0] -= 1
if slice_[1] and slice_[1] < 0:
slice_[1] = None if slice_[1] == -1 else slice_[1] + 1
return tuple(slice_)