def test_mathtools_NonreducedFraction___add___02(): result = mathtools.NonreducedFraction(3, 3) + 1 assert result.pair == (6, 3) result = 1 + mathtools.NonreducedFraction(3, 3) assert result.pair == (6, 3)
def __call__(self, divisions, rotation=None): r'''Calls rhythm-maker. Makes music as a list of selections. Applies cross-division ties (when specified by tie specifier). Other types of ties specified by tie specifier must be applied by child classes. Validates output type. Returns list of selections. ''' divisions_ = [] for division in divisions: if isinstance(division, mathtools.NonreducedFraction): divisions_.append(division) elif isinstance(division, durationtools.Division): division = mathtools.NonreducedFraction(division.duration) divisions_.append(division) else: division = mathtools.NonreducedFraction(division) divisions_.append(division) divisions = divisions_ prototype = mathtools.NonreducedFraction assert all(isinstance(_, prototype) for _ in divisions) self._rotation = rotation selections = self._make_music(divisions, rotation) selections = self._apply_tuplet_spelling_specifier(selections) self._apply_tie_specifier(selections) selections = self._apply_logical_tie_masks(selections) self._validate_selections(selections) self._validate_tuplets(selections) self._check_well_formedness(selections) return selections
def __call__(self, divisions=None): r'''Calls rounded ratio division maker on `division`. .. container:: example **Example 1.** Calls maker on nonempty input: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) >>> lists = maker([(7, 4), (6, 4)]) >>> for list_ in lists: ... list_ [NonreducedFraction(4, 4), NonreducedFraction(3, 4)] [NonreducedFraction(3, 4), NonreducedFraction(3, 4)] Returns list of division lists. .. container:: example **Example 2.** Calls maker on empty input: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) >>> maker([]) [] Returns empty list. Returns possibly empty list of division lists. ''' input_divisions = divisions or [] if not input_divisions: return [] output_division_lists = [] ratios = self._get_ratios() for i, input_division in enumerate(input_divisions): input_division = mathtools.NonreducedFraction(input_division) ratio = ratios[i] numerators = mathtools.partition_integer_by_ratio( input_division.numerator, ratio, ) output_division_list = [ mathtools.NonreducedFraction( numerator, input_division.denominator, ) for numerator in numerators ] output_division_lists.append(output_division_list) return output_division_lists
def test_mathtools_NonreducedFraction___add___01(): one = mathtools.NonreducedFraction(1, 4) two = mathtools.NonreducedFraction(2, 8) result = one + two assert result.pair == (4, 8) one = mathtools.NonreducedFraction(2, 8) two = mathtools.NonreducedFraction(1, 4) result = one + two assert result.pair == (4, 8)
def _coerce_divisions(self, divisions): nonreduced_fractions = [] for division in divisions: if hasattr(division, 'time_signature'): nonreduced_fraction = mathtools.NonreducedFraction( division.time_signature.pair ) else: nonreduced_fraction = mathtools.NonreducedFraction(division) nonreduced_fractions.append(nonreduced_fraction) return nonreduced_fractions
def test_mathtools_NonreducedFraction___add___03(): a = mathtools.NonreducedFraction(3, 6) b = mathtools.NonreducedFraction(3, 12) result_one = systemtools.IOManager.count_function_calls('a + b', locals()) result_two = systemtools.IOManager.count_function_calls('a + 10', locals()) if sys.version_info[0] == 2: assert result_one <= 80 assert result_two <= 80 else: assert result_one <= 100 assert result_two <= 100
def __getitem__(self, item): r'''Gets nonreduced fraction at `item` cyclically. .. container:: example **Example 1.** Gets item at index: :: >>> talea = rhythmmakertools.Talea( ... counts=(2, 1, 3, 2, 4, 1, 1), ... denominator=16, ... ) :: >>> talea[2] NonreducedFraction(3, 16) .. container:: example **Example 2.** Gets items in slice: :: >>> for nonreduced_fraction in talea[3:9]: ... nonreduced_fraction ... NonreducedFraction(2, 16) NonreducedFraction(4, 16) NonreducedFraction(1, 16) NonreducedFraction(1, 16) NonreducedFraction(2, 16) NonreducedFraction(1, 16) Returns nonreduced fraction or nonreduced fractions. ''' counts = datastructuretools.CyclicTuple(self.counts) if isinstance(item, int): count = counts[item] return mathtools.NonreducedFraction(count, self.denominator) elif isinstance(item, slice): counts = counts[item] result = [ mathtools.NonreducedFraction(count, self.denominator) for count in counts ] return result raise ValueError(item)
def _coerce_divisions(divisions): divisions_ = [] for division in divisions: if isinstance(division, mathtools.NonreducedFraction): divisions_.append(division) elif isinstance(division, durationtools.Division): division = mathtools.NonreducedFraction(division.duration) divisions_.append(division) else: division = mathtools.NonreducedFraction(division) divisions_.append(division) divisions = divisions_ prototype = mathtools.NonreducedFraction assert all(isinstance(_, prototype) for _ in divisions) return divisions
def __getitem__(self, item): r'''Gets non-reduced fraction at `item` cyclically. Returns non-reduced fraction or non-reduced fractions. ''' counts = datastructuretools.CyclicTuple(self.counts) if isinstance(item, int): count = counts[item] return mathtools.NonreducedFraction(count, self.denominator) elif isinstance(item, slice): counts = counts[item] result = [mathtools.NonreducedFraction(count, self.denominator) for count in counts] return result raise ValueError(item)
def _duration_and_possible_denominators_to_time_signature( duration, denominators=None, factor=None, ): # check input duration = durationtools.Duration(duration) if denominators is not None: if factor is not None: denominators = [ d for d in denominators if factor in mathtools.factors(d) ] for desired_denominator in sorted(denominators): nonreduced_fraction = mathtools.NonreducedFraction(duration) candidate_pair = \ nonreduced_fraction.with_denominator(desired_denominator) if candidate_pair.denominator == desired_denominator: return indicatortools.TimeSignature(candidate_pair) if factor is not None: if factor in mathtools.factors(duration.denominator): return indicatortools.TimeSignature(duration) else: time_signature_numerator = factor * duration.numerator time_signature_denominator = factor * duration.denominator return indicatortools.TimeSignature( (time_signature_numerator, time_signature_denominator)) else: return indicatortools.TimeSignature(duration)
def durations_to_nonreduced_fractions(durations): r'''Changes `durations` to nonreduced fractions sharing least common denominator. .. container:: example **Example.** Changes durations to nonreduced fractions: :: >>> durations = [Duration(2, 4), 3, (5, 16)] >>> result = Duration.durations_to_nonreduced_fractions(durations) >>> for x in result: ... x ... NonreducedFraction(8, 16) NonreducedFraction(48, 16) NonreducedFraction(5, 16) Returns new object of `durations` type. ''' durations = [Duration(x) for x in durations] denominators = [duration.denominator for duration in durations] lcd = mathtools.least_common_multiple(*denominators) nonreduced_fractions = [ mathtools.NonreducedFraction(x).with_denominator(lcd) for x in durations ] result = type(durations)(nonreduced_fractions) return result
def __init__( self, compound_meter_multiplier=durationtools.Multiplier(1), cyclic=True, durations=(), pattern_rotation_index=0, remainder=Right, remainder_fuse_threshold=None, ): compound_meter_multiplier = durationtools.Multiplier( compound_meter_multiplier) self._compound_meter_multiplier = compound_meter_multiplier assert isinstance(cyclic, bool), repr(cyclic) self._cyclic = cyclic durations = durations or () pattern_ = [] for division in durations: division = mathtools.NonreducedFraction(division) pattern_.append(division) durations = tuple(pattern_) self._pattern = durations assert remainder in (Left, Right), repr(remainder) self._remainder = remainder assert isinstance(pattern_rotation_index, int) self._pattern_rotation_index = pattern_rotation_index if remainder_fuse_threshold is not None: remainder_fuse_threshold = durationtools.Duration( remainder_fuse_threshold, ) self._remainder_fuse_threshold = remainder_fuse_threshold self._callbacks = ()
def __sub__(self, expr): r'''Subtracts `expr` from tempo. :: >>> tempo - 20 Returns new tempo. ''' if isinstance(expr, type(self)): if self.is_imprecise or expr.is_imprecise: raise ImpreciseTempoError new_quarters_per_minute = \ self.quarters_per_minute - expr.quarters_per_minute minimum_denominator = \ min((self.duration.denominator, expr.duration.denominator)) nonreduced_fraction = \ mathtools.NonreducedFraction(new_quarters_per_minute / 4) nonreduced_fraction = \ nonreduced_fraction.with_denominator(minimum_denominator) new_units_per_minute, new_duration_denominator = \ nonreduced_fraction.pair new_duration = \ durationtools.Duration(1, new_duration_denominator) new_tempo_indication = \ type(self)( duration=new_duration, units_per_minute=new_units_per_minute, ) return new_tempo_indication
def __call__(self, divisions, rotation=None): r'''Calls rhythm-maker. Makes music as a list of selections. Applies cross-division ties (when specified by tie specifier). Other types of ties specified by tie specifier must be applied by child classes. Validates output type. Returns list of selections. ''' divisions = [mathtools.NonreducedFraction(_) for _ in divisions] rotation = self._to_tuple(rotation) self._rotation = rotation selections = self._make_music( divisions, rotation, ) self._simplify_tuplets(selections) selections = self._flatten_trivial_tuplets(selections) self._apply_tie_specifier(selections) self._validate_selections(selections) self._validate_tuplets(selections) return selections
def __add__(self, arg): r'''Adds time signature to `arg`. .. container:: example **Example 1.** Adds two time signatures with the same denominator: >>> TimeSignature((3, 4)) + TimeSignature((3, 4)) TimeSignature((6, 4)) .. container:: example **Example 2.** Adds two time signatures with different denominators: >>> TimeSignature((3, 4)) + TimeSignature((6, 8)) TimeSignature((12, 8)) Returns new time signature in terms of greatest denominator. .. container:: example **Example 3.** Adds time signature to an integer: >>> TimeSignature((3, 4)) + 1 TimeSignature((7, 4)) Coerces integer to ``1/1``. Returns new time signature. ''' arg = type(self)(arg) nonreduced_1 = mathtools.NonreducedFraction( self.numerator, self.denominator, ) nonreduced_2 = mathtools.NonreducedFraction( arg.numerator, arg.denominator, ) result = nonreduced_1 + nonreduced_2 result = type(self)(( result.numerator, result.denominator, )) return result
def _beat_list_to_grouped_beat_list(self, beat_list): assert isinstance(beat_list, (list, tuple)), repr(beat_list) beat_list = [mathtools.NonreducedFraction(_) for _ in beat_list] total_duration = sum(beat_list) total_duration = durationtools.Duration(total_duration) if (total_duration.is_assignable and self.fuse_assignable_total_duration): return [[mathtools.NonreducedFraction(total_duration)]] if self.counts is None: beat_group = list(beat_list) grouped_beat_list = [beat_group] return grouped_beat_list grouped_beat_list = sequencetools.partition_sequence_by_counts( beat_list, counts=self.counts, cyclic=True, overhang=False, ) beats_included = sum([len(_) for _ in grouped_beat_list]) if beats_included == len(beat_list): return grouped_beat_list remainder_length = len(beat_list) - beats_included if self.remainder_direction == Left: grouped_beat_list = sequencetools.partition_sequence_by_counts( beat_list[remainder_length:], counts=self.counts, cyclic=True, overhang=False) remainder = beat_list[:remainder_length] if self.append_remainder: grouped_beat_list[0] = remainder + grouped_beat_list[0] else: grouped_beat_list.insert(0, remainder) else: grouped_beat_list = sequencetools.partition_sequence_by_counts( beat_list[:-remainder_length], counts=self.counts, cyclic=True, overhang=False) remainder = beat_list[-remainder_length:] if self.append_remainder: grouped_beat_list[-1] = grouped_beat_list[-1] + remainder else: grouped_beat_list.append(remainder) return grouped_beat_list
def __iter__(self): r'''Iterates meter. .. container:: example **Example 1.** Iterates ``5/4``: :: >>> meter = metertools.Meter((5, 4)) >>> for x in meter: ... x ... (NonreducedFraction(0, 4), NonreducedFraction(1, 4)) (NonreducedFraction(1, 4), NonreducedFraction(2, 4)) (NonreducedFraction(2, 4), NonreducedFraction(3, 4)) (NonreducedFraction(0, 4), NonreducedFraction(3, 4)) (NonreducedFraction(3, 4), NonreducedFraction(4, 4)) (NonreducedFraction(4, 4), NonreducedFraction(5, 4)) (NonreducedFraction(3, 4), NonreducedFraction(5, 4)) (NonreducedFraction(0, 4), NonreducedFraction(5, 4)) Yields pairs. ''' def recurse(node): result = [] for child in node: if isinstance(child, rhythmtreetools.RhythmTreeLeaf): result.append(child) else: result.extend(recurse(child)) result.append(node) return result result = recurse(self.root_node) for x in result: start_offset = mathtools.NonreducedFraction( x.start_offset).with_denominator(self.denominator) stop_offset = mathtools.NonreducedFraction( x.stop_offset).with_denominator(self.denominator) yield start_offset, stop_offset
def _conditionally_adjust_time_signature(self, old_denominator): if self.automatically_adjust_time_signature: naive_time_signature = self._preprolated_duration better_time_signature = \ mathtools.NonreducedFraction(naive_time_signature) better_time_signature = \ better_time_signature.with_denominator(old_denominator) better_time_signature = \ indicatortools.TimeSignature(better_time_signature) detach(indicatortools.TimeSignature, self) attach(better_time_signature, self)
def _remove_and_shrink_durated_parent_containers(self): from abjad.tools import indicatortools from abjad.tools import scoretools prolated_leaf_duration = self._get_duration() parentage = self._get_parentage(include_self=False) prolations = parentage._prolations current_prolation, i = durationtools.Duration(1), 0 parent = self._parent while parent is not None and not parent.is_simultaneous: current_prolation *= prolations[i] if isinstance(parent, scoretools.FixedDurationTuplet): candidate_new_parent_dur = ( parent.target_duration - current_prolation * self.written_duration) if durationtools.Duration(0) < candidate_new_parent_dur: parent.target_duration = candidate_new_parent_dur elif isinstance(parent, scoretools.Measure): indicator = parent._get_indicator(indicatortools.TimeSignature) parent_time_signature = indicator old_prolation = parent_time_signature.implied_prolation naive_time_signature = (parent_time_signature.duration - prolated_leaf_duration) better_time_signature = mathtools.NonreducedFraction( naive_time_signature) better_time_signature = better_time_signature.with_denominator( parent_time_signature.denominator) better_time_signature = indicatortools.TimeSignature( better_time_signature) detach(indicatortools.TimeSignature, parent) attach(better_time_signature, parent) indicator = parent._get_indicator(indicatortools.TimeSignature) parent_time_signature = indicator new_prolation = parent_time_signature.implied_prolation adjusted_prolation = old_prolation / new_prolation for x in parent: if isinstance(x, scoretools.FixedDurationTuplet): x.target_duration *= adjusted_prolation else: if adjusted_prolation != 1: new_target = \ x._preprolated_duration * adjusted_prolation scoretools.FixedDurationTuplet(new_target, [x]) parent = parent._parent i += 1 parentage = self._get_parentage(include_self=False) parent = self._parent if parent: index = parent.index(self) del (parent[index]) for x in parentage: if not len(x): x._extract() else: break
def set_measure_denominator_and_adjust_numerator(measure, denominator): r'''Set `measure` time signature `denominator` and multiply time signature numerator accordingly: :: >>> measure = Measure((3, 8), "c'8 d'8 e'8") >>> beam = spannertools.Beam() >>> attach(beam, measure[:]) .. doctest:: >>> print(format(measure)) { \time 3/8 c'8 [ d'8 e'8 ] } :: >>> scoretools.set_measure_denominator_and_adjust_numerator(measure, 16) Measure((6, 16), "c'8 d'8 e'8") .. doctest:: >>> print(format(measure)) { \time 6/16 c'8 [ d'8 e'8 ] } Leave `measure` contents unchanged. Return `measure`. ''' from abjad.tools import scoretools if isinstance(measure, scoretools.Measure): # to allow iteration inside zero-update loop old_time_signature = measure.time_signature old_time_signature_pair = (old_time_signature.numerator, old_time_signature.denominator) new_time_signature = mathtools.NonreducedFraction( old_time_signature_pair) new_time_signature = new_time_signature.with_denominator(denominator) new_time_signature = indicatortools.TimeSignature(new_time_signature) detach(indicatortools.TimeSignature, measure) attach(new_time_signature, measure) return measure
def __add__(self, arg): r'''Adds time signature to `arg`. .. container:: example **Example 1.** Adds two time signatures with the same denominator: >>> TimeSignature((3, 4)) + TimeSignature((3, 4)) TimeSignature((6, 4)) .. container:: example **Example 2.** Adds two time signatures with different denominators: >>> TimeSignature((3, 4)) + TimeSignature((6, 8)) TimeSignature((12, 8)) Returns new time signature in terms of greatest denominator. Returns new time signature. ''' if not isinstance(arg, type(self)): message = 'must be time signature: {!r}.' message = message.format(arg) raise Exception(message) nonreduced_1 = mathtools.NonreducedFraction( self.numerator, self.denominator, ) nonreduced_2 = mathtools.NonreducedFraction( arg.numerator, arg.denominator, ) result = nonreduced_1 + nonreduced_2 result = type(self)(( result.numerator, result.denominator, )) return result
def t_DURATION(self, t): r'-?[1-9]\d*(/[1-9]\d*)?' parts = t.value.partition('/') if not parts[2]: t.value = durationtools.Duration(int(parts[0])) else: numerator, denominator = int(parts[0]), int(parts[2]) fraction = mathtools.NonreducedFraction(numerator, denominator) preprolated_duration = durationtools.Duration(fraction) if fraction.numerator == preprolated_duration.numerator: t.value = preprolated_duration else: t.value = fraction return t
def make_desordre_measure(pitches): '''Makes a measure composed of *Désordre cells*. `pitches` is a list of lists of number (e.g., [[1, 2, 3], [2, 3, 4]]) The function returns a measure. ''' for sequence in pitches: container = abjad.demos.desordre.make_desordre_cell(sequence) time_signature = inspect_(container).get_duration() time_signature = mathtools.NonreducedFraction(time_signature) time_signature = time_signature.with_denominator(8) measure = scoretools.Measure(time_signature, [container]) return measure
def __call__(self, expr=None): r'''Makes divisions from `expr`. Pass in `expr` as either a list of divisions or as a list of division lists. Returns either a list of divisions or a list of division lists. ''' expr = expr or [] expr = list(expr) assert isinstance(expr, list), repr(expr) if self._is_flat_list(expr): expr = [mathtools.NonreducedFraction(_) for _ in expr] for callback in self.callbacks: expr = callback(expr) return expr
def with_denominator(self, denominator): r'''Change this duration to new duration with `denominator`. :: >>> duration = Duration(1, 4) >>> for denominator in (4, 8, 16, 32): ... print(duration.with_denominator(denominator)) ... 1/4 2/8 4/16 8/32 Returns new duration. ''' nonreduced_fraction = mathtools.NonreducedFraction(self) return nonreduced_fraction.with_denominator(denominator)
def _group_nonreduced_fractions_by_implied_prolation(durations): durations = [ mathtools.NonreducedFraction(duration) for duration in durations ] assert 0 < len(durations) group = [durations[0]] result = [group] for d in durations[1:]: d_f = set(mathtools.factors(d.denominator)) d_f.discard(2) gd_f = set(mathtools.factors(group[0].denominator)) gd_f.discard(2) if d_f == gd_f: group.append(d) else: group = [d] result.append(group) return result
def with_power_of_two_denominator( self, contents_multiplier=durationtools.Multiplier(1), ): r'''Makes new time signature equivalent to current time signature with power-of-two denominator. .. container:: example **Example 1.** Non-power-of-two denominator with power-of-two denominator: >>> time_signature = TimeSignature((3, 12)) >>> time_signature.with_power_of_two_denominator() TimeSignature((2, 8)) Returns new time signature. ''' # check input contents_multiplier = durationtools.Multiplier(contents_multiplier) # save non_power_of_two time_signature and denominator non_power_of_two_denominator = self.denominator # find power_of_two denominator if contents_multiplier == durationtools.Multiplier(1): power_of_two_denominator = \ mathtools.greatest_power_of_two_less_equal( non_power_of_two_denominator) else: power_of_two_denominator = \ mathtools.greatest_power_of_two_less_equal( non_power_of_two_denominator, 1) # find power_of_two pair non_power_of_two_pair = mathtools.NonreducedFraction(self.pair) power_of_two_fraction = non_power_of_two_pair.with_denominator( power_of_two_denominator) power_of_two_pair = power_of_two_fraction.pair # return new power_of_two time signature return type(self)(power_of_two_pair)
def with_denominator(self, denominator): r'''Changes duration to nonreduced fraction with `denominator`. .. container:: example Changes duration to nonreduced fraction: >>> duration = abjad.Duration(1, 4) >>> for denominator in (4, 8, 16, 32): ... print(duration.with_denominator(denominator)) ... 1/4 2/8 4/16 8/32 Returns new duration. ''' nonreduced_fraction = mathtools.NonreducedFraction(self) return nonreduced_fraction.with_denominator(denominator)
def __add__(self, expr): r'''Adds tempo to `expr`. .. container:: example **Example 1.** Adds one tempo to another: :: >>> Tempo(Duration(1, 4), 60) + Tempo(Duration(1, 4), 90) Tempo(duration=Duration(1, 4), units_per_minute=150) .. container:: example **Example 2.** Returns none when `expr` is not a tempo: :: >>> Tempo(Duration(1, 4), 60) + 90 is None True Returns new tempo or none. ''' if isinstance(expr, type(self)): if self.is_imprecise or expr.is_imprecise: raise ImpreciseTempoError new_quarters_per_minute = \ self.quarters_per_minute + expr.quarters_per_minute minimum_denominator = \ min((self.duration.denominator, expr.duration.denominator)) nonreduced_fraction = \ mathtools.NonreducedFraction(new_quarters_per_minute / 4) nonreduced_fraction = \ nonreduced_fraction.with_denominator(minimum_denominator) new_units_per_minute, new_duration_denominator = \ nonreduced_fraction.pair new_duration = \ durationtools.Duration(1, new_duration_denominator) new_tempo_indication = \ type(self)(new_duration, new_units_per_minute) return new_tempo_indication
def __add__(self, expr): r'''Adds tempo to `expr`. Returns new tempo. ''' if isinstance(expr, type(self)): if self.is_imprecise or expr.is_imprecise: raise ImpreciseTempoError new_quarters_per_minute = \ self.quarters_per_minute + expr.quarters_per_minute minimum_denominator = \ min((self.duration.denominator, expr.duration.denominator)) nonreduced_fraction = \ mathtools.NonreducedFraction(new_quarters_per_minute / 4) nonreduced_fraction = \ nonreduced_fraction.with_denominator(minimum_denominator) new_units_per_minute, new_duration_denominator = \ nonreduced_fraction.pair new_duration = \ durationtools.Duration(1, new_duration_denominator) new_tempo_indication = \ type(self)(new_duration, new_units_per_minute) return new_tempo_indication