def normalize_slice(e, n):
    """
    Return the slice tuple normalized for an ``n``-element object.

    :param e: a slice object representing a selector
    :param n: number of elements in a sequence to which ``e`` is applied
    :returns: tuple ``(start, count, step)`` derived from ``e``.
    """
    if n == 0:
        return (0, 0, 1)

    step = e.step
    if step is None:
        step = 1
    if step == 0:
        start = e.start
        count = e.stop
        if isinstance(start, int) and isinstance(count, int) and count >= 0:
            if start < 0:
                start += n
            if start < 0:
                return (0, 0, 0)
            return (start, count, 0)
        else:
            raise ValueError("Invalid slice %r" % e)
    assert isinstance(step, int) and step != 0

    if e.start is None:
        start = 0 if step > 0 else n - 1
    else:
        start = e.start
        if start < 0:
            start += n
        if (start < 0 and step < 0) or (start >= n and step > 0):
            return (0, 0, 0)
        start = min(max(0, start), n - 1)
    assert isinstance(start, int) and 0 <= start < n, \
        "Invalid start: %r" % start

    if e.stop is None:
        if step > 0:
            count = (n - 1 - start) // step + 1
        else:
            count = (start // -step) + 1
    else:
        stop = e.stop
        if stop < 0:
            stop += n
        if step > 0:
            if stop > start:
                count = (min(n, stop) - 1 - start) // step + 1
            else:
                count = 0
        else:
            if stop < start:
                count = (start - max(stop, -1) - 1) // -step + 1
            else:
                count = 0
    assert isinstance(count, int) and count >= 0
    assert count == 0 or 0 <= start + step * (count - 1) < n, \
        "Wrong tuple: (%d, %d, %d)" % (start, count, step)

    return (start, count, step)
def normalize_slice ( e , n ) : if n == 0 : return ( 0 , 0 , 1 ) step = e . step if step is None : step = 1 if step == 0 : start = e . start count = e . stop if isinstance ( start , int ) and isinstance ( count , int ) and count >= 0 : if start < 0 : start += n if start < 0 : return ( 0 , 0 , 0 ) return ( start , count , 0 ) else : raise ValueError ( "Invalid slice %r" % e ) assert isinstance ( step , int ) and step != 0 if e . start is None : start = 0 if step > 0 else n - 1 else : start = e . start if start < 0 : start += n if ( start < 0 and step < 0 ) or ( start >= n and step > 0 ) : return ( 0 , 0 , 0 ) start = min ( max ( 0 , start ) , n - 1 ) assert isinstance ( start , int ) and 0 <= start < n , "Invalid start: %r" % start if e . stop is None : if step > 0 : count = ( n - 1 - start ) // step + 1 else : count = ( start // - step ) + 1 else : stop = e . stop if stop < 0 : stop += n if step > 0 : if stop > start : count = ( min ( n , stop ) - 1 - start ) // step + 1 else : count = 0 else : if stop < start : count = ( start - max ( stop , - 1 ) - 1 ) // - step + 1 else : count = 0 assert isinstance ( count , int ) and count >= 0 assert count == 0 or 0 <= start + step * ( count - 1 ) < n , "Wrong tuple: (%d, %d, %d)" % ( start , count , step ) return ( start , count , step )
Return the slice tuple normalized for an ``n``-element object.

    :param e: a slice object representing a selector
    :param n: number of elements in a sequence to which ``e`` is applied
    :returns: tuple ``(start, count, step)`` derived from ``e``.