def test_sequencetools_repeat_sequence_to_weight_at_most_01():

    assert sequencetools.repeat_sequence_to_weight_at_most([5, -5, -5], 23) == [5, -5, -5, 5]
def split_sequence_by_weights(sequence, weights, cyclic=False, overhang=False):
    '''Split sequence by weights.

    ..  container:: example

        **Example 1.** Split sequence cyclically by weights with overhang:

        ::

            >>> sequencetools.split_sequence_by_weights(
            ...     (10, -10, 10, -10), 
            ...     (3, 15, 3), 
            ...     cyclic=True, 
            ...     overhang=True,
            ...     )
            [(3,), (7, -8), (-2, 1), (3,), (6, -9), (-1,)]

    ..  container:: example
    
        **Example 2.** Split sequence cyclically by weights without overhang:

        ::

            >>> sequencetools.split_sequence_by_weights(
            ...     (10, -10, 10, -10), 
            ...     (3, 15, 3), 
            ...     cyclic=True, 
            ...     overhang=False,
            ...     )
            [(3,), (7, -8), (-2, 1), (3,), (6, -9)]

    ..  container:: example

        **Example 3.** Split sequence once by weights with overhang:

        ::

            >>> sequencetools.split_sequence_by_weights(
            ...     (10, -10, 10, -10), 
            ...     (3, 15, 3), 
            ...     cyclic=False, 
            ...     overhang=True,
            ...     )
            [(3,), (7, -8), (-2, 1), (9, -10)]

    ..  container:: example

        **Example 4.** Split sequence once by weights without overhang:

        ::

            >>> sequencetools.split_sequence_by_weights(
            ...     (10, -10, 10, -10), 
            ...     (3, 15, 3), 
            ...     cyclic=False, 
            ...     overhang=False,
            ...     )
            [(3,), (7, -8), (-2, 1)]

    Returns list of sequence types.
    '''
    from abjad.tools import sequencetools

    result = []
    current_index = 0
    current_piece = []

    if cyclic:
        weights = sequencetools.repeat_sequence_to_weight_at_most(weights, mathtools.weight(sequence))

    for weight in weights:
        current_piece_weight = mathtools.weight(current_piece)
        while current_piece_weight < weight:
            current_piece.append(sequence[current_index])
            current_index += 1
            current_piece_weight = mathtools.weight(current_piece)
        if current_piece_weight == weight:
            current_piece = type(sequence)(current_piece)
            result.append(current_piece)
            current_piece = []
        elif weight < current_piece_weight:
            overage = current_piece_weight - weight
            current_last_element = current_piece.pop(-1)
            needed = abs(current_last_element) - overage
            needed *= mathtools.sign(current_last_element)
            current_piece.append(needed)
            current_piece = type(sequence)(current_piece)
            result.append(current_piece)
            overage *= mathtools.sign(current_last_element)
            current_piece = [overage]

    if overhang:
        last_piece = current_piece
        last_piece.extend(sequence[current_index:])
        if last_piece:
            last_piece = type(sequence)(last_piece)
            result.append(last_piece)

    return result
def partition_sequence_by_counts(sequence, counts, cyclic=False, overhang=False, copy_elements=False):
    r"""Partition sequence by counts.
    
    ..  container:: example

        **Example 1a.** Partition sequence once by counts without overhang:

        ::

            >>> sequencetools.partition_sequence_by_counts(
            ...     range(10), 
            ...     [3], 
            ...     cyclic=False, 
            ...     overhang=False,
            ...     )
            [[0, 1, 2]]

    ..  container:: example

        **Example 1b.** Partition sequence once by counts without overhang:

        ::

            >>> sequencetools.partition_sequence_by_counts(
            ...     range(16), 
            ...     [4, 3], 
            ...     cyclic=False, 
            ...     overhang=False,
            ...     )
            [[0, 1, 2, 3], [4, 5, 6]]

    ..  container:: example

        **Example 2a.** Partition sequence cyclically by counts without 
        overhang:

        ::

            >>> sequencetools.partition_sequence_by_counts(
            ...     range(10), 
            ...     [3], 
            ...     cyclic=True, 
            ...     overhang=False,
            ...     )
            [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

    ..  container:: example

        **Example 2b.** Partition sequence cyclically by counts without 
        overhang:

        ::

            >>> sequencetools.partition_sequence_by_counts(
            ...     range(16), 
            ...     [4, 3], 
            ...     cyclic=True, 
            ...     overhang=False,
            ...     )
            [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9, 10], [11, 12, 13]]

    ..  container:: example

        **Example 3a.** Partition sequence once by counts with overhang:

        ::

            >>> sequencetools.partition_sequence_by_counts(
            ...     range(10), 
            ...     [3], 
            ...     cyclic=False, 
            ...     overhang=True,
            ...     )
            [[0, 1, 2], [3, 4, 5, 6, 7, 8, 9]]

    ..  container:: example

        **Example 3b.** Partition sequence once by counts with overhang:

        ::

            >>> sequencetools.partition_sequence_by_counts(
            ...     range(16), 
            ...     [4, 3], 
            ...     cyclic=False, 
            ...     overhang=True,
            ...     )
            [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9, 10, 11, 12, 13, 14, 15]]

    ..  container:: example

        **Example 4a.** Partition sequence cyclically by counts with overhang:

        ::

            >>> sequencetools.partition_sequence_by_counts(
            ...     range(10), 
            ...     [3], 
            ...     cyclic=True, 
            ...     overhang=True,
            ...     )
            [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

    ..  container:: example

        **Example 4b.** Partition sequence cyclically by counts with overhang:

        ::

            >>> sequencetools.partition_sequence_by_counts(
            ...     range(16), 
            ...     [4, 3], 
            ...     cyclic=True, 
            ...     overhang=True,
            ...     )
            [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9, 10], [11, 12, 13], [14, 15]]

    Returns list of sequence objects.
    """
    from abjad.tools import sequencetools

    result = []

    if cyclic:
        if overhang:
            counts = sequencetools.repeat_sequence_to_weight_exactly(counts, len(sequence))
        else:
            counts = sequencetools.repeat_sequence_to_weight_at_most(counts, len(sequence))
    elif overhang:
        weight_counts = mathtools.weight(counts)
        len_sequence = len(sequence)
        if weight_counts < len_sequence:
            counts = list(counts)
            counts.append(len(sequence) - weight_counts)

    for start, stop in mathtools.cumulative_sums_pairwise(counts):
        result.append(type(sequence)(sequence[start:stop]))

    return result