def __and__(self, timespan):
        r'''Logical AND of payload expression and `timespan`.

        ::

            >>> timespan = timespantools.Timespan((1, 16), (5, 16))
            >>> result = payload_expression & timespan

        ::

            >>> print result.storage_format
            timespantools.TimespanInventory([
                musicexpressiontools.IterablePayloadExpression(
                    payload=(Division('[3, 16]', start_offset=Offset(1, 16)),
                    Division('[1, 16]', start_offset=Offset(1, 4)))
                    )
                ])

        Returns newly constructed payload expression.
        '''
        from experimental.tools import musicexpressiontools
        if not sequencetools.all_are_numbers(self.payload):
            payload = [mathtools.NonreducedFraction(x) for x in self.payload]
        else:
            payload = self.payload
        division_payload_expression = \
            musicexpressiontools.StartPositionedDivisionPayloadExpression(
            payload=payload, start_offset=0, voice_name='dummy voice name')
        result = division_payload_expression & timespan
        assert len(result) in (0, 1)
        if result:
            divisions = result[0].payload.divisions
            expression = self.new(payload=divisions)
            result[0] = expression
        return result
    def repeat_to_duration(self, duration):
        r'''Repeat payload expression to duration.

        ::

            >>> result = \
            ...     payload_expression.repeat_to_duration(Duration(13, 16))

        ::

            >>> print result.storage_format
            musicexpressiontools.IterablePayloadExpression(
                payload=(NonreducedFraction(4, 16),
                NonreducedFraction(2, 16),
                NonreducedFraction(4, 16),
                NonreducedFraction(2, 16),
                NonreducedFraction(1, 16))
                )

        Returns newly constructed payload expression.
        '''
        if not sequencetools.all_are_numbers(self.payload):
            payload = [mathtools.NonreducedFraction(x) for x in self.payload]
        else:
            payload = self.payload
        payload = sequencetools.repeat_sequence_to_weight_exactly(
            payload, duration)
        result = self.new(payload=payload)
        return result
def pair_duration_sequence_elements_with_input_pair_values(duration_sequence, input_pairs):
    r'''Pair `duration_sequence` elements with the values of `input_pairs`:

    ::

        >>> duration_sequence = [10, 10, 10, 10]
        >>> input_pairs = [('red', 1), ('orange', 18), ('yellow', 200)]

    ::

        >>> sequencetools.pair_duration_sequence_elements_with_input_pair_values(
        ... duration_sequence, input_pairs)
        [(10, 'red'), (10, 'orange'), (10, 'yellow'), (10, 'yellow')]

    Returns a list of ``(element, value)`` output pairs.

    The `input_pairs` argument must be a list of ``(value, duration)`` pairs.

    The basic idea behind the function is model which input pair
    value is in effect at the start of each element in `duration_sequence`.
    '''
    from abjad.tools import sequencetools

    assert sequencetools.all_are_numbers(duration_sequence)
    assert sequencetools.all_are_pairs(input_pairs)

    output_pairs = []
    current_element_start = 0
    current_input_pair_index = 0
    current_input_pair = input_pairs[current_input_pair_index]
    current_input_pair_value = current_input_pair[0]
    current_input_pair_duration = current_input_pair[-1]
    current_input_pair_start = 0
    current_input_pair_stop = current_input_pair_start + current_input_pair_duration

    for element in duration_sequence:
        while current_input_pair_stop <= current_element_start:
            current_input_pair_index += 1
            current_input_pair = input_pairs[current_input_pair_index]
            current_input_pair_value = current_input_pair[0]
            current_input_pair_duration = current_input_pair[-1]
            current_input_pair_start = current_input_pair_stop
            current_input_pair_stop += current_input_pair_duration
        output_pair = (element, current_input_pair_value)
        output_pairs.append(output_pair)
        current_element_start += element

    return output_pairs