1NOTE_ORDER = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
2
3
4def sort_tones(tone_set, root):
5 note_order = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
6 index = note_order.index(root.tone)
7
8 note_order = note_order[index:] + note_order[:index]
9
10 order_dict = {tone: index for index, tone in enumerate(note_order)}
11 sorted_tones = sorted(tone_set, key=lambda tone: order_dict.get(tone.tone, float('inf')))
12 return sorted_tones
13
14class Tone:
15
16 def __init__(self, tone):
17 self.tone = tone
18
19 def __str__(self):
20 return self.tone
21
22 def __eq__(self, other):
23 if isinstance(other, Tone):
24 return self.tone == other.tone
25 else:
26 return self.tone == other
27
28 def __hash__(self):
29 return hash(self.tone)
30
31 def __add__(self, other):
32 if isinstance(other, Tone):
33 return Chord(self,other)
34 elif isinstance(other, Interval):
35 return Tone(NOTE_ORDER[(other.go_back_yourself() + NOTE_ORDER.index(self))%12])
36
37 def __sub__(self, other):
38 if isinstance(other, Tone):
39 return Interval(NOTE_ORDER.index(self) + NOTE_ORDER.index(other))
40 elif isinstance(other, Interval):
41 return Tone(NOTE_ORDER[(NOTE_ORDER.index(self) - other.go_back_yourself()) % 12])
42
43
44class Interval:
45
46 def __init__(self, semitone_number):
47 match semitone_number % 12:
48 case 0:
49 self.interval="unison"
50 case 1:
51 self.interval = "minor 2nd"
52 case 2:
53 self.interval = "major 2nd"
54 case 3:
55 self.interval = "minor 3rd"
56 case 4:
57 self.interval = "major 3rd"
58 case 5:
59 self.interval = "perfect 4th"
60 case 6:
61 self.interval = "diminished 5th"
62 case 7:
63 self.interval = "perfect 5th"
64 case 8:
65 self.interval = "minor 6th"
66 case 9:
67 self.interval = "major 6th"
68 case 10:
69 self.interval = "minor 7th"
70 case 11:
71 self.interval = "major 7th"
72 case _:
73 self.interval = '''Живот ли бе — да го опишеш?
74
75 Живот ли бе — да го разровиш?
76
77 Разровиш ли го — ще мирише
78
79 и ще горчи като отрова.'''
80
81 def __str__(self):
82 return self.interval
83
84 def go_back_yourself(self):
85 match self.interval:
86 case "unison":
87 return 0
88 case "minor 2nd":
89 return 1
90 case "major 2nd":
91 return 2
92 case "minor 3rd":
93 return 3
94 case "major 3rd":
95 return 4
96 case "perfect 4th":
97 return 5
98 case "diminished 5th":
99 return 6
100 case "perfect 5th":
101 return 7
102 case "minor 6th":
103 return 8
104 case "major 6th":
105 return 9
106 case "minor 7th":
107 return 10
108 case "major 7th":
109 return 11
110 case _:
111 self.interval = "Само онзи, който е живял, страдал и плакал с народа си – само той може да го разбере и да му помогне."+"Христо Ботев" + "He would have hated java"
112
113 def __add__(self, other):
114 if isinstance(other, Tone):
115 raise TypeError("Invalid operation")
116 if isinstance(other, Interval):
117 plc=Interval(self.go_back_yourself() + other.go_back_yourself())
118 return plc
119
120 def __sub__(self, other):
121 if isinstance(other, Tone):
122 raise TypeError("Invalid operation")
123 def __neg__(self):
124 return Interval(12 - self.go_back_yourself())
125
126class Chord:
127
128 def __init__(self, arg, *args, **kwargs):
129 self.root = arg
130 self.set_of_tones = set()
131 self.set_of_tones.add(arg)
132 for item in args:
133 if isinstance(item, tuple):
134 temporary_transition_list = []
135 temporary_transition_list.extend(item)
136 self.set_of_tones.update(temporary_transition_list)
137 else:
138 self.set_of_tones.update(set(args))
139 for value in kwargs.values():
140 self.set_of_tones.add(value)
141 if len(self.set_of_tones) < 2:
142 raise TypeError("Cannot have a chord made of only 1 unique tone")
143
144
145 def __str__(self):
146 return "-".join(t.tone for t in sort_tones(self.set_of_tones, self.root))
147
148 def is_minor(self):
149 for el in self.set_of_tones:
150 interval = self.root - el
151 if el == self.root:
152 continue
153 elif interval.interval == "minor 3rd":
154 return True
155 return False
156
157 def is_major(self):
158 for el in self.set_of_tones:
159 interval = self.root - el
160 if el == self.root:
161 continue
162 elif interval.interval == "major 3rd":
163 return True
164 return False
165
166 def is_power_chord(self):
167 return not self.is_major() and not self.is_minor()
168
169 def __add__(self, other):
170 if isinstance(other, Tone):
171 self.set_of_tones.add(other)
172 sort_tones(self.set_of_tones, self.root)
173 return self
174 if isinstance(other, Chord):
175 self.set_of_tones.update(other.set_of_tones)
176 placeholed = self
177 return placeholed
178
179 def __sub__(self, other):
180 if other not in self.set_of_tones:
181 raise TypeError(f"Cannot remove tone {other} from chord {self}")
182 elif len(self.set_of_tones) < 3:
183 raise TypeError("Cannot have a chord made of only 1 unique tone")
184 else:
185 self.set_of_tones.remove(other)
186 sort_tones(self.set_of_tones, self.root)
187 if self.root == other:
188 self.root = list(self.set_of_tones)[0]
189 return self
190
191 def transposed(self, inter):
192 notes = sort_tones(self.set_of_tones,self.root)
193 for i in range(0,3):
194 notes[i] = notes[i] + inter
195 return Chord(notes[0], tuple(notes))
....FFF............................F.
======================================================================
FAIL: test_is_major (test.TestBasicChordFunctionality.test_is_major)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 107, in test_is_major
self.assertTrue(a_major_chord.is_major())
AssertionError: False is not true
======================================================================
FAIL: test_is_minor (test.TestBasicChordFunctionality.test_is_minor)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 90, in test_is_minor
self.assertTrue(a_minor_chord.is_minor())
AssertionError: False is not true
======================================================================
FAIL: test_is_power_chord (test.TestBasicChordFunctionality.test_is_power_chord)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 116, in test_is_power_chord
self.assertFalse(a_minor_chord.is_power_chord())
AssertionError: True is not false
======================================================================
FAIL: test_tone_subtraction_inverse (test.TestOperations.test_tone_subtraction_inverse)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 178, in test_tone_subtraction_inverse
self.assertEqual(str(perfect_4th), "perfect 4th")
AssertionError: 'perfect 5th' != 'perfect 4th'
- perfect 5th
? ^
+ perfect 4th
? ^
----------------------------------------------------------------------
Ran 37 tests in 0.002s
FAILED (failures=4)
f | 1 | NOTE_ORDER = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | f | 1 | NOTE_ORDER = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] |
2 | 2 | ||||
3 | 3 | ||||
4 | def sort_tones(tone_set, root): | 4 | def sort_tones(tone_set, root): | ||
5 | note_order = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | 5 | note_order = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | ||
6 | index = note_order.index(root.tone) | 6 | index = note_order.index(root.tone) | ||
7 | 7 | ||||
8 | note_order = note_order[index:] + note_order[:index] | 8 | note_order = note_order[index:] + note_order[:index] | ||
9 | 9 | ||||
10 | order_dict = {tone: index for index, tone in enumerate(note_order)} | 10 | order_dict = {tone: index for index, tone in enumerate(note_order)} | ||
11 | sorted_tones = sorted(tone_set, key=lambda tone: order_dict.get(tone.tone, float('inf'))) | 11 | sorted_tones = sorted(tone_set, key=lambda tone: order_dict.get(tone.tone, float('inf'))) | ||
12 | return sorted_tones | 12 | return sorted_tones | ||
13 | 13 | ||||
14 | class Tone: | 14 | class Tone: | ||
15 | 15 | ||||
16 | def __init__(self, tone): | 16 | def __init__(self, tone): | ||
17 | self.tone = tone | 17 | self.tone = tone | ||
18 | 18 | ||||
19 | def __str__(self): | 19 | def __str__(self): | ||
20 | return self.tone | 20 | return self.tone | ||
21 | 21 | ||||
22 | def __eq__(self, other): | 22 | def __eq__(self, other): | ||
23 | if isinstance(other, Tone): | 23 | if isinstance(other, Tone): | ||
24 | return self.tone == other.tone | 24 | return self.tone == other.tone | ||
25 | else: | 25 | else: | ||
26 | return self.tone == other | 26 | return self.tone == other | ||
27 | 27 | ||||
28 | def __hash__(self): | 28 | def __hash__(self): | ||
29 | return hash(self.tone) | 29 | return hash(self.tone) | ||
30 | 30 | ||||
31 | def __add__(self, other): | 31 | def __add__(self, other): | ||
32 | if isinstance(other, Tone): | 32 | if isinstance(other, Tone): | ||
33 | return Chord(self,other) | 33 | return Chord(self,other) | ||
34 | elif isinstance(other, Interval): | 34 | elif isinstance(other, Interval): | ||
35 | return Tone(NOTE_ORDER[(other.go_back_yourself() + NOTE_ORDER.index(self))%12]) | 35 | return Tone(NOTE_ORDER[(other.go_back_yourself() + NOTE_ORDER.index(self))%12]) | ||
36 | 36 | ||||
37 | def __sub__(self, other): | 37 | def __sub__(self, other): | ||
38 | if isinstance(other, Tone): | 38 | if isinstance(other, Tone): | ||
39 | return Interval(NOTE_ORDER.index(self) + NOTE_ORDER.index(other)) | 39 | return Interval(NOTE_ORDER.index(self) + NOTE_ORDER.index(other)) | ||
40 | elif isinstance(other, Interval): | 40 | elif isinstance(other, Interval): | ||
41 | return Tone(NOTE_ORDER[(NOTE_ORDER.index(self) - other.go_back_yourself()) % 12]) | 41 | return Tone(NOTE_ORDER[(NOTE_ORDER.index(self) - other.go_back_yourself()) % 12]) | ||
42 | 42 | ||||
43 | 43 | ||||
44 | class Interval: | 44 | class Interval: | ||
45 | 45 | ||||
46 | def __init__(self, semitone_number): | 46 | def __init__(self, semitone_number): | ||
47 | match semitone_number % 12: | 47 | match semitone_number % 12: | ||
48 | case 0: | 48 | case 0: | ||
49 | self.interval="unison" | 49 | self.interval="unison" | ||
50 | case 1: | 50 | case 1: | ||
51 | self.interval = "minor 2nd" | 51 | self.interval = "minor 2nd" | ||
52 | case 2: | 52 | case 2: | ||
53 | self.interval = "major 2nd" | 53 | self.interval = "major 2nd" | ||
54 | case 3: | 54 | case 3: | ||
55 | self.interval = "minor 3rd" | 55 | self.interval = "minor 3rd" | ||
56 | case 4: | 56 | case 4: | ||
57 | self.interval = "major 3rd" | 57 | self.interval = "major 3rd" | ||
58 | case 5: | 58 | case 5: | ||
59 | self.interval = "perfect 4th" | 59 | self.interval = "perfect 4th" | ||
60 | case 6: | 60 | case 6: | ||
61 | self.interval = "diminished 5th" | 61 | self.interval = "diminished 5th" | ||
62 | case 7: | 62 | case 7: | ||
63 | self.interval = "perfect 5th" | 63 | self.interval = "perfect 5th" | ||
64 | case 8: | 64 | case 8: | ||
65 | self.interval = "minor 6th" | 65 | self.interval = "minor 6th" | ||
66 | case 9: | 66 | case 9: | ||
67 | self.interval = "major 6th" | 67 | self.interval = "major 6th" | ||
68 | case 10: | 68 | case 10: | ||
69 | self.interval = "minor 7th" | 69 | self.interval = "minor 7th" | ||
70 | case 11: | 70 | case 11: | ||
71 | self.interval = "major 7th" | 71 | self.interval = "major 7th" | ||
72 | case _: | 72 | case _: | ||
73 | self.interval = '''Живот ли бе — да го опишеш? | 73 | self.interval = '''Живот ли бе — да го опишеш? | ||
74 | 74 | ||||
75 | Живот ли бе — да го разровиш? | 75 | Живот ли бе — да го разровиш? | ||
76 | 76 | ||||
77 | Разровиш ли го — ще мирише | 77 | Разровиш ли го — ще мирише | ||
78 | 78 | ||||
79 | и ще горчи като отрова.''' | 79 | и ще горчи като отрова.''' | ||
80 | 80 | ||||
81 | def __str__(self): | 81 | def __str__(self): | ||
82 | return self.interval | 82 | return self.interval | ||
83 | 83 | ||||
84 | def go_back_yourself(self): | 84 | def go_back_yourself(self): | ||
85 | match self.interval: | 85 | match self.interval: | ||
86 | case "unison": | 86 | case "unison": | ||
87 | return 0 | 87 | return 0 | ||
88 | case "minor 2nd": | 88 | case "minor 2nd": | ||
89 | return 1 | 89 | return 1 | ||
90 | case "major 2nd": | 90 | case "major 2nd": | ||
91 | return 2 | 91 | return 2 | ||
92 | case "minor 3rd": | 92 | case "minor 3rd": | ||
93 | return 3 | 93 | return 3 | ||
94 | case "major 3rd": | 94 | case "major 3rd": | ||
95 | return 4 | 95 | return 4 | ||
96 | case "perfect 4th": | 96 | case "perfect 4th": | ||
97 | return 5 | 97 | return 5 | ||
98 | case "diminished 5th": | 98 | case "diminished 5th": | ||
99 | return 6 | 99 | return 6 | ||
100 | case "perfect 5th": | 100 | case "perfect 5th": | ||
101 | return 7 | 101 | return 7 | ||
102 | case "minor 6th": | 102 | case "minor 6th": | ||
103 | return 8 | 103 | return 8 | ||
104 | case "major 6th": | 104 | case "major 6th": | ||
105 | return 9 | 105 | return 9 | ||
106 | case "minor 7th": | 106 | case "minor 7th": | ||
107 | return 10 | 107 | return 10 | ||
108 | case "major 7th": | 108 | case "major 7th": | ||
109 | return 11 | 109 | return 11 | ||
110 | case _: | 110 | case _: | ||
111 | self.interval = "Само онзи, който е живял, страдал и плакал с народа си – само той може да го разбере и да му помогне."+"Христо Ботев" + "He would have hated java" | 111 | self.interval = "Само онзи, който е живял, страдал и плакал с народа си – само той може да го разбере и да му помогне."+"Христо Ботев" + "He would have hated java" | ||
112 | 112 | ||||
113 | def __add__(self, other): | 113 | def __add__(self, other): | ||
114 | if isinstance(other, Tone): | 114 | if isinstance(other, Tone): | ||
115 | raise TypeError("Invalid operation") | 115 | raise TypeError("Invalid operation") | ||
116 | if isinstance(other, Interval): | 116 | if isinstance(other, Interval): | ||
117 | plc=Interval(self.go_back_yourself() + other.go_back_yourself()) | 117 | plc=Interval(self.go_back_yourself() + other.go_back_yourself()) | ||
118 | return plc | 118 | return plc | ||
119 | 119 | ||||
120 | def __sub__(self, other): | 120 | def __sub__(self, other): | ||
121 | if isinstance(other, Tone): | 121 | if isinstance(other, Tone): | ||
122 | raise TypeError("Invalid operation") | 122 | raise TypeError("Invalid operation") | ||
123 | def __neg__(self): | 123 | def __neg__(self): | ||
124 | return Interval(12 - self.go_back_yourself()) | 124 | return Interval(12 - self.go_back_yourself()) | ||
125 | 125 | ||||
126 | class Chord: | 126 | class Chord: | ||
127 | 127 | ||||
128 | def __init__(self, arg, *args, **kwargs): | 128 | def __init__(self, arg, *args, **kwargs): | ||
129 | self.root = arg | 129 | self.root = arg | ||
130 | self.set_of_tones = set() | 130 | self.set_of_tones = set() | ||
131 | self.set_of_tones.add(arg) | 131 | self.set_of_tones.add(arg) | ||
132 | for item in args: | 132 | for item in args: | ||
133 | if isinstance(item, tuple): | 133 | if isinstance(item, tuple): | ||
134 | temporary_transition_list = [] | 134 | temporary_transition_list = [] | ||
135 | temporary_transition_list.extend(item) | 135 | temporary_transition_list.extend(item) | ||
136 | self.set_of_tones.update(temporary_transition_list) | 136 | self.set_of_tones.update(temporary_transition_list) | ||
137 | else: | 137 | else: | ||
138 | self.set_of_tones.update(set(args)) | 138 | self.set_of_tones.update(set(args)) | ||
139 | for value in kwargs.values(): | 139 | for value in kwargs.values(): | ||
140 | self.set_of_tones.add(value) | 140 | self.set_of_tones.add(value) | ||
141 | if len(self.set_of_tones) < 2: | 141 | if len(self.set_of_tones) < 2: | ||
142 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 142 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
143 | 143 | ||||
144 | 144 | ||||
145 | def __str__(self): | 145 | def __str__(self): | ||
146 | return "-".join(t.tone for t in sort_tones(self.set_of_tones, self.root)) | 146 | return "-".join(t.tone for t in sort_tones(self.set_of_tones, self.root)) | ||
147 | 147 | ||||
148 | def is_minor(self): | 148 | def is_minor(self): | ||
149 | for el in self.set_of_tones: | 149 | for el in self.set_of_tones: | ||
150 | interval = self.root - el | 150 | interval = self.root - el | ||
151 | if el == self.root: | 151 | if el == self.root: | ||
152 | continue | 152 | continue | ||
153 | elif interval.interval == "minor 3rd": | 153 | elif interval.interval == "minor 3rd": | ||
154 | return True | 154 | return True | ||
155 | return False | 155 | return False | ||
156 | 156 | ||||
157 | def is_major(self): | 157 | def is_major(self): | ||
158 | for el in self.set_of_tones: | 158 | for el in self.set_of_tones: | ||
159 | interval = self.root - el | 159 | interval = self.root - el | ||
160 | if el == self.root: | 160 | if el == self.root: | ||
161 | continue | 161 | continue | ||
162 | elif interval.interval == "major 3rd": | 162 | elif interval.interval == "major 3rd": | ||
163 | return True | 163 | return True | ||
164 | return False | 164 | return False | ||
165 | 165 | ||||
166 | def is_power_chord(self): | 166 | def is_power_chord(self): | ||
167 | return not self.is_major() and not self.is_minor() | 167 | return not self.is_major() and not self.is_minor() | ||
168 | 168 | ||||
169 | def __add__(self, other): | 169 | def __add__(self, other): | ||
170 | if isinstance(other, Tone): | 170 | if isinstance(other, Tone): | ||
171 | self.set_of_tones.add(other) | 171 | self.set_of_tones.add(other) | ||
172 | sort_tones(self.set_of_tones, self.root) | 172 | sort_tones(self.set_of_tones, self.root) | ||
173 | return self | 173 | return self | ||
174 | if isinstance(other, Chord): | 174 | if isinstance(other, Chord): | ||
175 | self.set_of_tones.update(other.set_of_tones) | 175 | self.set_of_tones.update(other.set_of_tones) | ||
176 | placeholed = self | 176 | placeholed = self | ||
177 | return placeholed | 177 | return placeholed | ||
178 | 178 | ||||
179 | def __sub__(self, other): | 179 | def __sub__(self, other): | ||
180 | if other not in self.set_of_tones: | 180 | if other not in self.set_of_tones: | ||
181 | raise TypeError(f"Cannot remove tone {other} from chord {self}") | 181 | raise TypeError(f"Cannot remove tone {other} from chord {self}") | ||
182 | elif len(self.set_of_tones) < 3: | 182 | elif len(self.set_of_tones) < 3: | ||
183 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 183 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
184 | else: | 184 | else: | ||
185 | self.set_of_tones.remove(other) | 185 | self.set_of_tones.remove(other) | ||
186 | sort_tones(self.set_of_tones, self.root) | 186 | sort_tones(self.set_of_tones, self.root) | ||
187 | if self.root == other: | 187 | if self.root == other: | ||
188 | self.root = list(self.set_of_tones)[0] | 188 | self.root = list(self.set_of_tones)[0] | ||
189 | return self | 189 | return self | ||
190 | 190 | ||||
191 | def transposed(self, inter): | 191 | def transposed(self, inter): | ||
192 | notes = sort_tones(self.set_of_tones,self.root) | 192 | notes = sort_tones(self.set_of_tones,self.root) | ||
193 | for i in range(0,3): | 193 | for i in range(0,3): | ||
194 | notes[i] = notes[i] + inter | 194 | notes[i] = notes[i] + inter | ||
195 | return Chord(notes[0], tuple(notes)) | 195 | return Chord(notes[0], tuple(notes)) | ||
t | 196 | t | |||
197 | c, d_sharp, g = Tone("C"), Tone("D#"), Tone("G") | ||||
198 | c_minor_chord = Chord(c, d_sharp, g) | ||||
199 | print(str(c_minor_chord)) | ||||
200 | # "C-D#-G" | ||||
201 | d_minor_chord = c_minor_chord.transposed(Interval(2)) | ||||
202 | print(str(d_minor_chord)) | ||||
203 | # "D-F-A" | ||||
204 | |||||
205 | a_sharp_minor_chord = d_minor_chord.transposed(-Interval(4)) | ||||
206 | print(str(a_sharp_minor_chord)) | ||||
207 | # "A#-C#-F" |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
n | 1 | NOTE_ORDER=["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | n | 1 | NOTE_ORDER = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] |
2 | |||||
2 | 3 | ||||
3 | def sort_tones(tone_set, root): | 4 | def sort_tones(tone_set, root): | ||
4 | note_order = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | 5 | note_order = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | ||
5 | index = note_order.index(root.tone) | 6 | index = note_order.index(root.tone) | ||
6 | 7 | ||||
7 | note_order = note_order[index:] + note_order[:index] | 8 | note_order = note_order[index:] + note_order[:index] | ||
8 | 9 | ||||
9 | order_dict = {tone: index for index, tone in enumerate(note_order)} | 10 | order_dict = {tone: index for index, tone in enumerate(note_order)} | ||
10 | sorted_tones = sorted(tone_set, key=lambda tone: order_dict.get(tone.tone, float('inf'))) | 11 | sorted_tones = sorted(tone_set, key=lambda tone: order_dict.get(tone.tone, float('inf'))) | ||
11 | return sorted_tones | 12 | return sorted_tones | ||
12 | 13 | ||||
n | 13 | n | |||
14 | class Tone: | 14 | class Tone: | ||
n | 15 | n | |||
16 | 15 | ||||
17 | def __init__(self, tone): | 16 | def __init__(self, tone): | ||
18 | self.tone = tone | 17 | self.tone = tone | ||
19 | 18 | ||||
n | 20 | n | |||
21 | def __str__(self): | 19 | def __str__(self): | ||
22 | return self.tone | 20 | return self.tone | ||
n | 23 | n | |||
24 | 21 | ||||
25 | def __eq__(self, other): | 22 | def __eq__(self, other): | ||
26 | if isinstance(other, Tone): | 23 | if isinstance(other, Tone): | ||
27 | return self.tone == other.tone | 24 | return self.tone == other.tone | ||
28 | else: | 25 | else: | ||
29 | return self.tone == other | 26 | return self.tone == other | ||
30 | 27 | ||||
n | 31 | n | |||
32 | def __hash__(self): | 28 | def __hash__(self): | ||
33 | return hash(self.tone) | 29 | return hash(self.tone) | ||
n | 34 | n | |||
35 | 30 | ||||
36 | def __add__(self, other): | 31 | def __add__(self, other): | ||
37 | if isinstance(other, Tone): | 32 | if isinstance(other, Tone): | ||
38 | return Chord(self,other) | 33 | return Chord(self,other) | ||
39 | elif isinstance(other, Interval): | 34 | elif isinstance(other, Interval): | ||
40 | return Tone(NOTE_ORDER[(other.go_back_yourself() + NOTE_ORDER.index(self))%12]) | 35 | return Tone(NOTE_ORDER[(other.go_back_yourself() + NOTE_ORDER.index(self))%12]) | ||
41 | 36 | ||||
n | 42 | n | |||
43 | def __sub__(self, other): | 37 | def __sub__(self, other): | ||
44 | if isinstance(other, Tone): | 38 | if isinstance(other, Tone): | ||
45 | return Interval(NOTE_ORDER.index(self) + NOTE_ORDER.index(other)) | 39 | return Interval(NOTE_ORDER.index(self) + NOTE_ORDER.index(other)) | ||
46 | elif isinstance(other, Interval): | 40 | elif isinstance(other, Interval): | ||
n | 47 | return Tone(NOTE_ORDER[(NOTE_ORDER.index(self) - other.go_back_yourself())%12]) | n | 41 | return Tone(NOTE_ORDER[(NOTE_ORDER.index(self) - other.go_back_yourself()) % 12]) |
48 | 42 | ||||
49 | 43 | ||||
50 | class Interval: | 44 | class Interval: | ||
n | 51 | n | |||
52 | 45 | ||||
53 | def __init__(self, semitone_number): | 46 | def __init__(self, semitone_number): | ||
54 | match semitone_number % 12: | 47 | match semitone_number % 12: | ||
55 | case 0: | 48 | case 0: | ||
56 | self.interval="unison" | 49 | self.interval="unison" | ||
57 | case 1: | 50 | case 1: | ||
58 | self.interval = "minor 2nd" | 51 | self.interval = "minor 2nd" | ||
59 | case 2: | 52 | case 2: | ||
60 | self.interval = "major 2nd" | 53 | self.interval = "major 2nd" | ||
61 | case 3: | 54 | case 3: | ||
62 | self.interval = "minor 3rd" | 55 | self.interval = "minor 3rd" | ||
63 | case 4: | 56 | case 4: | ||
64 | self.interval = "major 3rd" | 57 | self.interval = "major 3rd" | ||
65 | case 5: | 58 | case 5: | ||
66 | self.interval = "perfect 4th" | 59 | self.interval = "perfect 4th" | ||
67 | case 6: | 60 | case 6: | ||
68 | self.interval = "diminished 5th" | 61 | self.interval = "diminished 5th" | ||
69 | case 7: | 62 | case 7: | ||
70 | self.interval = "perfect 5th" | 63 | self.interval = "perfect 5th" | ||
71 | case 8: | 64 | case 8: | ||
72 | self.interval = "minor 6th" | 65 | self.interval = "minor 6th" | ||
73 | case 9: | 66 | case 9: | ||
74 | self.interval = "major 6th" | 67 | self.interval = "major 6th" | ||
75 | case 10: | 68 | case 10: | ||
76 | self.interval = "minor 7th" | 69 | self.interval = "minor 7th" | ||
77 | case 11: | 70 | case 11: | ||
78 | self.interval = "major 7th" | 71 | self.interval = "major 7th" | ||
79 | case _: | 72 | case _: | ||
80 | self.interval = '''Живот ли бе — да го опишеш? | 73 | self.interval = '''Живот ли бе — да го опишеш? | ||
81 | 74 | ||||
82 | Живот ли бе — да го разровиш? | 75 | Живот ли бе — да го разровиш? | ||
83 | 76 | ||||
84 | Разровиш ли го — ще мирише | 77 | Разровиш ли го — ще мирише | ||
85 | 78 | ||||
86 | и ще горчи като отрова.''' | 79 | и ще горчи като отрова.''' | ||
87 | 80 | ||||
n | 88 | n | |||
89 | def __str__(self): | 81 | def __str__(self): | ||
90 | return self.interval | 82 | return self.interval | ||
n | 91 | n | |||
92 | 83 | ||||
93 | def go_back_yourself(self): | 84 | def go_back_yourself(self): | ||
94 | match self.interval: | 85 | match self.interval: | ||
95 | case "unison": | 86 | case "unison": | ||
96 | return 0 | 87 | return 0 | ||
97 | case "minor 2nd": | 88 | case "minor 2nd": | ||
98 | return 1 | 89 | return 1 | ||
99 | case "major 2nd": | 90 | case "major 2nd": | ||
100 | return 2 | 91 | return 2 | ||
101 | case "minor 3rd": | 92 | case "minor 3rd": | ||
102 | return 3 | 93 | return 3 | ||
103 | case "major 3rd": | 94 | case "major 3rd": | ||
104 | return 4 | 95 | return 4 | ||
105 | case "perfect 4th": | 96 | case "perfect 4th": | ||
106 | return 5 | 97 | return 5 | ||
107 | case "diminished 5th": | 98 | case "diminished 5th": | ||
108 | return 6 | 99 | return 6 | ||
109 | case "perfect 5th": | 100 | case "perfect 5th": | ||
110 | return 7 | 101 | return 7 | ||
111 | case "minor 6th": | 102 | case "minor 6th": | ||
112 | return 8 | 103 | return 8 | ||
113 | case "major 6th": | 104 | case "major 6th": | ||
114 | return 9 | 105 | return 9 | ||
115 | case "minor 7th": | 106 | case "minor 7th": | ||
116 | return 10 | 107 | return 10 | ||
117 | case "major 7th": | 108 | case "major 7th": | ||
118 | return 11 | 109 | return 11 | ||
119 | case _: | 110 | case _: | ||
120 | self.interval = "Само онзи, който е живял, страдал и плакал с народа си – само той може да го разбере и да му помогне."+"Христо Ботев" + "He would have hated java" | 111 | self.interval = "Само онзи, който е живял, страдал и плакал с народа си – само той може да го разбере и да му помогне."+"Христо Ботев" + "He would have hated java" | ||
121 | 112 | ||||
n | 122 | n | |||
123 | def __add__(self, other): | 113 | def __add__(self, other): | ||
124 | if isinstance(other, Tone): | 114 | if isinstance(other, Tone): | ||
125 | raise TypeError("Invalid operation") | 115 | raise TypeError("Invalid operation") | ||
126 | if isinstance(other, Interval): | 116 | if isinstance(other, Interval): | ||
127 | plc=Interval(self.go_back_yourself() + other.go_back_yourself()) | 117 | plc=Interval(self.go_back_yourself() + other.go_back_yourself()) | ||
128 | return plc | 118 | return plc | ||
129 | 119 | ||||
n | 130 | n | |||
131 | def __sub__(self, other): | 120 | def __sub__(self, other): | ||
132 | if isinstance(other, Tone): | 121 | if isinstance(other, Tone): | ||
133 | raise TypeError("Invalid operation") | 122 | raise TypeError("Invalid operation") | ||
n | 134 | n | 123 | def __neg__(self): | |
124 | return Interval(12 - self.go_back_yourself()) | ||||
135 | 125 | ||||
136 | class Chord: | 126 | class Chord: | ||
n | 137 | n | |||
138 | 127 | ||||
139 | def __init__(self, arg, *args, **kwargs): | 128 | def __init__(self, arg, *args, **kwargs): | ||
140 | self.root = arg | 129 | self.root = arg | ||
141 | self.set_of_tones = set() | 130 | self.set_of_tones = set() | ||
142 | self.set_of_tones.add(arg) | 131 | self.set_of_tones.add(arg) | ||
143 | for item in args: | 132 | for item in args: | ||
n | 144 | if isinstance(item,tuple): | n | 133 | if isinstance(item, tuple): |
145 | res = [] | 134 | temporary_transition_list = [] | ||
146 | res.extend(item) | 135 | temporary_transition_list.extend(item) | ||
147 | self.set_of_tones.update(res) | 136 | self.set_of_tones.update(temporary_transition_list) | ||
148 | else: | 137 | else: | ||
149 | self.set_of_tones.update(set(args)) | 138 | self.set_of_tones.update(set(args)) | ||
n | 150 | for _, value in kwargs.items(): | n | 139 | for value in kwargs.values(): |
151 | self.set_of_tones.add(value) | 140 | self.set_of_tones.add(value) | ||
152 | if len(self.set_of_tones) < 2: | 141 | if len(self.set_of_tones) < 2: | ||
153 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 142 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
154 | 143 | ||||
155 | 144 | ||||
156 | def __str__(self): | 145 | def __str__(self): | ||
157 | return "-".join(t.tone for t in sort_tones(self.set_of_tones, self.root)) | 146 | return "-".join(t.tone for t in sort_tones(self.set_of_tones, self.root)) | ||
n | 158 | n | |||
159 | |||||
160 | 147 | ||||
161 | def is_minor(self): | 148 | def is_minor(self): | ||
162 | for el in self.set_of_tones: | 149 | for el in self.set_of_tones: | ||
163 | interval = self.root - el | 150 | interval = self.root - el | ||
164 | if el == self.root: | 151 | if el == self.root: | ||
165 | continue | 152 | continue | ||
166 | elif interval.interval == "minor 3rd": | 153 | elif interval.interval == "minor 3rd": | ||
167 | return True | 154 | return True | ||
168 | return False | 155 | return False | ||
169 | 156 | ||||
n | 170 | n | |||
171 | def is_major(self): | 157 | def is_major(self): | ||
172 | for el in self.set_of_tones: | 158 | for el in self.set_of_tones: | ||
173 | interval = self.root - el | 159 | interval = self.root - el | ||
174 | if el == self.root: | 160 | if el == self.root: | ||
175 | continue | 161 | continue | ||
176 | elif interval.interval == "major 3rd": | 162 | elif interval.interval == "major 3rd": | ||
177 | return True | 163 | return True | ||
178 | return False | 164 | return False | ||
179 | 165 | ||||
n | 180 | n | |||
181 | def is_power_chord(self): | 166 | def is_power_chord(self): | ||
n | 182 | return self.is_major() is False and self.is_minor() is False | n | 167 | return not self.is_major() and not self.is_minor() |
183 | |||||
184 | 168 | ||||
185 | def __add__(self, other): | 169 | def __add__(self, other): | ||
186 | if isinstance(other, Tone): | 170 | if isinstance(other, Tone): | ||
187 | self.set_of_tones.add(other) | 171 | self.set_of_tones.add(other) | ||
188 | sort_tones(self.set_of_tones, self.root) | 172 | sort_tones(self.set_of_tones, self.root) | ||
189 | return self | 173 | return self | ||
190 | if isinstance(other, Chord): | 174 | if isinstance(other, Chord): | ||
191 | self.set_of_tones.update(other.set_of_tones) | 175 | self.set_of_tones.update(other.set_of_tones) | ||
192 | placeholed = self | 176 | placeholed = self | ||
193 | return placeholed | 177 | return placeholed | ||
n | 194 | n | |||
195 | 178 | ||||
196 | def __sub__(self, other): | 179 | def __sub__(self, other): | ||
197 | if other not in self.set_of_tones: | 180 | if other not in self.set_of_tones: | ||
198 | raise TypeError(f"Cannot remove tone {other} from chord {self}") | 181 | raise TypeError(f"Cannot remove tone {other} from chord {self}") | ||
199 | elif len(self.set_of_tones) < 3: | 182 | elif len(self.set_of_tones) < 3: | ||
200 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 183 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
201 | else: | 184 | else: | ||
202 | self.set_of_tones.remove(other) | 185 | self.set_of_tones.remove(other) | ||
203 | sort_tones(self.set_of_tones, self.root) | 186 | sort_tones(self.set_of_tones, self.root) | ||
204 | if self.root == other: | 187 | if self.root == other: | ||
205 | self.root = list(self.set_of_tones)[0] | 188 | self.root = list(self.set_of_tones)[0] | ||
206 | return self | 189 | return self | ||
207 | 190 | ||||
n | 208 | #Не баца за отрицателен интер и тая си е | n | ||
209 | def transposed(self, inter): | 191 | def transposed(self, inter): | ||
210 | notes = sort_tones(self.set_of_tones,self.root) | 192 | notes = sort_tones(self.set_of_tones,self.root) | ||
211 | for i in range(0,3): | 193 | for i in range(0,3): | ||
212 | notes[i] = notes[i] + inter | 194 | notes[i] = notes[i] + inter | ||
213 | return Chord(notes[0], tuple(notes)) | 195 | return Chord(notes[0], tuple(notes)) | ||
n | n | 196 | |||
197 | c, d_sharp, g = Tone("C"), Tone("D#"), Tone("G") | ||||
198 | c_minor_chord = Chord(c, d_sharp, g) | ||||
199 | print(str(c_minor_chord)) | ||||
200 | # "C-D#-G" | ||||
201 | d_minor_chord = c_minor_chord.transposed(Interval(2)) | ||||
202 | print(str(d_minor_chord)) | ||||
203 | # "D-F-A" | ||||
214 | 204 | ||||
t | t | 205 | a_sharp_minor_chord = d_minor_chord.transposed(-Interval(4)) | ||
206 | print(str(a_sharp_minor_chord)) | ||||
207 | # "A#-C#-F" |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | NOTE_ORDER=["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | f | 1 | NOTE_ORDER=["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] |
n | n | 2 | |||
2 | def sort_tones(tone_set, root): | 3 | def sort_tones(tone_set, root): | ||
3 | note_order = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | 4 | note_order = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] | ||
4 | index = note_order.index(root.tone) | 5 | index = note_order.index(root.tone) | ||
5 | 6 | ||||
6 | note_order = note_order[index:] + note_order[:index] | 7 | note_order = note_order[index:] + note_order[:index] | ||
7 | 8 | ||||
8 | order_dict = {tone: index for index, tone in enumerate(note_order)} | 9 | order_dict = {tone: index for index, tone in enumerate(note_order)} | ||
9 | sorted_tones = sorted(tone_set, key=lambda tone: order_dict.get(tone.tone, float('inf'))) | 10 | sorted_tones = sorted(tone_set, key=lambda tone: order_dict.get(tone.tone, float('inf'))) | ||
10 | return sorted_tones | 11 | return sorted_tones | ||
11 | 12 | ||||
n | n | 13 | |||
12 | class Tone: | 14 | class Tone: | ||
n | n | 15 | |||
16 | |||||
13 | def __init__(self, tone): | 17 | def __init__(self, tone): | ||
14 | self.tone = tone | 18 | self.tone = tone | ||
n | n | 19 | |||
20 | |||||
15 | def __str__(self): | 21 | def __str__(self): | ||
16 | return self.tone | 22 | return self.tone | ||
n | n | 23 | |||
24 | |||||
17 | def __eq__(self, other): | 25 | def __eq__(self, other): | ||
18 | if isinstance(other, Tone): | 26 | if isinstance(other, Tone): | ||
19 | return self.tone == other.tone | 27 | return self.tone == other.tone | ||
20 | else: | 28 | else: | ||
21 | return self.tone == other | 29 | return self.tone == other | ||
n | n | 30 | |||
31 | |||||
22 | def __hash__(self): | 32 | def __hash__(self): | ||
23 | return hash(self.tone) | 33 | return hash(self.tone) | ||
n | n | 34 | |||
35 | |||||
24 | def __add__(self, other): | 36 | def __add__(self, other): | ||
25 | if isinstance(other, Tone): | 37 | if isinstance(other, Tone): | ||
26 | return Chord(self,other) | 38 | return Chord(self,other) | ||
27 | elif isinstance(other, Interval): | 39 | elif isinstance(other, Interval): | ||
28 | return Tone(NOTE_ORDER[(other.go_back_yourself() + NOTE_ORDER.index(self))%12]) | 40 | return Tone(NOTE_ORDER[(other.go_back_yourself() + NOTE_ORDER.index(self))%12]) | ||
n | n | 41 | |||
42 | |||||
29 | def __sub__(self, other): | 43 | def __sub__(self, other): | ||
30 | if isinstance(other, Tone): | 44 | if isinstance(other, Tone): | ||
31 | return Interval(NOTE_ORDER.index(self) + NOTE_ORDER.index(other)) | 45 | return Interval(NOTE_ORDER.index(self) + NOTE_ORDER.index(other)) | ||
32 | elif isinstance(other, Interval): | 46 | elif isinstance(other, Interval): | ||
33 | return Tone(NOTE_ORDER[(NOTE_ORDER.index(self) - other.go_back_yourself())%12]) | 47 | return Tone(NOTE_ORDER[(NOTE_ORDER.index(self) - other.go_back_yourself())%12]) | ||
34 | 48 | ||||
n | n | 49 | |||
35 | class Interval: | 50 | class Interval: | ||
n | n | 51 | |||
52 | |||||
36 | def __init__(self, semitone_number): | 53 | def __init__(self, semitone_number): | ||
37 | match semitone_number % 12: | 54 | match semitone_number % 12: | ||
38 | case 0: | 55 | case 0: | ||
39 | self.interval="unison" | 56 | self.interval="unison" | ||
40 | case 1: | 57 | case 1: | ||
41 | self.interval = "minor 2nd" | 58 | self.interval = "minor 2nd" | ||
42 | case 2: | 59 | case 2: | ||
43 | self.interval = "major 2nd" | 60 | self.interval = "major 2nd" | ||
44 | case 3: | 61 | case 3: | ||
45 | self.interval = "minor 3rd" | 62 | self.interval = "minor 3rd" | ||
46 | case 4: | 63 | case 4: | ||
47 | self.interval = "major 3rd" | 64 | self.interval = "major 3rd" | ||
48 | case 5: | 65 | case 5: | ||
49 | self.interval = "perfect 4th" | 66 | self.interval = "perfect 4th" | ||
50 | case 6: | 67 | case 6: | ||
51 | self.interval = "diminished 5th" | 68 | self.interval = "diminished 5th" | ||
52 | case 7: | 69 | case 7: | ||
53 | self.interval = "perfect 5th" | 70 | self.interval = "perfect 5th" | ||
54 | case 8: | 71 | case 8: | ||
55 | self.interval = "minor 6th" | 72 | self.interval = "minor 6th" | ||
56 | case 9: | 73 | case 9: | ||
57 | self.interval = "major 6th" | 74 | self.interval = "major 6th" | ||
58 | case 10: | 75 | case 10: | ||
59 | self.interval = "minor 7th" | 76 | self.interval = "minor 7th" | ||
60 | case 11: | 77 | case 11: | ||
61 | self.interval = "major 7th" | 78 | self.interval = "major 7th" | ||
62 | case _: | 79 | case _: | ||
63 | self.interval = '''Живот ли бе — да го опишеш? | 80 | self.interval = '''Живот ли бе — да го опишеш? | ||
64 | 81 | ||||
65 | Живот ли бе — да го разровиш? | 82 | Живот ли бе — да го разровиш? | ||
66 | 83 | ||||
67 | Разровиш ли го — ще мирише | 84 | Разровиш ли го — ще мирише | ||
68 | 85 | ||||
69 | и ще горчи като отрова.''' | 86 | и ще горчи като отрова.''' | ||
n | n | 87 | |||
88 | |||||
70 | def __str__(self): | 89 | def __str__(self): | ||
71 | return self.interval | 90 | return self.interval | ||
n | n | 91 | |||
92 | |||||
72 | def go_back_yourself(self): | 93 | def go_back_yourself(self): | ||
73 | match self.interval: | 94 | match self.interval: | ||
74 | case "unison": | 95 | case "unison": | ||
75 | return 0 | 96 | return 0 | ||
76 | case "minor 2nd": | 97 | case "minor 2nd": | ||
77 | return 1 | 98 | return 1 | ||
78 | case "major 2nd": | 99 | case "major 2nd": | ||
79 | return 2 | 100 | return 2 | ||
80 | case "minor 3rd": | 101 | case "minor 3rd": | ||
81 | return 3 | 102 | return 3 | ||
82 | case "major 3rd": | 103 | case "major 3rd": | ||
83 | return 4 | 104 | return 4 | ||
84 | case "perfect 4th": | 105 | case "perfect 4th": | ||
85 | return 5 | 106 | return 5 | ||
86 | case "diminished 5th": | 107 | case "diminished 5th": | ||
87 | return 6 | 108 | return 6 | ||
88 | case "perfect 5th": | 109 | case "perfect 5th": | ||
89 | return 7 | 110 | return 7 | ||
90 | case "minor 6th": | 111 | case "minor 6th": | ||
91 | return 8 | 112 | return 8 | ||
92 | case "major 6th": | 113 | case "major 6th": | ||
93 | return 9 | 114 | return 9 | ||
94 | case "minor 7th": | 115 | case "minor 7th": | ||
95 | return 10 | 116 | return 10 | ||
96 | case "major 7th": | 117 | case "major 7th": | ||
97 | return 11 | 118 | return 11 | ||
98 | case _: | 119 | case _: | ||
99 | self.interval = "Само онзи, който е живял, страдал и плакал с народа си – само той може да го разбере и да му помогне."+"Христо Ботев" + "He would have hated java" | 120 | self.interval = "Само онзи, който е живял, страдал и плакал с народа си – само той може да го разбере и да му помогне."+"Христо Ботев" + "He would have hated java" | ||
n | n | 121 | |||
122 | |||||
100 | def __add__(self, other): | 123 | def __add__(self, other): | ||
101 | if isinstance(other, Tone): | 124 | if isinstance(other, Tone): | ||
102 | raise TypeError("Invalid operation") | 125 | raise TypeError("Invalid operation") | ||
103 | if isinstance(other, Interval): | 126 | if isinstance(other, Interval): | ||
104 | plc=Interval(self.go_back_yourself() + other.go_back_yourself()) | 127 | plc=Interval(self.go_back_yourself() + other.go_back_yourself()) | ||
105 | return plc | 128 | return plc | ||
n | n | 129 | |||
130 | |||||
106 | def __sub__(self, other): | 131 | def __sub__(self, other): | ||
107 | if isinstance(other, Tone): | 132 | if isinstance(other, Tone): | ||
108 | raise TypeError("Invalid operation") | 133 | raise TypeError("Invalid operation") | ||
109 | 134 | ||||
110 | 135 | ||||
111 | class Chord: | 136 | class Chord: | ||
n | n | 137 | |||
138 | |||||
112 | def __init__(self, arg, *args, **kwargs): | 139 | def __init__(self, arg, *args, **kwargs): | ||
113 | self.root = arg | 140 | self.root = arg | ||
114 | self.set_of_tones = set() | 141 | self.set_of_tones = set() | ||
115 | self.set_of_tones.add(arg) | 142 | self.set_of_tones.add(arg) | ||
116 | for item in args: | 143 | for item in args: | ||
117 | if isinstance(item,tuple): | 144 | if isinstance(item,tuple): | ||
118 | res = [] | 145 | res = [] | ||
119 | res.extend(item) | 146 | res.extend(item) | ||
120 | self.set_of_tones.update(res) | 147 | self.set_of_tones.update(res) | ||
121 | else: | 148 | else: | ||
122 | self.set_of_tones.update(set(args)) | 149 | self.set_of_tones.update(set(args)) | ||
123 | for _, value in kwargs.items(): | 150 | for _, value in kwargs.items(): | ||
124 | self.set_of_tones.add(value) | 151 | self.set_of_tones.add(value) | ||
125 | if len(self.set_of_tones) < 2: | 152 | if len(self.set_of_tones) < 2: | ||
126 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 153 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
n | n | 154 | |||
155 | |||||
127 | def __str__(self): | 156 | def __str__(self): | ||
128 | return "-".join(t.tone for t in sort_tones(self.set_of_tones, self.root)) | 157 | return "-".join(t.tone for t in sort_tones(self.set_of_tones, self.root)) | ||
n | n | 158 | |||
159 | |||||
160 | |||||
129 | def is_minor(self): | 161 | def is_minor(self): | ||
130 | for el in self.set_of_tones: | 162 | for el in self.set_of_tones: | ||
131 | interval = self.root - el | 163 | interval = self.root - el | ||
132 | if el == self.root: | 164 | if el == self.root: | ||
133 | continue | 165 | continue | ||
134 | elif interval.interval == "minor 3rd": | 166 | elif interval.interval == "minor 3rd": | ||
135 | return True | 167 | return True | ||
136 | return False | 168 | return False | ||
n | n | 169 | |||
170 | |||||
137 | def is_major(self): | 171 | def is_major(self): | ||
138 | for el in self.set_of_tones: | 172 | for el in self.set_of_tones: | ||
139 | interval = self.root - el | 173 | interval = self.root - el | ||
140 | if el == self.root: | 174 | if el == self.root: | ||
141 | continue | 175 | continue | ||
142 | elif interval.interval == "major 3rd": | 176 | elif interval.interval == "major 3rd": | ||
143 | return True | 177 | return True | ||
144 | return False | 178 | return False | ||
n | n | 179 | |||
180 | |||||
145 | def is_power_chord(self): | 181 | def is_power_chord(self): | ||
146 | return self.is_major() is False and self.is_minor() is False | 182 | return self.is_major() is False and self.is_minor() is False | ||
n | n | 183 | |||
184 | |||||
147 | def __add__(self, other): | 185 | def __add__(self, other): | ||
148 | if isinstance(other, Tone): | 186 | if isinstance(other, Tone): | ||
149 | self.set_of_tones.add(other) | 187 | self.set_of_tones.add(other) | ||
150 | sort_tones(self.set_of_tones, self.root) | 188 | sort_tones(self.set_of_tones, self.root) | ||
151 | return self | 189 | return self | ||
152 | if isinstance(other, Chord): | 190 | if isinstance(other, Chord): | ||
153 | self.set_of_tones.update(other.set_of_tones) | 191 | self.set_of_tones.update(other.set_of_tones) | ||
154 | placeholed = self | 192 | placeholed = self | ||
155 | return placeholed | 193 | return placeholed | ||
n | n | 194 | |||
195 | |||||
156 | def __sub__(self, other): | 196 | def __sub__(self, other): | ||
157 | if other not in self.set_of_tones: | 197 | if other not in self.set_of_tones: | ||
158 | raise TypeError(f"Cannot remove tone {other} from chord {self}") | 198 | raise TypeError(f"Cannot remove tone {other} from chord {self}") | ||
159 | elif len(self.set_of_tones) < 3: | 199 | elif len(self.set_of_tones) < 3: | ||
160 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 200 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
161 | else: | 201 | else: | ||
162 | self.set_of_tones.remove(other) | 202 | self.set_of_tones.remove(other) | ||
163 | sort_tones(self.set_of_tones, self.root) | 203 | sort_tones(self.set_of_tones, self.root) | ||
164 | if self.root == other: | 204 | if self.root == other: | ||
165 | self.root = list(self.set_of_tones)[0] | 205 | self.root = list(self.set_of_tones)[0] | ||
166 | return self | 206 | return self | ||
n | n | 207 | |||
167 | #Не баца за отрицателен инпут и тая си е | 208 | #Не баца за отрицателен интер и тая си е | ||
168 | def transposed(self, inter): | 209 | def transposed(self, inter): | ||
169 | notes = sort_tones(self.set_of_tones,self.root) | 210 | notes = sort_tones(self.set_of_tones,self.root) | ||
170 | for i in range(0,3): | 211 | for i in range(0,3): | ||
171 | notes[i] = notes[i] + inter | 212 | notes[i] = notes[i] + inter | ||
172 | return Chord(notes[0], tuple(notes)) | 213 | return Chord(notes[0], tuple(notes)) | ||
t | t | 214 |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|