def order_by(self, segment): """ Orders pitch-class set by pitch-class `segment`. .. container:: example >>> set_ = abjad.PitchClassSet(['c', 'e', 'b']) >>> segment = abjad.PitchClassSegment(['e', 'a', 'f']) >>> set_.order_by(segment) PitchClassSegment("b e c") Returns pitch-class segment. """ import abjad if not len(self) == len(segment): message = "set and segment must be on equal length." raise ValueError(message) enumerator = Enumerator(self) for pitch_classes in enumerator.yield_permutations(): candidate = abjad.PitchClassSegment(pitch_classes) if candidate._is_equivalent_under_transposition(segment): return candidate message = "{!s} can not order by {!s}." message = message.format(self, segment) raise ValueError(message)
def order_by(self, segment): """ Orders pitch-class set by pitch-class `segment`. .. container:: example >>> set_ = abjad.PitchClassSet(['c', 'e', 'b']) >>> segment = abjad.PitchClassSegment(['e', 'a', 'f']) >>> set_.order_by(segment) PitchClassSegment("b e c") Returns pitch-class segment. """ import abjad if not len(self) == len(segment): message = 'set and segment must be on equal length.' raise ValueError(message) enumerator = Enumerator(self) for pitch_classes in enumerator.yield_permutations(): candidate = abjad.PitchClassSegment(pitch_classes) if candidate._is_equivalent_under_transposition(segment): return candidate message = '{!s} can not order by {!s}.' message = message.format(self, segment) raise ValueError(message)
def __init__(self, items=None, item_class=None): import abjad prototype = ( abjad.PitchClassSegment, abjad.PitchClassSet, abjad.PitchSegment, abjad.PitchSet, ) if isinstance(items, prototype): items = list(items) enumerator = Enumerator(items) pairs = enumerator.yield_pairs() items = [second - first for first, second in pairs] Set.__init__(self, items=items, item_class=item_class)
def __init__(self, items=None, item_class=None): import abjad prototype = ( abjad.PitchSegment, abjad.PitchSet, abjad.PitchClassSegment, abjad.PitchClassSet, ) if isinstance(items, prototype): intervals = [] items = tuple(items) enumerator = Enumerator(items) pairs = enumerator.yield_pairs() for first, second in pairs: intervals.append(second - first) items = intervals Vector.__init__(self, items=items, item_class=item_class)
def from_selection(class_, selection, item_class=None): """ Initializes interval set from component selection. .. container:: example >>> staff_1 = abjad.Staff("c'4 <d' fs' a'>4 b2") >>> staff_2 = abjad.Staff("c4. r8 g2") >>> selection = abjad.select((staff_1, staff_2)) >>> intervals = abjad.IntervalSet.from_selection(selection) >>> for interval in sorted(intervals): ... interval ... NamedInterval('-M6') NamedInterval('-P5') NamedInterval('-A4') NamedInterval('-M3') NamedInterval('-m3') NamedInterval('-M2') NamedInterval('+m2') NamedInterval('+m3') NamedInterval('+M3') NamedInterval('+P4') NamedInterval('+P5') NamedInterval('+m7') NamedInterval('+M7') NamedInterval('+P8') NamedInterval('+M9') NamedInterval('+A11') NamedInterval('+M13') Returns interval set. """ import abjad pitch_segment = abjad.PitchSegment.from_selection(selection) enumerator = Enumerator(pitch_segment) pairs = enumerator.yield_pairs() intervals = [second - first for first, second in pairs] return class_( items=intervals, item_class=item_class, )
def list_related_tempos( self, maximum_numerator=None, maximum_denominator=None, integer_tempos_only=False, ) -> typing.List[typing.Tuple["MetronomeMark", "Ratio"]]: r""" Lists related tempos. .. container:: example Rewrites tempo ``4=58`` by ratios ``n:d`` such that ``1 <= n <= 8`` and ``1 <= d <= 8``. >>> mark = abjad.MetronomeMark((1, 4), 58) >>> pairs = mark.list_related_tempos( ... maximum_numerator=8, ... maximum_denominator=8, ... ) >>> for tempo, ratio in pairs: ... string = f'{tempo!s}\t{ratio!s}' ... print(string) 4=29 1:2 4=33+1/7 4:7 4=34+4/5 3:5 4=36+1/4 5:8 4=38+2/3 2:3 4=41+3/7 5:7 4=43+1/2 3:4 4=46+2/5 4:5 4=48+1/3 5:6 4=49+5/7 6:7 4=50+3/4 7:8 4=58 1:1 4=66+2/7 8:7 4=67+2/3 7:6 4=69+3/5 6:5 4=72+1/2 5:4 4=77+1/3 4:3 4=81+1/5 7:5 4=87 3:2 4=92+4/5 8:5 4=96+2/3 5:3 4=101+1/2 7:4 4=116 2:1 .. container:: example Integer-valued tempos only: >>> mark = abjad.MetronomeMark((1, 4), 58) >>> pairs = mark.list_related_tempos( ... maximum_numerator=16, ... maximum_denominator=16, ... integer_tempos_only=True, ... ) >>> for tempo, ratio in pairs: ... string = f'{tempo!s}\t{ratio!s}' ... print(string) 4=29 1:2 4=58 1:1 4=87 3:2 4=116 2:1 Constrains ratios such that ``1:2 <= n:d <= 2:1``. """ allowable_numerators = range(1, maximum_numerator + 1) allowable_denominators = range(1, maximum_denominator + 1) numbers = [allowable_numerators, allowable_denominators] enumerator = Enumerator(numbers) pairs = enumerator.yield_outer_product() multipliers = [Multiplier(_) for _ in pairs] multipliers = [_ for _ in multipliers if Fraction(1, 2) <= _ <= Fraction(2)] multipliers.sort() multipliers = sequence(multipliers).remove_repeats() pairs = [] for multiplier in multipliers: new_units_per_minute = multiplier * self.units_per_minute if integer_tempos_only and not mathtools.is_integer_equivalent_number( new_units_per_minute ): continue metronome_mark = type(self)( reference_duration=self.reference_duration, units_per_minute=new_units_per_minute, ) ratio = Ratio(multiplier.pair) pair = (metronome_mark, ratio) pairs.append(pair) return pairs