bpeterso2000
4/16/2014 - 11:58 PM

Convert a string containing a column number range (unit-based slice) into a Python zero-based slice tuple (start, stop, step)

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_)