def partition_to_avoid_octave_adjacencies(l, direction): '''Partition to avoid octave adjacencies. ''' assert direction in ('left', 'right') result = [[]] part = result[-1] for x in l: if not isinstance(x, (int, float, Fraction)): raise ValueError if x % 12 in [y % 12 for y in part]: first_value = [y for y in part if y % 12 == x % 12][0] first_index = part.index(first_value) ## partition current part into left and middle subparts old_part = part[:first_index+1] disputed_part = part[first_index+1:] new_part = [] ## divvy up disputed part left, right = mathtools.partition_integer_into_halves( len(disputed_part), bigger = direction) disputed_parts = sequencetools.partition_sequence_by_counts( disputed_part, [left, right], cyclic=False, overhang=False) left_disputed_part, right_disputed_part = disputed_parts assert len(left_disputed_part) == left assert len(right_disputed_part) == right old_part.extend(left_disputed_part) new_part.extend(right_disputed_part) ## replace last sublist in result with old, trimmed part result[-1] = old_part ## append new part to result result.append(new_part) part = result[-1] part.append(x) result = [tuple(x) for x in result] return result
def test_mathtools_partition_integer_into_halves_03(): r'''Partition zero into halves. ''' assert mathtools.partition_integer_into_halves(0, bigger='left') == (0, 0) assert mathtools.partition_integer_into_halves(0, bigger='right') == (0, 0)
def test_mathtools_partition_integer_into_halves_01(): assert mathtools.partition_integer_into_halves(7, bigger='left') == (4, 3) assert mathtools.partition_integer_into_halves(7, bigger='right') == (3, 4)
def test_mathtools_partition_integer_into_halves_02(): assert mathtools.partition_integer_into_halves(8, bigger='left') == (4, 4) assert mathtools.partition_integer_into_halves(8, bigger='right') == (4, 4) assert mathtools.partition_integer_into_halves(8, bigger='left', even='disallowed') == (5, 3) assert mathtools.partition_integer_into_halves(8, bigger='right', even='disallowed') == (3, 5)