| f | TONES_COUNT = 12 | f | TONES_COUNT = 12 | 
             | TONES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] |  | TONES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] | 
             |  |  |  | 
             | class Tone: |  | class Tone: | 
             |     """Musical tone""" |  |     """Musical tone""" | 
             |     def __init__(self, tone): |  |     def __init__(self, tone): | 
             |         self.tone = tone |  |         self.tone = tone | 
             |         if tone == 'C': |  |         if tone == 'C': | 
             |             self.position = 0 |  |             self.position = 0 | 
             |         elif tone == 'C#': |  |         elif tone == 'C#': | 
             |             self.position = 1 |  |             self.position = 1 | 
             |         elif tone == 'D': |  |         elif tone == 'D': | 
             |             self.position = 2 |  |             self.position = 2 | 
             |         elif tone == 'D#': |  |         elif tone == 'D#': | 
             |             self.position = 3 |  |             self.position = 3 | 
             |         elif tone == 'E': |  |         elif tone == 'E': | 
             |             self.position = 4 |  |             self.position = 4 | 
             |         elif tone == 'F': |  |         elif tone == 'F': | 
             |             self.position = 5 |  |             self.position = 5 | 
             |         elif tone == 'F#': |  |         elif tone == 'F#': | 
             |             self.position = 6 |  |             self.position = 6 | 
             |         elif tone == 'G': |  |         elif tone == 'G': | 
             |             self.position = 7 |  |             self.position = 7 | 
             |         elif tone == 'G#': |  |         elif tone == 'G#': | 
             |             self.position = 8 |  |             self.position = 8 | 
             |         elif tone == 'A': |  |         elif tone == 'A': | 
             |             self.position = 9 |  |             self.position = 9 | 
             |         elif tone == 'A#': |  |         elif tone == 'A#': | 
             |             self.position = 10 |  |             self.position = 10 | 
             |         elif tone == 'B': |  |         elif tone == 'B': | 
             |             self.position = 11 |  |             self.position = 11 | 
             |  |  |  | 
             |     def __str__(self): |  |     def __str__(self): | 
             |         return str(self.tone) |  |         return str(self.tone) | 
             |  |  |  | 
             |     def __eq__(self, other): |  |     def __eq__(self, other): | 
             |         return self.tone == other.tone |  |         return self.tone == other.tone | 
             |  |  |  | 
             |     def __int__(self): |  |     def __int__(self): | 
             |         return self.position |  |         return self.position | 
             |  |  |  | 
             |     def __add__(self, other): |  |     def __add__(self, other): | 
             |         if isinstance(other, Tone): |  |         if isinstance(other, Tone): | 
             |             return Chord(self, other) |  |             return Chord(self, other) | 
             |         if isinstance(other, Interval): |  |         if isinstance(other, Interval): | 
             |             return Tone(TONES[(self.position + other.semitones) % TONES_COUNT]) |  |             return Tone(TONES[(self.position + other.semitones) % TONES_COUNT]) | 
             |         return Tone(self.tone) |  |         return Tone(self.tone) | 
             |  |  |  | 
             |     def __sub__(self, other): |  |     def __sub__(self, other): | 
             |         if isinstance(other, Tone): |  |         if isinstance(other, Tone): | 
             |             if self.position < other.position: |  |             if self.position < other.position: | 
             |                 return Interval(self.position + TONES_COUNT - other.position) |  |                 return Interval(self.position + TONES_COUNT - other.position) | 
             |             return Interval(self.position - other.position) |  |             return Interval(self.position - other.position) | 
             |         if isinstance(other, Interval): |  |         if isinstance(other, Interval): | 
             |             if self.position < other.semitones: |  |             if self.position < other.semitones: | 
             |                 return Tone(TONES[TONES_COUNT + self.position - other.semitones]) |  |                 return Tone(TONES[TONES_COUNT + self.position - other.semitones]) | 
             |             return Tone(TONES[self.position - other.semitones]) |  |             return Tone(TONES[self.position - other.semitones]) | 
             |         return Tone(self.tone) |  |         return Tone(self.tone) | 
             |  |  |  | 
             |  |  |  | 
             | class Interval: |  | class Interval: | 
             |     """Musical interval, measured in semitones.""" |  |     """Musical interval, measured in semitones.""" | 
             |     def __init__(self, semitones): |  |     def __init__(self, semitones): | 
             |         self.semitones = semitones % 12 |  |         self.semitones = semitones % 12 | 
             |         self.is_negative = False # Chord.transposed function uses it |  |         self.is_negative = False # Chord.transposed function uses it | 
             |  |  |  | 
             |         if self.semitones == 0: |  |         if self.semitones == 0: | 
             |             self.name = 'unison' |  |             self.name = 'unison' | 
             |         elif self.semitones == 1: |  |         elif self.semitones == 1: | 
             |             self.name = 'minor 2nd' |  |             self.name = 'minor 2nd' | 
             |         elif self.semitones == 2: |  |         elif self.semitones == 2: | 
             |             self.name = 'major 2nd' |  |             self.name = 'major 2nd' | 
             |         elif self.semitones == 3: |  |         elif self.semitones == 3: | 
             |             self.name = 'minor 3rd' |  |             self.name = 'minor 3rd' | 
             |         elif self.semitones == 4: |  |         elif self.semitones == 4: | 
             |             self.name = 'major 3rd' |  |             self.name = 'major 3rd' | 
             |         elif self.semitones == 5: |  |         elif self.semitones == 5: | 
             |             self.name = 'perfect 4th' |  |             self.name = 'perfect 4th' | 
             |         elif self.semitones == 6: |  |         elif self.semitones == 6: | 
             |             self.name = 'diminished 5th' |  |             self.name = 'diminished 5th' | 
             |         elif self.semitones == 7: |  |         elif self.semitones == 7: | 
             |             self.name = 'perfect 5th' |  |             self.name = 'perfect 5th' | 
             |         elif self.semitones == 8: |  |         elif self.semitones == 8: | 
             |             self.name = 'minor 6th' |  |             self.name = 'minor 6th' | 
             |         elif self.semitones == 9: |  |         elif self.semitones == 9: | 
             |             self.name = 'major 6th' |  |             self.name = 'major 6th' | 
             |         elif self.semitones == 10: |  |         elif self.semitones == 10: | 
             |             self.name = 'minor 7th' |  |             self.name = 'minor 7th' | 
             |         elif self.semitones == 11: |  |         elif self.semitones == 11: | 
             |             self.name = 'major 7th' |  |             self.name = 'major 7th' | 
             |  |  |  | 
             |     def __str__(self): |  |     def __str__(self): | 
             |         return self.name |  |         return self.name | 
             |  |  |  | 
             |     def __int__(self): |  |     def __int__(self): | 
             |         return self.semitones |  |         return self.semitones | 
             |  |  |  | 
             |     def __add__(self, other): |  |     def __add__(self, other): | 
             |         if isinstance(other, Tone): |  |         if isinstance(other, Tone): | 
             |             raise TypeError('Invalid operation') |  |             raise TypeError('Invalid operation') | 
             |         return Interval(self.semitones + other.semitones) |  |         return Interval(self.semitones + other.semitones) | 
             |  |  |  | 
             |     def __sub__(self, other): |  |     def __sub__(self, other): | 
             |         if isinstance(other, Tone): |  |         if isinstance(other, Tone): | 
             |             raise TypeError('Invalid operation') |  |             raise TypeError('Invalid operation') | 
             |  |  |  | 
             |     def __neg__(self): |  |     def __neg__(self): | 
             |         self.is_negative = True |  |         self.is_negative = True | 
             |         return self |  |         return self | 
             |  |  |  | 
             |  |  |  | 
             | class Chord: |  | class Chord: | 
             |     """Musical chord made up of 2 or more unique tones.""" |  |     """Musical chord made up of 2 or more unique tones.""" | 
             |     def __init__(self, root_tone, *other_tones): |  |     def __init__(self, root_tone, *other_tones): | 
             |         self.root_tone = root_tone |  |         self.root_tone = root_tone | 
             |         tones = {self.root_tone.tone : self.root_tone.position} |  |         tones = {self.root_tone.tone : self.root_tone.position} | 
             |         self.tones = [self.root_tone] |  |         self.tones = [self.root_tone] | 
             |  |  |  | 
             |         # remove duplicates |  |         # remove duplicates | 
             |         for tone in other_tones: |  |         for tone in other_tones: | 
             |             if tone.tone not in tones: |  |             if tone.tone not in tones: | 
             |                 tones[tone.tone] = tone.position |  |                 tones[tone.tone] = tone.position | 
             |                 self.tones.append(tone) |  |                 self.tones.append(tone) | 
             |  |  |  | 
             |         if self.tones.__len__() == 1: |  |         if self.tones.__len__() == 1: | 
             |             raise TypeError('Cannot have a chord made of only 1 unique tone') |  |             raise TypeError('Cannot have a chord made of only 1 unique tone') | 
             |  |  |  | 
             |         # order relative to root |  |         # order relative to root | 
             |         tones = [self.root_tone] |  |         tones = [self.root_tone] | 
             |         position_list = list(map(int, self.tones)) |  |         position_list = list(map(int, self.tones)) | 
             |         for i in range(self.root_tone.position + 1, self.root_tone.position + TONES_COUNT): |  |         for i in range(self.root_tone.position + 1, self.root_tone.position + TONES_COUNT): | 
             |             if i % TONES_COUNT in position_list: |  |             if i % TONES_COUNT in position_list: | 
             |                 tones.append(self.tones[position_list.index(i % TONES_COUNT)]) |  |                 tones.append(self.tones[position_list.index(i % TONES_COUNT)]) | 
             |         self.tones = tones |  |         self.tones = tones | 
             |  |  |  | 
             |     def __str__(self): |  |     def __str__(self): | 
             |         return '-'.join(map(str, self.tones)) |  |         return '-'.join(map(str, self.tones)) | 
             |  |  |  | 
             |     def is_minor(self): |  |     def is_minor(self): | 
             |         """Return whether there are 3 semitones between the root  |  |         """Return whether there are 3 semitones between the root  | 
             |         and any other tone in the chord.""" |  |         and any other tone in the chord.""" | 
             |         for tone in self.tones: |  |         for tone in self.tones: | 
             |             if (tone is not self.root_tone |  |             if (tone is not self.root_tone | 
            | n |                 and abs(self.root_tone.position - tone.position) == 3): | n |                 and self.root_tone + Interval(3) == tone): | 
             |                 return True |  |                 return True | 
             |         return False |  |         return False | 
             |  |  |  | 
             |     def is_major(self): |  |     def is_major(self): | 
             |         """Return whether there are 4 semitones between the root  |  |         """Return whether there are 4 semitones between the root  | 
             |         and any other tone in the chord.""" |  |         and any other tone in the chord.""" | 
             |         for tone in self.tones: |  |         for tone in self.tones: | 
             |             if (tone is not self.root_tone |  |             if (tone is not self.root_tone | 
            | t |                 and abs(self.root_tone.position - tone.position) == 4): | t |                 and self.root_tone + Interval(4) == tone): | 
             |                 return True |  |                 return True | 
             |         return False |  |         return False | 
             |  |  |  | 
             |     def is_power_chord(self): |  |     def is_power_chord(self): | 
             |         """Return whether chord is neither minor nor major.""" |  |         """Return whether chord is neither minor nor major.""" | 
             |         return not self.is_major() and not self.is_minor() |  |         return not self.is_major() and not self.is_minor() | 
             |  |  |  | 
             |     def __add__(self, other): |  |     def __add__(self, other): | 
             |         if isinstance(other, Tone): |  |         if isinstance(other, Tone): | 
             |             tones = self.tones[:] |  |             tones = self.tones[:] | 
             |             tones.append(other) |  |             tones.append(other) | 
             |             return Chord(*tones) |  |             return Chord(*tones) | 
             |         if isinstance(other, Chord): |  |         if isinstance(other, Chord): | 
             |             tones = self.tones[:] |  |             tones = self.tones[:] | 
             |             tones.extend(other.tones) |  |             tones.extend(other.tones) | 
             |             return Chord(*tones) |  |             return Chord(*tones) | 
             |         return Chord(*self.tones) |  |         return Chord(*self.tones) | 
             |  |  |  | 
             |     def __sub__(self, other): |  |     def __sub__(self, other): | 
             |         if other in self.tones: |  |         if other in self.tones: | 
             |             tones = self.tones[:] |  |             tones = self.tones[:] | 
             |             tones.remove(other) |  |             tones.remove(other) | 
             |             return Chord(*tones) |  |             return Chord(*tones) | 
             |         raise TypeError(f'Cannot remove tone {other} from chord {self}') |  |         raise TypeError(f'Cannot remove tone {other} from chord {self}') | 
             |  |  |  | 
             |     def transposed(self, interval): |  |     def transposed(self, interval): | 
             |         """Subtract or add an interval to all of chord's tones.""" |  |         """Subtract or add an interval to all of chord's tones.""" | 
             |         tones = [tone - interval if interval.is_negative |  |         tones = [tone - interval if interval.is_negative | 
             |                  else tone + interval for tone in self.tones] |  |                  else tone + interval for tone in self.tones] | 
             |         return Chord(*tones) |  |         return Chord(*tones) | 
        
     
07.11.2024 10:44
07.11.2024 10:45
07.11.2024 10:46
07.11.2024 10:47
07.11.2024 10:48
07.11.2024 10:50
07.11.2024 10:51
07.11.2024 10:52