1class Tone:
2 """A class that represents a musical tone."""
3 TONES = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")
4
5 def __init__(self, tone):
6 if tone not in Tone.TONES or not tone:
7 raise ValueError("Invalid input for tone")
8 self.tone = tone
9
10 def __str__(self):
11 return self.tone
12
13 def __eq__(self, other):
14 if isinstance(other, Tone):
15 return self.tone == other.tone
16 return False
17
18 def __add__(self, other):
19 if isinstance(other, Interval):
20 return self.add_interval(other)
21 if isinstance(other, Tone):
22 return Chord(self, other)
23 raise TypeError("Invalid operation")
24
25 def __sub__(self, other):
26 if isinstance(other, Interval):
27 return self.sub_interval(other)
28 if isinstance(self, Tone) and isinstance(other, Tone):
29 return Interval(abs(self.TONES.index(self.tone) - other.TONES.index(other.tone)))
30 raise TypeError("Invalid operation")
31
32 def add_interval(self, other):
33 """A method that adds an interval to a tone and returns new tone."""
34 if isinstance(other, Tone):
35 raise TypeError("Invalid operation")
36 elif isinstance(self, Tone) and isinstance(other, Interval):
37 cur_tone_index = self.TONES.index(self.tone)
38 new_index = (cur_tone_index + other.number_of_semitones) % len(self.TONES)
39 return Tone(self.TONES[new_index])
40 raise TypeError("Invalid operation")
41
42 def sub_interval(self, other):
43 """A method that subtracts an interval to a tone and returns new tone."""
44 if isinstance(self, Tone) and isinstance(other, Interval):
45 cur_tone_index = self.TONES.index(self.tone)
46 new_index = abs((cur_tone_index - other.number_of_semitones) % len(self.TONES))
47 return Tone(self.TONES[new_index])
48 if isinstance(other, Tone):
49 raise TypeError("Invalid operation")
50 raise TypeError("Invalid operation")
51
52
53class Interval:
54 """A class that represents a musical interval."""
55 INTERVALS = ("unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th",
56 "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th")
57 INTERVALS_LENGTH = len(INTERVALS)
58
59 def __init__(self, number_of_semitones):
60 if not isinstance(number_of_semitones, int):
61 raise TypeError("Invalid input for number of semitones")
62 self.number_of_semitones = number_of_semitones % Interval.INTERVALS_LENGTH
63
64 def __str__(self):
65 return self.INTERVALS[self.number_of_semitones % Interval.INTERVALS_LENGTH]
66
67 def __add__(self, other):
68 if isinstance(self, Interval) and isinstance(other, Interval):
69 return Interval(self.number_of_semitones + other.number_of_semitones)
70 raise TypeError("Invalid operation")
71
72 def __sub__(self, other):
73 raise TypeError("Invalid operation")
74
75 def __neg__(self):
76 return Interval(-self.number_of_semitones)
77
78
79class Chord:
80 """A class that represents a musical chord."""
81
82 def __init__(self, *args):
83 if len(args) == 0:
84 raise TypeError("Empty chord")
85 self.root = args[0].tone
86 self.all_tones = []
87 for cur_tone in args:
88 if cur_tone not in self.all_tones:
89 self.all_tones.append(cur_tone)
90
91 if len(self.all_tones) == 1:
92 raise TypeError("Cannot have a chord made of only 1 unique tone")
93
94 root_index = Tone.TONES.index(self.root)
95 sorted_all_tones = []
96 sorted_all_tones.append(Tone.TONES[root_index])
97
98 for i in range(1, len(Tone.TONES)):
99 current_index = (root_index + i) % len(Tone.TONES)
100 current_tone = Tone.TONES[current_index]
101 if Tone(current_tone) in self.all_tones:
102 sorted_all_tones.append(current_tone)
103 self.all_tones = sorted_all_tones
104
105 def __str__(self):
106 return "-".join(str(cur_tone) for cur_tone in self.all_tones)
107
108 def is_minor(self):
109 """A method that checks if there is a tone in the chord that together
110 with the root tone form minor 3rd interval. Returns a boolean."""
111 root_index = Tone.TONES.index(self.root)
112 for tone in self.all_tones:
113 tone_index = Tone.TONES.index(tone)
114 if tone == self.root:
115 continue
116 elif tone_index - root_index == 3:
117 return True
118 elif (root_index - tone_index) % 12 == 9:
119 return True
120 return False
121
122 def is_major(self):
123 """A method that checks if there is a tone in the chord that together
124 with the root tone form major 3rd interval. Returns a boolean."""
125 root_index = Tone.TONES.index(self.root)
126 for tone in self.all_tones:
127 tone_index = Tone.TONES.index(tone)
128 if tone == self.root:
129 continue
130 elif tone_index - root_index == 4:
131 return True
132 elif (root_index - tone_index) % 12 == 9:
133 return True
134 return False
135
136 def is_power_chord(self):
137 """A method that checks if a chord does not contain a tone that, together
138 with the root, forms a minor 3rd or a major 3rd. Returns a boolean."""
139 if not self.is_major() and not self.is_minor():
140 return True
141 return False
142
143 def __add__(self, other):
144 if isinstance(other, Tone):
145 return Chord(*map(Tone, self.all_tones + [other.tone]))
146 if isinstance(other, Chord):
147 result = []
148 for tone in self.all_tones:
149 result.append(Tone(tone))
150 for tone in other.all_tones:
151 result.append(Tone(tone))
152 return Chord(*result)
153 raise TypeError("Invalid operation")
154
155 def __sub__(self, other):
156 if isinstance(other, Tone):
157 result = []
158 additional_tone = Tone(other.tone)
159 result.append(Tone(other.tone))
160 for tone in self.all_tones:
161 if Tone(tone) == additional_tone:
162 result.remove(additional_tone)
163 else:
164 result.append(Tone(tone))
165 if additional_tone in result:
166 raise TypeError(f"Cannot remove tone {Tone(other.tone)} from chord {str(self)}")
167 return Chord(*result)
168 raise TypeError("Invalid operation")
169
170 def transposed(self, interval):
171 """A method that shifts each of its tones by the same interval."""
172 transposed_tones = [Tone(tone) + interval for tone in self.all_tones]
173 return Chord(*transposed_tones)
....F.F............................F.
======================================================================
FAIL: test_is_major (test.TestBasicChordFunctionality.test_is_major)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 103, in test_is_major
self.assertFalse(a_minor_chord.is_major())
AssertionError: True is not false
======================================================================
FAIL: test_is_power_chord (test.TestBasicChordFunctionality.test_is_power_chord)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 120, in test_is_power_chord
self.assertFalse(a_major_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=3)
Росица Илиева
04.11.2024 16:33Много благодаря!
|
Георги Кунчев
04.11.2024 16:24Ето пример:
```
reference_list = ['най-малко', 'по-малко', 'нещо', 'по-голямо', 'най-голямо']
to_be_sorted = ['най-голямо', 'нещо', 'по-малко']
print(sorted(to_be_sorted, key=lambda x: reference_list.index(x))) # ['по-малко', 'нещо', 'най-голямо']
```
`key` атрибутът на `sorted` очаква функция, която връща някаква стойност. Тази стойност се използва за сортирането вместо самите стойности в `to_be_sorted`.
Създавайки функцията `lambda x: reference_list.index(x)`, просто връщаме индекса на даден елемент в списъка `reference_list`.
Ако сортираме `to_be_sorted`, използвайки не стойностите в него, а резултата от функцията, извикана със конкретния елемент, всъщност сортираме елементите сравнявайки индексите им в списъка `reference_list`.
В горния пример индексите са съответно:
4 - най-голямо (4 е резултатът от `reference_list.index('най-голямо')`;
2 - нещо (2 е резултатът от `reference_list.index('нещо')`;
1 - по-малко (1 е резултатът от `reference_list.index('по-малко')`.
Тъй като сортирането не става по стойността на текста, а по индекса (4, 2, 1), резултатът е ['по-малко', 'нещо', 'най-голямо']
|
Росица Илиева
04.11.2024 16:04Може ли да ме насочите повече как трябва да сортирам с sorted(some_list, key=lambda x: ordered_list.index(x)), тъй като ламбда функциите доста ме объркват, и както и да се опитвам да го направя по този начин, не се получава?
|
| f | 1 | class Tone: | f | 1 | class Tone: |
| 2 | """A class that represents a musical tone.""" | 2 | """A class that represents a musical tone.""" | ||
| n | 3 | tones = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B") | n | 3 | TONES = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B") |
| 4 | |||||
| 4 | def __init__(self, tone): | 5 | def __init__(self, tone): | ||
| n | 5 | if tone not in Tone.tones or not tone: | n | 6 | if tone not in Tone.TONES or not tone: |
| 6 | raise ValueError("Invalid input for tone") | 7 | raise ValueError("Invalid input for tone") | ||
| 7 | self.tone = tone | 8 | self.tone = tone | ||
| 8 | 9 | ||||
| 9 | def __str__(self): | 10 | def __str__(self): | ||
| n | 10 | return f"{self.tone}" | n | 11 | return self.tone |
| 11 | 12 | ||||
| 12 | def __eq__(self, other): | 13 | def __eq__(self, other): | ||
| 13 | if isinstance(other, Tone): | 14 | if isinstance(other, Tone): | ||
| 14 | return self.tone == other.tone | 15 | return self.tone == other.tone | ||
| 15 | return False | 16 | return False | ||
| 16 | 17 | ||||
| 17 | def __add__(self, other): | 18 | def __add__(self, other): | ||
| 18 | if isinstance(other, Interval): | 19 | if isinstance(other, Interval): | ||
| 19 | return self.add_interval(other) | 20 | return self.add_interval(other) | ||
| 20 | if isinstance(other, Tone): | 21 | if isinstance(other, Tone): | ||
| 21 | return Chord(self, other) | 22 | return Chord(self, other) | ||
| n | n | 23 | raise TypeError("Invalid operation") | ||
| 22 | 24 | ||||
| 23 | def __sub__(self, other): | 25 | def __sub__(self, other): | ||
| 24 | if isinstance(other, Interval): | 26 | if isinstance(other, Interval): | ||
| 25 | return self.sub_interval(other) | 27 | return self.sub_interval(other) | ||
| 26 | if isinstance(self, Tone) and isinstance(other, Tone): | 28 | if isinstance(self, Tone) and isinstance(other, Tone): | ||
| n | 27 | return Interval(abs(self.tones.index(self.tone) - other.tones.index(other.tone))) | n | 29 | return Interval(abs(self.TONES.index(self.tone) - other.TONES.index(other.tone))) |
| 30 | raise TypeError("Invalid operation") | ||||
| 28 | 31 | ||||
| 29 | def add_interval(self, other): | 32 | def add_interval(self, other): | ||
| n | n | 33 | """A method that adds an interval to a tone and returns new tone.""" | ||
| 30 | if isinstance(other, Tone): | 34 | if isinstance(other, Tone): | ||
| 31 | raise TypeError("Invalid operation") | 35 | raise TypeError("Invalid operation") | ||
| 32 | elif isinstance(self, Tone) and isinstance(other, Interval): | 36 | elif isinstance(self, Tone) and isinstance(other, Interval): | ||
| n | 33 | cur_tone_index = self.tones.index(self.tone) | n | 37 | cur_tone_index = self.TONES.index(self.tone) |
| 34 | new_index = (cur_tone_index + other.number_of_semitones) % len(self.tones) | 38 | new_index = (cur_tone_index + other.number_of_semitones) % len(self.TONES) | ||
| 35 | return Tone(self.tones[new_index]) | 39 | return Tone(self.TONES[new_index]) | ||
| 40 | raise TypeError("Invalid operation") | ||||
| 36 | 41 | ||||
| 37 | def sub_interval(self, other): | 42 | def sub_interval(self, other): | ||
| n | n | 43 | """A method that subtracts an interval to a tone and returns new tone.""" | ||
| 38 | if isinstance(self, Tone) and isinstance(other, Interval): | 44 | if isinstance(self, Tone) and isinstance(other, Interval): | ||
| n | 39 | cur_tone_index = self.tones.index(self.tone) | n | 45 | cur_tone_index = self.TONES.index(self.tone) |
| 40 | new_index = abs((cur_tone_index - other.number_of_semitones) % len(self.tones)) | 46 | new_index = abs((cur_tone_index - other.number_of_semitones) % len(self.TONES)) | ||
| 41 | return Tone(self.tones[new_index]) | 47 | return Tone(self.TONES[new_index]) | ||
| 42 | if isinstance(other, Tone): | 48 | if isinstance(other, Tone): | ||
| 43 | raise TypeError("Invalid operation") | 49 | raise TypeError("Invalid operation") | ||
| n | n | 50 | raise TypeError("Invalid operation") | ||
| 51 | |||||
| 44 | 52 | ||||
| 45 | class Interval: | 53 | class Interval: | ||
| 46 | """A class that represents a musical interval.""" | 54 | """A class that represents a musical interval.""" | ||
| n | 47 | intervals = {0 : "unison", 1 : "minor 2nd", 2 : "major 2nd", 3 : "minor 3rd", 4 : "major 3rd", 5 : "perfect 4th", | n | 55 | INTERVALS = ("unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", |
| 48 | 6 : "diminished 5th", 7 : "perfect 5th", 8 : "minor 6th", 9 : "major 6th", 10 : "minor 7th", 11 : "major 7th"} | 56 | "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th") | ||
| 57 | INTERVALS_LENGTH = len(INTERVALS) | ||||
| 49 | 58 | ||||
| 50 | def __init__(self, number_of_semitones): | 59 | def __init__(self, number_of_semitones): | ||
| 51 | if not isinstance(number_of_semitones, int): | 60 | if not isinstance(number_of_semitones, int): | ||
| 52 | raise TypeError("Invalid input for number of semitones") | 61 | raise TypeError("Invalid input for number of semitones") | ||
| n | 53 | self.number_of_semitones = number_of_semitones % 12 | n | 62 | self.number_of_semitones = number_of_semitones % Interval.INTERVALS_LENGTH |
| 54 | 63 | ||||
| 55 | def __str__(self): | 64 | def __str__(self): | ||
| n | 56 | return f"{self.intervals[self.number_of_semitones % 12]}" | n | 65 | return self.INTERVALS[self.number_of_semitones % Interval.INTERVALS_LENGTH] |
| 57 | 66 | ||||
| 58 | def __add__(self, other): | 67 | def __add__(self, other): | ||
| 59 | if isinstance(self, Interval) and isinstance(other, Interval): | 68 | if isinstance(self, Interval) and isinstance(other, Interval): | ||
| 60 | return Interval(self.number_of_semitones + other.number_of_semitones) | 69 | return Interval(self.number_of_semitones + other.number_of_semitones) | ||
| n | 61 | n | 70 | raise TypeError("Invalid operation") | |
| 71 | |||||
| 72 | def __sub__(self, other): | ||||
| 73 | raise TypeError("Invalid operation") | ||||
| 74 | |||||
| 62 | def __neg__(self): | 75 | def __neg__(self): | ||
| 63 | return Interval(-self.number_of_semitones) | 76 | return Interval(-self.number_of_semitones) | ||
| n | 64 | n | 77 | ||
| 78 | |||||
| 65 | class Chord: | 79 | class Chord: | ||
| n | 66 | """A class that represents a musical chord.""" | n | 80 | """A class that represents a musical chord.""" |
| 81 | |||||
| 67 | def __init__(self, *args): | 82 | def __init__(self, *args): | ||
| 68 | if len(args) == 0: | 83 | if len(args) == 0: | ||
| 69 | raise TypeError("Empty chord") | 84 | raise TypeError("Empty chord") | ||
| n | 70 | self.root = str(args[0]) | n | 85 | self.root = args[0].tone |
| 71 | self.all_thones = [] | 86 | self.all_tones = [] | ||
| 72 | for cur_tone in args: | 87 | for cur_tone in args: | ||
| n | 73 | if cur_tone not in self.all_thones: | n | 88 | if cur_tone not in self.all_tones: |
| 74 | self.all_thones.append(cur_tone) | 89 | self.all_tones.append(cur_tone) | ||
| 75 | 90 | ||||
| n | 76 | if len(self.all_thones) == 1: | n | 91 | if len(self.all_tones) == 1: |
| 77 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 92 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
| 78 | 93 | ||||
| n | 79 | root_index = Tone.tones.index(self.root) | n | 94 | root_index = Tone.TONES.index(self.root) |
| 80 | sorted_all_thones = [] | 95 | sorted_all_tones = [] | ||
| 81 | sorted_all_thones.append(Tone.tones[root_index]) | 96 | sorted_all_tones.append(Tone.TONES[root_index]) | ||
| 82 | 97 | ||||
| n | 83 | for i in range(1, len(Tone.tones)): | n | 98 | for i in range(1, len(Tone.TONES)): |
| 84 | current_index = (root_index + i) % len(Tone.tones) | 99 | current_index = (root_index + i) % len(Tone.TONES) | ||
| 85 | current_tone = Tone.tones[current_index] | 100 | current_tone = Tone.TONES[current_index] | ||
| 86 | if Tone(current_tone) in self.all_thones: | 101 | if Tone(current_tone) in self.all_tones: | ||
| 87 | sorted_all_thones.append(current_tone) | 102 | sorted_all_tones.append(current_tone) | ||
| 88 | self.all_thones = sorted_all_thones | 103 | self.all_tones = sorted_all_tones | ||
| 89 | 104 | ||||
| 90 | def __str__(self): | 105 | def __str__(self): | ||
| n | 91 | return "-".join(str(cur_tone) for cur_tone in self.all_thones) | n | 106 | return "-".join(str(cur_tone) for cur_tone in self.all_tones) |
| 92 | 107 | ||||
| 93 | def is_minor(self): | 108 | def is_minor(self): | ||
| n | n | 109 | """A method that checks if there is a tone in the chord that together | ||
| 110 | with the root tone form minor 3rd interval. Returns a boolean.""" | ||||
| 94 | root_index = Tone.tones.index(self.root) | 111 | root_index = Tone.TONES.index(self.root) | ||
| 95 | for tone in self.all_thones: | 112 | for tone in self.all_tones: | ||
| 96 | tone_index = Tone.tones.index(tone) | 113 | tone_index = Tone.TONES.index(tone) | ||
| 97 | if tone == self.root: | 114 | if tone == self.root: | ||
| 98 | continue | 115 | continue | ||
| 99 | elif tone_index - root_index == 3: | 116 | elif tone_index - root_index == 3: | ||
| 100 | return True | 117 | return True | ||
| n | 101 | elif tone_index in (0, 1, 2) and root_index == tone_index + 9: | n | 118 | elif (root_index - tone_index) % 12 == 9: |
| 102 | return True | ||||
| 103 | elif tone_index in (9, 10, 11) and root_index == tone_index - 9: | ||||
| 104 | return True | 119 | return True | ||
| 105 | return False | 120 | return False | ||
| n | 106 | n | 121 | ||
| 107 | def is_major(self): | 122 | def is_major(self): | ||
| n | n | 123 | """A method that checks if there is a tone in the chord that together | ||
| 124 | with the root tone form major 3rd interval. Returns a boolean.""" | ||||
| 108 | root_index = Tone.tones.index(self.root) | 125 | root_index = Tone.TONES.index(self.root) | ||
| 109 | for tone in self.all_thones: | 126 | for tone in self.all_tones: | ||
| 110 | tone_index = Tone.tones.index(tone) | 127 | tone_index = Tone.TONES.index(tone) | ||
| 111 | if tone == self.root: | 128 | if tone == self.root: | ||
| 112 | continue | 129 | continue | ||
| 113 | elif tone_index - root_index == 4: | 130 | elif tone_index - root_index == 4: | ||
| 114 | return True | 131 | return True | ||
| n | 115 | elif tone_index in (0, 1, 2, 3) and root_index == tone_index + 8: | n | 132 | elif (root_index - tone_index) % 12 == 9: |
| 116 | return True | ||||
| 117 | elif tone_index in (8, 9, 10, 11) and root_index == tone_index - 8: | ||||
| 118 | return True | 133 | return True | ||
| 119 | return False | 134 | return False | ||
| 120 | 135 | ||||
| 121 | def is_power_chord(self): | 136 | def is_power_chord(self): | ||
| n | n | 137 | """A method that checks if a chord does not contain a tone that, together | ||
| 138 | with the root, forms a minor 3rd or a major 3rd. Returns a boolean.""" | ||||
| 122 | if self.is_major() is False and self.is_minor() is False: | 139 | if not self.is_major() and not self.is_minor(): | ||
| 123 | return True | 140 | return True | ||
| 124 | return False | 141 | return False | ||
| n | 125 | n | 142 | ||
| 126 | def __add__(self, other): | 143 | def __add__(self, other): | ||
| 127 | if isinstance(other, Tone): | 144 | if isinstance(other, Tone): | ||
| n | 128 | result = [] | n | 145 | return Chord(*map(Tone, self.all_tones + [other.tone])) |
| 129 | for tone in self.all_thones: | ||||
| 130 | result.append(Tone(tone)) | ||||
| 131 | result.append(Tone(other.tone)) | ||||
| 132 | return Chord(*result) | ||||
| 133 | if isinstance(other, Chord): | 146 | if isinstance(other, Chord): | ||
| 134 | result = [] | 147 | result = [] | ||
| n | 135 | for tone in self.all_thones: | n | 148 | for tone in self.all_tones: |
| 136 | result.append(Tone(tone)) | 149 | result.append(Tone(tone)) | ||
| n | 137 | for tone in other.all_thones: | n | 150 | for tone in other.all_tones: |
| 138 | result.append(Tone(tone)) | 151 | result.append(Tone(tone)) | ||
| 139 | return Chord(*result) | 152 | return Chord(*result) | ||
| n | 140 | n | 153 | raise TypeError("Invalid operation") | |
| 154 | |||||
| 141 | def __sub__(self, other): | 155 | def __sub__(self, other): | ||
| 142 | if isinstance(other, Tone): | 156 | if isinstance(other, Tone): | ||
| 143 | result = [] | 157 | result = [] | ||
| 144 | additional_tone = Tone(other.tone) | 158 | additional_tone = Tone(other.tone) | ||
| 145 | result.append(Tone(other.tone)) | 159 | result.append(Tone(other.tone)) | ||
| n | 146 | for tone in self.all_thones: | n | 160 | for tone in self.all_tones: |
| 147 | if Tone(tone) == additional_tone: | 161 | if Tone(tone) == additional_tone: | ||
| 148 | result.remove(additional_tone) | 162 | result.remove(additional_tone) | ||
| 149 | else: | 163 | else: | ||
| 150 | result.append(Tone(tone)) | 164 | result.append(Tone(tone)) | ||
| 151 | if additional_tone in result: | 165 | if additional_tone in result: | ||
| n | 152 | raise TypeError(f"Cannot remove tone {Tone(other.tone)} from chord {Chord(*(Tone(tone) for tone in self.all_thones))}") | n | 166 | raise TypeError(f"Cannot remove tone {Tone(other.tone)} from chord {str(self)}") |
| 153 | return Chord(*result) | 167 | return Chord(*result) | ||
| n | n | 168 | raise TypeError("Invalid operation") | ||
| 154 | 169 | ||||
| 155 | def transposed(self, interval): | 170 | def transposed(self, interval): | ||
| t | t | 171 | """A method that shifts each of its tones by the same interval.""" | ||
| 156 | transposed_tones = [Tone(tone) + interval for tone in self.all_thones] | 172 | transposed_tones = [Tone(tone) + interval for tone in self.all_tones] | ||
| 157 | return Chord(*transposed_tones) | 173 | return Chord(*transposed_tones) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||