def __call__(self, items=None): r'''Calls sequence expression on `items`. Makes sequence from `items`. Then applies callbacks to sequence. Returns sequence. ''' from abjad.tools import sequencetools if items is None: #result = sequencetools.Sequence() result = self._client_class() else: #result = sequencetools.Sequence(items) result = self._client_class(items) callbacks = self.callbacks or () map_next = False for callback in callbacks: if callback.name == 'Sequence.__init__': result = sequencetools.Sequence(result) map_next = False elif callback.name == 'map': map_next = True else: if map_next: class_ = type(result) result = class_([callback(_) for _ in result]) else: result = callback(result) map_next = False return result
def rotate_sequence(sequence, n): '''Rotates `sequence`. Rotates `sequence` to the right: :: >>> sequencetools.rotate_sequence(list(range(10)), 4) [6, 7, 8, 9, 0, 1, 2, 3, 4, 5] Rotates `sequence` to the left: :: >>> sequencetools.rotate_sequence(list(range(10)), -3) [3, 4, 5, 6, 7, 8, 9, 0, 1, 2] Rotates `sequence` neither to the right nor the left: :: >>> sequencetools.rotate_sequence(list(range(10)), 0) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Returns newly created `sequence` object. ''' from abjad.tools import sequencetools result = sequencetools.Sequence(*sequence) result = result.rotate(n) return type(sequence)(result)
def reverse_sequence(sequence): '''Reverses `sequence`. .. container:: example **Example 1.** Reverses tuple: :: >>> sequencetools.reverse_sequence((1, 2, 3, 4, 5)) (5, 4, 3, 2, 1) .. container:: example **Example 2.** Reverses list: :: >>> sequencetools.reverse_sequence([1, 2, 3, 4, 5]) [5, 4, 3, 2, 1] Returns new object of `sequence` type. ''' from abjad.tools import sequencetools if not isinstance(sequence, collections.Sequence): message = 'must by sequence {!r}.' message = message.format(sequence) raise Exception(message) sequence_type = type(sequence) result = sequencetools.Sequence(sequence).reverse() result = sequence_type(result) return result
def permute_sequence(sequence, permutation): '''Permutes `sequence`. :: >>> sequencetools.permute_sequence([10, 11, 12, 13, 14, 15], [5, 4, 0, 1, 2, 3]) [15, 14, 10, 11, 12, 13] Returns new object of `sequence` type. ''' from abjad.tools import sequencetools if not sequencetools.Sequence(*permutation).is_permutation() or \ len(sequence) != len(permutation): message = '{!r} must be permutation of length {}.' message = message.format(permutation, len(sequence)) raise TypeError(message) result = [] for index in permutation: new_element = copy.copy(sequence[index]) result.append(new_element) if isinstance(sequence, str): return ''.join(result) else: return type(sequence)(result)
def yield_all_permutations_of_sequence_in_orbit(sequence, permutation): '''Yields all permutations of `sequence` in orbit of `permutation`. :: >>> list(sequencetools.yield_all_permutations_of_sequence_in_orbit( ... (1, 2, 3, 4), [1, 2, 3, 0])) [(1, 2, 3, 4), (2, 3, 4, 1), (3, 4, 1, 2), (4, 1, 2, 3)] Returns permutations in lex order. Returns generator of `sequence` objects. ''' from abjad.tools import sequencetools if not sequencetools.Sequence(*permutation).is_permutation() or \ len(sequence) != len(permutation): args = (str(permutation), len(sequence)) message = '{!r} must be permutation of length {}.' message = message.format(permutation, len(sequence)) raise TypeError(message) # return identity first next_permutation = sequencetools.permute_sequence(sequence, range(len(sequence))) yield next_permutation # then return remaining permutations in orbit of permutation while True: next_permutation = sequencetools.permute_sequence( next_permutation, permutation) if next_permutation == sequence: break else: yield next_permutation
def rotate_sequence(sequence, index=None): '''Rotates `sequence`. .. container:: example **Example 1.** Rotates `sequence` to the right: :: >>> sequencetools.rotate_sequence(list(range(10)), 4) [6, 7, 8, 9, 0, 1, 2, 3, 4, 5] .. container:: example **Example 2.** Rotates `sequence` to the left: :: >>> sequencetools.rotate_sequence(list(range(10)), -3) [3, 4, 5, 6, 7, 8, 9, 0, 1, 2] .. container:: example **Example 3.** Rotates `sequence` neither to the right nor the left: :: >>> sequencetools.rotate_sequence(list(range(10)), 0) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] .. container:: example **Example 4.** Rotates ratio numbers: :: >>> ratio = mathtools.Ratio((1, 2, 3, 4, 5)) >>> sequencetools.rotate_sequence(ratio.numbers, 2) (4, 5, 1, 2, 3) .. container:: example **Example 5.** Rotates interval segment: :: >>> interval_segment = pitchtools.IntervalSegment((-1, 3, 2, 7)) >>> sequencetools.rotate_sequence(interval_segment, -1) IntervalSegment([3, 2, 7, -1]) Returns new object of `sequence` type. ''' from abjad.tools import sequencetools sequence_type = type(sequence) result = sequencetools.Sequence(sequence) result = result.rotate(index=index) result = sequence_type(result) return result
def reverse_sequence(sequence): '''Reverses `sequence`. :: >>> sequencetools.reverse_sequence((1, 2, 3, 4, 5)) (5, 4, 3, 2, 1) Returns new `sequence` object. ''' from abjad.tools import sequencetools result = sequencetools.Sequence(*sequence).reverse() return type(sequence)(result)
def rotate_sequence(sequence, n): '''Rotates `sequence`. Rotates `sequence` to the right: :: >>> sequencetools.rotate_sequence(list(range(10)), 4) [6, 7, 8, 9, 0, 1, 2, 3, 4, 5] Rotates `sequence` to the left: :: >>> sequencetools.rotate_sequence(list(range(10)), -3) [3, 4, 5, 6, 7, 8, 9, 0, 1, 2] Rotates `sequence` neither to the right nor the left: :: >>> sequencetools.rotate_sequence(list(range(10)), 0) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Rotates ratio: :: >>> ratio = mathtools.Ratio((1, 2, 3, 4, 5)) >>> sequencetools.rotate_sequence(ratio, 2) Ratio((4, 5, 1, 2, 3)) Rotates interval segment: :: >>> interval_segment = pitchtools.IntervalSegment((-1, 3, 2, 7)) >>> sequencetools.rotate_sequence(interval_segment, -1) IntervalSegment([3, 2, 7, -1]) Returns newly created `sequence` object. ''' from abjad.tools import sequencetools result = sequencetools.Sequence(*sequence) result = result.rotate(n) return type(sequence)(result)
def partition_sequence_by_restricted_growth_function( sequence, restricted_growth_function, ): '''Partitions `sequence` by `restricted_growth_function`. :: >>> l = range(10) >>> rgf = [1, 1, 2, 2, 1, 2, 3, 3, 2, 4] :: >>> sequencetools.partition_sequence_by_restricted_growth_function( ... l, rgf) [[0, 1, 4], [2, 3, 5, 8], [6, 7], [9]] Raises value error when `sequence` length does not equal `restricted_growth_function` length. Returns list of lists. ''' from abjad.tools import sequencetools restricted_growth_function = sequencetools.Sequence( restricted_growth_function) if not restricted_growth_function.is_restricted_growth_function(): message = 'must be restricted growth function: {!r}.' message = message.format(restricted_growth_function) raise ValueError(message) if not len(sequence) == len(restricted_growth_function): message = 'lengths must be equal.' raise ValueError(message) partition = [] for part_index in range(max(restricted_growth_function)): part = [] partition.append(part) for n, part_number in zip(sequence, restricted_growth_function): part_index = part_number - 1 part = partition[part_index] part.append(n) return partition
def __init__(self, sequence=None): from abjad.tools import quantizationtools q_event_classes = ( quantizationtools.PitchedQEvent, quantizationtools.SilentQEvent, ) #sequence = sequence or [] if sequence is None: self._sequence = () return else: assert 1 < len(sequence) assert all(isinstance(q_event, q_event_classes) for q_event in sequence[:-1]) assert isinstance(sequence[-1], quantizationtools.TerminalQEvent) offsets = [x.offset for x in sequence] offsets = sequencetools.Sequence(offsets) assert offsets.is_increasing(strict=False) assert 0 <= sequence[0].offset self._sequence = tuple(sequence)
def permute_sequence(sequence, permutation): '''Permutes `sequence`. :: >>> sequencetools.permute_sequence([10, 11, 12, 13, 14, 15], [5, 4, 0, 1, 2, 3]) [15, 14, 10, 11, 12, 13] Permutes references to `sequence` elements; does not copy `sequence` elements. Returns new object of `sequence` type. ''' from abjad.tools import sequencetools if not isinstance(sequence, collections.Sequence): message = 'must by sequence {!r}.' message = message.format(sequence) raise Exception(message) sequence_type = type(sequence) if not sequencetools.Sequence(permutation).is_permutation() or \ len(sequence) != len(permutation): message = '{!r} must be permutation of length {}.' message = message.format(permutation, len(sequence)) raise TypeError(message) result = [] for index in permutation: new_element = sequence[index] result.append(new_element) if isinstance(sequence, str): result = ''.join(result) result = sequence_type(result) return result
def sequence(expr=None): r'''Makes sequence or sequence expression. .. container:: example **Example 1.** Makes sequence: :: >>> sequence([1, 2, [3, [4]], 5]) Sequence((1, 2, [3, [4]], 5)) .. container:: example **Example 2.** Flattens, reverses and slices sequence: :: >>> sequence_ = sequence([1, 2, [3, [4]], 5]) >>> sequence_ Sequence((1, 2, [3, [4]], 5)) :: >>> sequence_ = sequence_.flatten() >>> sequence_ Sequence((1, 2, 3, 4, 5)) :: >>> sequence_ = sequence_.reverse() >>> sequence_ Sequence((5, 4, 3, 2, 1)) :: >>> sequence_ = sequence_[-3:] >>> sequence_ Sequence((3, 2, 1)) .. container:: example **Example 3.** Makes sequence expression: :: >>> sequence() SequenceExpression() .. container:: example **Example 4.** Makes expression to flatten, reverse and slice sequence: :: >>> expression = sequence() >>> expression = expression.flatten() >>> expression = expression.reverse() >>> expression = expression[-3:] :: >>> print(format(expression)) expressiontools.SequenceExpression( callbacks=( expressiontools.Callback( name='Sequence.flatten', arguments=[ ('classes', None), ('depth', -1), ('indices', None), ], ), expressiontools.Callback( name='Sequence.reverse', ), expressiontools.Callback( name='Sequence.__getitem__', arguments=[ ( 'i', slice(-3, None, None), ), ], ), ), ) Works with numbers: :: >>> expression([1, 2, [3, [4]], 5]) Sequence((3, 2, 1)) Works with divisions: :: >>> divisions = [(1, 8), (2, 8), (3, 8), (4, 8), (5, 8)] >>> divisions = [durationtools.Division(_) for _ in divisions] >>> expression(divisions) Sequence((Division((3, 8)), Division((2, 8)), Division((1, 8)))) Input argument to expression need not be available in Abjad global namespace. Returns sequence when `expr` is not none. Returns sequence expression when `expr` is none. ''' from abjad.tools import expressiontools from abjad.tools import sequencetools if expr is None: return expressiontools.SequenceExpression() else: return sequencetools.Sequence(expr)