1class Tone:
2
3 TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
4 TONES_COUNT = len(TONES)
5
6 def __init__(self, name):
7 self.name = name
8 self.position = self.TONES.index(self.name)
9
10 def __eq__(self, other):
11 return self.name == other.name
12
13 def __str__(self):
14 return self.name
15
16 def __add__(self, other):
17 if isinstance(other, Tone):
18 return Chord(self, other)
19 elif isinstance(other, Interval):
20 result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT
21 return Tone(self.TONES[result_tone_position])
22
23 def __sub__(self, other):
24 if isinstance(other, Tone):
25 return Interval(self.position - other.position)
26 elif isinstance(other, Interval):
27 result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT
28 return Tone(self.TONES[result_tone_position])
29
30
31class Interval:
32
33 POSSIBLE_INTERVALS = ["unison", "minor 2nd", "major 2nd",
34 "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th",
35 "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"
36 ]
37 INTERVALS_COUNT = len(POSSIBLE_INTERVALS)
38
39 def __init__(self, number_of_semitones):
40 self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT
41
42 def __str__(self):
43 return self.POSSIBLE_INTERVALS[self.number_of_semitones]
44
45 def __add__(self, other):
46 if isinstance(other, Interval):
47 return Interval(self.number_of_semitones + other.number_of_semitones)
48 elif isinstance(other, Tone):
49 raise TypeError("Invalid operation")
50
51 def __sub__(self, other):
52 if isinstance(other, Tone):
53 raise TypeError("Invalid operation")
54
55 def __neg__(self):
56 return Interval(-self.number_of_semitones)
57
58
59class Chord:
60
61 def __init__(self, root_tone, *args):
62 self.tones = [root_tone]
63 for tone in args:
64 if tone.name not in [t.name for t in self.tones]:
65 self.tones.append(tone)
66 if len(self.tones) < 2:
67 raise TypeError("Cannot have a chord made of only 1 unique tone")
68
69 def position_of_tone(self, tone):
70 return (tone.position - self.tones[0].position) % Tone.TONES_COUNT
71
72 def __str__(self):
73 sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t))
74 return '-'.join(str(tone) for tone in sorted_tones)
75
76 def __add__(self, other):
77 if isinstance(other, Tone):
78 return Chord(*self.tones, other)
79 if isinstance(other, Chord):
80 return Chord(*self.tones, *other.tones)
81
82 def __sub__(self, other):
83 """В тази функция приемам, че при премахване на root акорда, root става следващия акорд
84 по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид."""
85 if isinstance(other, Tone):
86 if other not in self.tones:
87 raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
88 if len(self.tones) <= 2:
89 raise TypeError("Cannot have a chord made of only 1 unique tone")
90 new_tones = [tone for tone in self.tones if tone != other]
91 return Chord(*new_tones)
92
93 def is_minor(self):
94 root_tone = self.tones[0]
95 for tone in self.tones[1:]:
96 if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3:
97 return True
98 return False
99
100 def is_major(self):
101 root_tone = self.tones[0]
102 for tone in self.tones[1:]:
103 if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4:
104 return True
105 return False
106
107 def is_power_chord(self):
108 return not (self.is_minor() or self.is_major())
109
110 def transposed(self, interval):
111 transpose_by = interval.number_of_semitones
112 new_tones = []
113 for tone in self.tones:
114 if transpose_by >= 0:
115 new_tones.append(tone + interval)
116 else:
117 new_tones.append(tone + (-interval))
118 return Chord(*new_tones)
.....................................
----------------------------------------------------------------------
Ran 37 tests in 0.001s
OK
Виктор Бечев
06.11.2024 16:01Много чисто, браво!
|
| f | 1 | class Tone: | f | 1 | class Tone: |
| 2 | 2 | ||||
| 3 | TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | 3 | TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | ||
| 4 | TONES_COUNT = len(TONES) | 4 | TONES_COUNT = len(TONES) | ||
| 5 | 5 | ||||
| 6 | def __init__(self, name): | 6 | def __init__(self, name): | ||
| 7 | self.name = name | 7 | self.name = name | ||
| 8 | self.position = self.TONES.index(self.name) | 8 | self.position = self.TONES.index(self.name) | ||
| 9 | 9 | ||||
| 10 | def __eq__(self, other): | 10 | def __eq__(self, other): | ||
| 11 | return self.name == other.name | 11 | return self.name == other.name | ||
| 12 | 12 | ||||
| 13 | def __str__(self): | 13 | def __str__(self): | ||
| 14 | return self.name | 14 | return self.name | ||
| 15 | 15 | ||||
| 16 | def __add__(self, other): | 16 | def __add__(self, other): | ||
| 17 | if isinstance(other, Tone): | 17 | if isinstance(other, Tone): | ||
| 18 | return Chord(self, other) | 18 | return Chord(self, other) | ||
| 19 | elif isinstance(other, Interval): | 19 | elif isinstance(other, Interval): | ||
| 20 | result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT | 20 | result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT | ||
| 21 | return Tone(self.TONES[result_tone_position]) | 21 | return Tone(self.TONES[result_tone_position]) | ||
| 22 | 22 | ||||
| 23 | def __sub__(self, other): | 23 | def __sub__(self, other): | ||
| 24 | if isinstance(other, Tone): | 24 | if isinstance(other, Tone): | ||
| 25 | return Interval(self.position - other.position) | 25 | return Interval(self.position - other.position) | ||
| 26 | elif isinstance(other, Interval): | 26 | elif isinstance(other, Interval): | ||
| 27 | result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT | 27 | result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT | ||
| 28 | return Tone(self.TONES[result_tone_position]) | 28 | return Tone(self.TONES[result_tone_position]) | ||
| 29 | 29 | ||||
| 30 | 30 | ||||
| 31 | class Interval: | 31 | class Interval: | ||
| 32 | 32 | ||||
| n | 33 | POSSIBLE_INTERVALS = { | n | 33 | POSSIBLE_INTERVALS = ["unison", "minor 2nd", "major 2nd", |
| 34 | 0: "unison", | 34 | "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", | ||
| 35 | 1 : "minor 2nd", | 35 | "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th" | ||
| 36 | 2 : "major 2nd", | ||||
| 37 | 3 : "minor 3rd", | ||||
| 38 | 4 : "major 3rd", | ||||
| 39 | 5 : "perfect 4th", | ||||
| 40 | 6 : "diminished 5th", | ||||
| 41 | 7 : "perfect 5th", | ||||
| 42 | 8 : "minor 6th", | ||||
| 43 | 9 : "major 6th", | ||||
| 44 | 10: "minor 7th", | ||||
| 45 | 11: "major 7th" | ||||
| 46 | } | 36 | ] | ||
| 47 | INTERVALS_COUNT = len(POSSIBLE_INTERVALS) | 37 | INTERVALS_COUNT = len(POSSIBLE_INTERVALS) | ||
| 48 | 38 | ||||
| 49 | def __init__(self, number_of_semitones): | 39 | def __init__(self, number_of_semitones): | ||
| 50 | self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT | 40 | self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT | ||
| 51 | 41 | ||||
| 52 | def __str__(self): | 42 | def __str__(self): | ||
| 53 | return self.POSSIBLE_INTERVALS[self.number_of_semitones] | 43 | return self.POSSIBLE_INTERVALS[self.number_of_semitones] | ||
| 54 | 44 | ||||
| 55 | def __add__(self, other): | 45 | def __add__(self, other): | ||
| 56 | if isinstance(other, Interval): | 46 | if isinstance(other, Interval): | ||
| 57 | return Interval(self.number_of_semitones + other.number_of_semitones) | 47 | return Interval(self.number_of_semitones + other.number_of_semitones) | ||
| 58 | elif isinstance(other, Tone): | 48 | elif isinstance(other, Tone): | ||
| 59 | raise TypeError("Invalid operation") | 49 | raise TypeError("Invalid operation") | ||
| 60 | 50 | ||||
| 61 | def __sub__(self, other): | 51 | def __sub__(self, other): | ||
| 62 | if isinstance(other, Tone): | 52 | if isinstance(other, Tone): | ||
| 63 | raise TypeError("Invalid operation") | 53 | raise TypeError("Invalid operation") | ||
| 64 | 54 | ||||
| 65 | def __neg__(self): | 55 | def __neg__(self): | ||
| 66 | return Interval(-self.number_of_semitones) | 56 | return Interval(-self.number_of_semitones) | ||
| 67 | 57 | ||||
| 68 | 58 | ||||
| 69 | class Chord: | 59 | class Chord: | ||
| 70 | 60 | ||||
| 71 | def __init__(self, root_tone, *args): | 61 | def __init__(self, root_tone, *args): | ||
| 72 | self.tones = [root_tone] | 62 | self.tones = [root_tone] | ||
| 73 | for tone in args: | 63 | for tone in args: | ||
| 74 | if tone.name not in [t.name for t in self.tones]: | 64 | if tone.name not in [t.name for t in self.tones]: | ||
| 75 | self.tones.append(tone) | 65 | self.tones.append(tone) | ||
| 76 | if len(self.tones) < 2: | 66 | if len(self.tones) < 2: | ||
| 77 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 67 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
| 78 | 68 | ||||
| 79 | def position_of_tone(self, tone): | 69 | def position_of_tone(self, tone): | ||
| 80 | return (tone.position - self.tones[0].position) % Tone.TONES_COUNT | 70 | return (tone.position - self.tones[0].position) % Tone.TONES_COUNT | ||
| 81 | 71 | ||||
| 82 | def __str__(self): | 72 | def __str__(self): | ||
| 83 | sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t)) | 73 | sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t)) | ||
| n | 84 | string_representation = '-'.join(str(tone) for tone in sorted_tones) | n | 74 | return '-'.join(str(tone) for tone in sorted_tones) |
| 85 | return string_representation | ||||
| 86 | 75 | ||||
| 87 | def __add__(self, other): | 76 | def __add__(self, other): | ||
| 88 | if isinstance(other, Tone): | 77 | if isinstance(other, Tone): | ||
| 89 | return Chord(*self.tones, other) | 78 | return Chord(*self.tones, other) | ||
| 90 | if isinstance(other, Chord): | 79 | if isinstance(other, Chord): | ||
| 91 | return Chord(*self.tones, *other.tones) | 80 | return Chord(*self.tones, *other.tones) | ||
| 92 | 81 | ||||
| 93 | def __sub__(self, other): | 82 | def __sub__(self, other): | ||
| 94 | """В тази функция приемам, че при премахване на root акорда, root става следващия акорд | 83 | """В тази функция приемам, че при премахване на root акорда, root става следващия акорд | ||
| 95 | по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид.""" | 84 | по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид.""" | ||
| 96 | if isinstance(other, Tone): | 85 | if isinstance(other, Tone): | ||
| 97 | if other not in self.tones: | 86 | if other not in self.tones: | ||
| 98 | raise TypeError(f"Cannot remove tone {other.name} from chord {self}") | 87 | raise TypeError(f"Cannot remove tone {other.name} from chord {self}") | ||
| 99 | if len(self.tones) <= 2: | 88 | if len(self.tones) <= 2: | ||
| 100 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 89 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
| 101 | new_tones = [tone for tone in self.tones if tone != other] | 90 | new_tones = [tone for tone in self.tones if tone != other] | ||
| 102 | return Chord(*new_tones) | 91 | return Chord(*new_tones) | ||
| 103 | 92 | ||||
| 104 | def is_minor(self): | 93 | def is_minor(self): | ||
| 105 | root_tone = self.tones[0] | 94 | root_tone = self.tones[0] | ||
| 106 | for tone in self.tones[1:]: | 95 | for tone in self.tones[1:]: | ||
| 107 | if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3: | 96 | if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3: | ||
| 108 | return True | 97 | return True | ||
| 109 | return False | 98 | return False | ||
| 110 | 99 | ||||
| 111 | def is_major(self): | 100 | def is_major(self): | ||
| 112 | root_tone = self.tones[0] | 101 | root_tone = self.tones[0] | ||
| 113 | for tone in self.tones[1:]: | 102 | for tone in self.tones[1:]: | ||
| 114 | if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4: | 103 | if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4: | ||
| 115 | return True | 104 | return True | ||
| 116 | return False | 105 | return False | ||
| 117 | 106 | ||||
| 118 | def is_power_chord(self): | 107 | def is_power_chord(self): | ||
| t | 119 | if not (self.is_minor() or self.is_major()): | t | 108 | return not (self.is_minor() or self.is_major()) |
| 120 | return True | ||||
| 121 | return False | ||||
| 122 | 109 | ||||
| 123 | def transposed(self, interval): | 110 | def transposed(self, interval): | ||
| 124 | transpose_by = interval.number_of_semitones | 111 | transpose_by = interval.number_of_semitones | ||
| 125 | new_tones = [] | 112 | new_tones = [] | ||
| 126 | for tone in self.tones: | 113 | for tone in self.tones: | ||
| 127 | if transpose_by >= 0: | 114 | if transpose_by >= 0: | ||
| 128 | new_tones.append(tone + interval) | 115 | new_tones.append(tone + interval) | ||
| 129 | else: | 116 | else: | ||
| 130 | new_tones.append(tone + (-interval)) | 117 | new_tones.append(tone + (-interval)) | ||
| 131 | return Chord(*new_tones) | 118 | return Chord(*new_tones) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | class Tone: | f | 1 | class Tone: |
| 2 | 2 | ||||
| 3 | TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | 3 | TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | ||
| 4 | TONES_COUNT = len(TONES) | 4 | TONES_COUNT = len(TONES) | ||
| 5 | 5 | ||||
| 6 | def __init__(self, name): | 6 | def __init__(self, name): | ||
| 7 | self.name = name | 7 | self.name = name | ||
| 8 | self.position = self.TONES.index(self.name) | 8 | self.position = self.TONES.index(self.name) | ||
| 9 | 9 | ||||
| 10 | def __eq__(self, other): | 10 | def __eq__(self, other): | ||
| 11 | return self.name == other.name | 11 | return self.name == other.name | ||
| 12 | 12 | ||||
| 13 | def __str__(self): | 13 | def __str__(self): | ||
| 14 | return self.name | 14 | return self.name | ||
| 15 | 15 | ||||
| 16 | def __add__(self, other): | 16 | def __add__(self, other): | ||
| 17 | if isinstance(other, Tone): | 17 | if isinstance(other, Tone): | ||
| 18 | return Chord(self, other) | 18 | return Chord(self, other) | ||
| 19 | elif isinstance(other, Interval): | 19 | elif isinstance(other, Interval): | ||
| 20 | result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT | 20 | result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT | ||
| 21 | return Tone(self.TONES[result_tone_position]) | 21 | return Tone(self.TONES[result_tone_position]) | ||
| 22 | 22 | ||||
| 23 | def __sub__(self, other): | 23 | def __sub__(self, other): | ||
| 24 | if isinstance(other, Tone): | 24 | if isinstance(other, Tone): | ||
| 25 | return Interval(self.position - other.position) | 25 | return Interval(self.position - other.position) | ||
| 26 | elif isinstance(other, Interval): | 26 | elif isinstance(other, Interval): | ||
| 27 | result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT | 27 | result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT | ||
| 28 | return Tone(self.TONES[result_tone_position]) | 28 | return Tone(self.TONES[result_tone_position]) | ||
| 29 | 29 | ||||
| 30 | 30 | ||||
| 31 | class Interval: | 31 | class Interval: | ||
| 32 | 32 | ||||
| 33 | POSSIBLE_INTERVALS = { | 33 | POSSIBLE_INTERVALS = { | ||
| 34 | 0: "unison", | 34 | 0: "unison", | ||
| 35 | 1 : "minor 2nd", | 35 | 1 : "minor 2nd", | ||
| 36 | 2 : "major 2nd", | 36 | 2 : "major 2nd", | ||
| 37 | 3 : "minor 3rd", | 37 | 3 : "minor 3rd", | ||
| 38 | 4 : "major 3rd", | 38 | 4 : "major 3rd", | ||
| 39 | 5 : "perfect 4th", | 39 | 5 : "perfect 4th", | ||
| 40 | 6 : "diminished 5th", | 40 | 6 : "diminished 5th", | ||
| 41 | 7 : "perfect 5th", | 41 | 7 : "perfect 5th", | ||
| 42 | 8 : "minor 6th", | 42 | 8 : "minor 6th", | ||
| 43 | 9 : "major 6th", | 43 | 9 : "major 6th", | ||
| 44 | 10: "minor 7th", | 44 | 10: "minor 7th", | ||
| 45 | 11: "major 7th" | 45 | 11: "major 7th" | ||
| 46 | } | 46 | } | ||
| 47 | INTERVALS_COUNT = len(POSSIBLE_INTERVALS) | 47 | INTERVALS_COUNT = len(POSSIBLE_INTERVALS) | ||
| 48 | 48 | ||||
| 49 | def __init__(self, number_of_semitones): | 49 | def __init__(self, number_of_semitones): | ||
| 50 | self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT | 50 | self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT | ||
| 51 | 51 | ||||
| 52 | def __str__(self): | 52 | def __str__(self): | ||
| 53 | return self.POSSIBLE_INTERVALS[self.number_of_semitones] | 53 | return self.POSSIBLE_INTERVALS[self.number_of_semitones] | ||
| 54 | 54 | ||||
| 55 | def __add__(self, other): | 55 | def __add__(self, other): | ||
| 56 | if isinstance(other, Interval): | 56 | if isinstance(other, Interval): | ||
| 57 | return Interval(self.number_of_semitones + other.number_of_semitones) | 57 | return Interval(self.number_of_semitones + other.number_of_semitones) | ||
| 58 | elif isinstance(other, Tone): | 58 | elif isinstance(other, Tone): | ||
| n | 59 | return TypeError("Invalid operation") | n | 59 | raise TypeError("Invalid operation") |
| 60 | 60 | ||||
| 61 | def __sub__(self, other): | 61 | def __sub__(self, other): | ||
| 62 | if isinstance(other, Tone): | 62 | if isinstance(other, Tone): | ||
| t | 63 | return TypeError("Invalid operation") | t | 63 | raise TypeError("Invalid operation") |
| 64 | 64 | ||||
| 65 | def __neg__(self): | 65 | def __neg__(self): | ||
| 66 | return Interval(-self.number_of_semitones) | 66 | return Interval(-self.number_of_semitones) | ||
| 67 | 67 | ||||
| 68 | 68 | ||||
| 69 | class Chord: | 69 | class Chord: | ||
| 70 | 70 | ||||
| 71 | def __init__(self, root_tone, *args): | 71 | def __init__(self, root_tone, *args): | ||
| 72 | self.tones = [root_tone] | 72 | self.tones = [root_tone] | ||
| 73 | for tone in args: | 73 | for tone in args: | ||
| 74 | if tone.name not in [t.name for t in self.tones]: | 74 | if tone.name not in [t.name for t in self.tones]: | ||
| 75 | self.tones.append(tone) | 75 | self.tones.append(tone) | ||
| 76 | if len(self.tones) < 2: | 76 | if len(self.tones) < 2: | ||
| 77 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 77 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
| 78 | 78 | ||||
| 79 | def position_of_tone(self, tone): | 79 | def position_of_tone(self, tone): | ||
| 80 | return (tone.position - self.tones[0].position) % Tone.TONES_COUNT | 80 | return (tone.position - self.tones[0].position) % Tone.TONES_COUNT | ||
| 81 | 81 | ||||
| 82 | def __str__(self): | 82 | def __str__(self): | ||
| 83 | sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t)) | 83 | sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t)) | ||
| 84 | string_representation = '-'.join(str(tone) for tone in sorted_tones) | 84 | string_representation = '-'.join(str(tone) for tone in sorted_tones) | ||
| 85 | return string_representation | 85 | return string_representation | ||
| 86 | 86 | ||||
| 87 | def __add__(self, other): | 87 | def __add__(self, other): | ||
| 88 | if isinstance(other, Tone): | 88 | if isinstance(other, Tone): | ||
| 89 | return Chord(*self.tones, other) | 89 | return Chord(*self.tones, other) | ||
| 90 | if isinstance(other, Chord): | 90 | if isinstance(other, Chord): | ||
| 91 | return Chord(*self.tones, *other.tones) | 91 | return Chord(*self.tones, *other.tones) | ||
| 92 | 92 | ||||
| 93 | def __sub__(self, other): | 93 | def __sub__(self, other): | ||
| 94 | """В тази функция приемам, че при премахване на root акорда, root става следващия акорд | 94 | """В тази функция приемам, че при премахване на root акорда, root става следващия акорд | ||
| 95 | по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид.""" | 95 | по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид.""" | ||
| 96 | if isinstance(other, Tone): | 96 | if isinstance(other, Tone): | ||
| 97 | if other not in self.tones: | 97 | if other not in self.tones: | ||
| 98 | raise TypeError(f"Cannot remove tone {other.name} from chord {self}") | 98 | raise TypeError(f"Cannot remove tone {other.name} from chord {self}") | ||
| 99 | if len(self.tones) <= 2: | 99 | if len(self.tones) <= 2: | ||
| 100 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 100 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
| 101 | new_tones = [tone for tone in self.tones if tone != other] | 101 | new_tones = [tone for tone in self.tones if tone != other] | ||
| 102 | return Chord(*new_tones) | 102 | return Chord(*new_tones) | ||
| 103 | 103 | ||||
| 104 | def is_minor(self): | 104 | def is_minor(self): | ||
| 105 | root_tone = self.tones[0] | 105 | root_tone = self.tones[0] | ||
| 106 | for tone in self.tones[1:]: | 106 | for tone in self.tones[1:]: | ||
| 107 | if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3: | 107 | if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3: | ||
| 108 | return True | 108 | return True | ||
| 109 | return False | 109 | return False | ||
| 110 | 110 | ||||
| 111 | def is_major(self): | 111 | def is_major(self): | ||
| 112 | root_tone = self.tones[0] | 112 | root_tone = self.tones[0] | ||
| 113 | for tone in self.tones[1:]: | 113 | for tone in self.tones[1:]: | ||
| 114 | if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4: | 114 | if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4: | ||
| 115 | return True | 115 | return True | ||
| 116 | return False | 116 | return False | ||
| 117 | 117 | ||||
| 118 | def is_power_chord(self): | 118 | def is_power_chord(self): | ||
| 119 | if not (self.is_minor() or self.is_major()): | 119 | if not (self.is_minor() or self.is_major()): | ||
| 120 | return True | 120 | return True | ||
| 121 | return False | 121 | return False | ||
| 122 | 122 | ||||
| 123 | def transposed(self, interval): | 123 | def transposed(self, interval): | ||
| 124 | transpose_by = interval.number_of_semitones | 124 | transpose_by = interval.number_of_semitones | ||
| 125 | new_tones = [] | 125 | new_tones = [] | ||
| 126 | for tone in self.tones: | 126 | for tone in self.tones: | ||
| 127 | if transpose_by >= 0: | 127 | if transpose_by >= 0: | ||
| 128 | new_tones.append(tone + interval) | 128 | new_tones.append(tone + interval) | ||
| 129 | else: | 129 | else: | ||
| 130 | new_tones.append(tone + (-interval)) | 130 | new_tones.append(tone + (-interval)) | ||
| 131 | return Chord(*new_tones) | 131 | return Chord(*new_tones) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||