def __sub__(self, argument): r'''Subtracts `argument` from numbered pitch-class. Subtraction is defined against both numbered intervals and against other pitch-classes. .. container:: example :: >>> abjad.NumberedPitchClass(6) - abjad.NumberedPitchClass(6) NumberedInversionEquivalentIntervalClass(0) :: >>> abjad.NumberedPitchClass(6) - abjad.NumberedPitchClass(7) NumberedInversionEquivalentIntervalClass(1) :: >>> abjad.NumberedPitchClass(7) - abjad.NumberedPitchClass(6) NumberedInversionEquivalentIntervalClass(1) .. container:: example :: >>> abjad.NumberedPitchClass(6) - abjad.NumberedInterval(-1) NumberedPitchClass(5) :: >>> abjad.NumberedPitchClass(6) - abjad.NumberedInterval(0) NumberedPitchClass(6) :: >>> abjad.NumberedPitchClass(6) - abjad.NumberedInterval(1) NumberedPitchClass(5) Returns numbered inversion-equivalent interval-class. ''' from abjad.tools import pitchtools if isinstance(argument, type(self)): interval_class_number = abs( self.number - argument.number ) if 6 < interval_class_number: interval_class_number = 12 - interval_class_number return pitchtools.NumberedInversionEquivalentIntervalClass( interval_class_number) interval_class = pitchtools.NumberedInversionEquivalentIntervalClass( argument) return type(self)(self.number - interval_class.number % 12)
def __sub__(self, expr): r'''Subtracts `expr` from numbered pitch-class. Subtraction defined against both numbered intervals and against other pitch-classes. Returns numbered inversion-equivalent interval-class. ''' from abjad.tools import pitchtools if isinstance(expr, type(self)): interval_class_number = abs(self.pitch_class_number - expr.pitch_class_number) if 6 < interval_class_number: interval_class_number = 12 - interval_class_number return pitchtools.NumberedInversionEquivalentIntervalClass( interval_class_number) interval_class = pitchtools.NumberedInversionEquivalentIntervalClass( expr) return type(self)(self.pitch_class_number - interval_class.number % 12)
def label_leaves_in_expr_with_numbered_inversion_equivalent_interval_classes( expr, markup_direction=Up): r"""Label leaves in `expr` with numbered inversion-equivalent interval classes: :: >>> notes = scoretools.make_notes( ... [0, 25, 11, -4, -14, -13, 9, 10, 6, 5], ... [Duration(1, 8)], ... ) >>> staff = Staff(notes) >>> labeltools.label_leaves_in_expr_with_numbered_inversion_equivalent_interval_classes( ... staff) .. doctest:: >>> print(format(staff)) \new Staff { c'8 ^ \markup { 1 } cs'''8 ^ \markup { 2 } b'8 ^ \markup { 3 } af8 ^ \markup { 2 } bf,8 ^ \markup { 1 } b,8 ^ \markup { 2 } a'8 ^ \markup { 1 } bf'8 ^ \markup { 4 } fs'8 ^ \markup { 1 } f'8 } :: >>> show(staff) # doctest: +SKIP Returns none. """ for note in iterate(expr).by_class(scoretools.Note): logical_voice_iterator = iterate(note).by_logical_voice_from_component( scoretools.Leaf, ) try: next(logical_voice_iterator) next_leaf = next(logical_voice_iterator) if isinstance(next_leaf, scoretools.Note): mdi = note.written_pitch - next_leaf.written_pitch iecic = \ pitchtools.NumberedInversionEquivalentIntervalClass(mdi) markup = markuptools.Markup(iecic, markup_direction) attach(markup, note) except StopIteration: pass
def instantiate_pitch_and_interval_test_collection(): r'''Instantiate pitch and interval test collection: :: >>> for x in pitchtools.instantiate_pitch_and_interval_test_collection(): x ... NumberedInversionEquivalentIntervalClass(1) NamedInversionEquivalentIntervalClass('+M2') NumberedInterval(1) NumberedIntervalClass(1) NamedInterval('+M2') NamedIntervalClass('+M2') NamedPitch('c') NamedPitchClass('c') NumberedPitch(1) NumberedPitchClass(1) Use to test pitch and interval interface consistency. Returns list. ''' from abjad.tools import pitchtools result = [] result.append(pitchtools.NumberedInversionEquivalentIntervalClass(1)) result.append(pitchtools.NamedInversionEquivalentIntervalClass('M2')) result.append(pitchtools.NumberedInterval(1)) result.append(pitchtools.NumberedIntervalClass(1)) result.append(pitchtools.NamedInterval('M2')) result.append(pitchtools.NamedIntervalClass('M2')) result.append(pitchtools.NamedPitch('c')) result.append(pitchtools.NamedPitchClass('c')) result.append(pitchtools.NumberedPitch(1)) result.append(pitchtools.NumberedPitchClass(1)) return result
def list_numbered_inversion_equivalent_interval_classes_pairwise( pitch_carriers, wrap=False, ): r'''Lists numbered inversion-equivalent interval-classes pairwise between `pitch_carriers`. :: >>> staff = Staff("c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8") .. doctest:: >>> f(staff) \new Staff { c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8 } :: >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise( ... staff[:], wrap=False) :: >>> for x in result: x ... NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(1) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(1) :: >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise( ... staff[:], wrap=True) :: >>> for x in result: x NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(1) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(1) NumberedInversionEquivalentIntervalClass(0) :: >>> notes = staff[:] >>> notes = list(reversed(notes)) :: >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise( ... notes, wrap=False) :: >>> for x in result: x ... NumberedInversionEquivalentIntervalClass(1) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(1) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) :: >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise( ... notes, wrap=True) :: >>> for x in result: x ... NumberedInversionEquivalentIntervalClass(1) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(1) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(2) NumberedInversionEquivalentIntervalClass(0) When ``wrap=False`` does not return ``pitch_carriers[-1] - pitch_carriers[0]`` as last in series. When ``wrap=True`` does return ``pitch_carriers[-1] - pitch_carriers[0]`` as last in series. Returns list. ''' from abjad.tools import pitchtools result = [] if len(pitch_carriers) == 0: return result elif len(pitch_carriers) == 1: if pitchtools.Pitch.is_pitch_carrier(pitch_carriers[0]): return result else: message = 'must be pitch, note, note-head or chord.' raise TypeError(message) if wrap: pairs = sequencetools.iterate_sequence_nwise( pitch_carriers, wrapped=True) else: pairs = sequencetools.iterate_sequence_nwise(pitch_carriers) for first_carrier, second_carrier in pairs: first_pitch = pitchtools.NamedPitch.from_pitch_carrier(first_carrier) second_pitch = pitchtools.NamedPitch.from_pitch_carrier(second_carrier) mdi = second_pitch - first_pitch iecic = pitchtools.NumberedInversionEquivalentIntervalClass(mdi) result.append(iecic) return result