1class Tone:
2 NOTES = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")
3 NOTE_COUNT = 12
4
5 def __init__(self, name):
6 if name not in Tone.NOTES:
7 raise TypeError("Invalid tone")
8 self.name = name
9 self.index = Tone.NOTES.index(name)
10
11 def __str__(self):
12 return self.name
13
14 def __add__(self, other):
15 if isinstance(other, Interval):
16 new_index = (self.index + other.steps) % self.NOTE_COUNT
17 return Tone(Tone.NOTES[new_index])
18 elif isinstance(other, Tone):
19 return Chord(self, other)
20 raise TypeError("Invalid operation")
21
22 def __sub__(self, other):
23 if isinstance(other, Interval):
24 new_index = (self.index - other.steps) % self.NOTE_COUNT
25 return Tone(Tone.NOTES[new_index])
26 elif isinstance(other, Tone):
27 steps = (self.index - other.index) % self.NOTE_COUNT
28 return Interval(steps)
29 raise TypeError("Invalid operation")
30
31 def __hash__(self):
32 return hash(self.name)
33
34 def __eq__(self, other):
35 if isinstance(other, Tone):
36 return self.name == other.name
37 return False
38
39
40class Interval:
41 INTERVAL_NAMES = {0: "unison", 1: "minor 2nd",
42 2: "major 2nd", 3: "minor 3rd",
43 4: "major 3rd", 5: "perfect 4th",
44 6: "diminished 5th", 7: "perfect 5th",
45 8: "minor 6th", 9: "major 6th",
46 10: "minor 7th", 11: "major 7th"}
47
48 def __init__(self, steps):
49 self.steps = steps % Tone.NOTE_COUNT
50
51 def __str__(self):
52 return Interval.INTERVAL_NAMES[self.steps]
53
54 def __add__(self, other):
55 if isinstance(other, Interval):
56 return Interval(self.steps + other.steps)
57 raise TypeError("Invalid operation")
58
59 def __sub__(self, other):
60 if isinstance(other, Tone):
61 raise TypeError("Invalid operation")
62
63 def __neg__(self):
64 return Interval(-self.steps)
65
66class Chord:
67 def __init__(self, root, *tones):
68 unique_tones = {root} | set(tones)
69 if len(unique_tones) < 2:
70 raise TypeError("Cannot have a chord made of only 1 unique tone")
71 self.root = root
72 self.tones = sorted(unique_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT)
73 self.tone_names = set(map(lambda tone: tone.name, self.tones))
74
75 def __str__(self):
76 return "-".join(str(tone) for tone in self.tones)
77
78 def __add__(self, other):
79 if isinstance(other, Tone):
80 return Chord(self.root, *self.tones, other)
81 elif isinstance(other, Chord):
82 new_tones = {self.root} | set(self.tones + other.tones)
83 return Chord(self.root, *(new_tones))
84 elif isinstance(other, Interval):
85 return self.transposed(other)
86 raise TypeError("Invalid operation")
87
88 def __sub__(self, other):
89 if isinstance(other, Tone):
90 if other.name not in self.tone_names:
91 raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
92 remaining_tones = set(filter(lambda tone: tone.name != other.name, self.tones))
93 if len(remaining_tones) < 2:
94 raise TypeError("Cannot have a chord made of only 1 unique tone")
95 if self.root not in remaining_tones:
96 new_root = min(remaining_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT)
97 return Chord(new_root, *remaining_tones)
98 else:
99 return Chord(self.root, *remaining_tones)
100 raise TypeError("Invalid operation")
101
102 def is_minor(self):
103 minor_3rd = Interval(3)
104 return any((tone - self.root).steps == minor_3rd.steps for tone in self.tones)
105
106 def is_major(self):
107 major_3rd = Interval(4)
108 return any((tone - self.root).steps == major_3rd.steps for tone in self.tones)
109
110 def is_power_chord(self):
111 return not (self.is_minor() or self.is_major())
112
113 def transposed(self, interval):
114 transposed_tones = list(map(lambda tone: tone + interval, self.tones))
115 return Chord(*transposed_tones)
.....................................
----------------------------------------------------------------------
Ran 37 tests in 0.001s
OK
f | 1 | class Tone: | f | 1 | class Tone: |
2 | NOTES = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B") | 2 | NOTES = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B") | ||
3 | NOTE_COUNT = 12 | 3 | NOTE_COUNT = 12 | ||
4 | 4 | ||||
5 | def __init__(self, name): | 5 | def __init__(self, name): | ||
6 | if name not in Tone.NOTES: | 6 | if name not in Tone.NOTES: | ||
7 | raise TypeError("Invalid tone") | 7 | raise TypeError("Invalid tone") | ||
8 | self.name = name | 8 | self.name = name | ||
9 | self.index = Tone.NOTES.index(name) | 9 | self.index = Tone.NOTES.index(name) | ||
10 | 10 | ||||
11 | def __str__(self): | 11 | def __str__(self): | ||
12 | return self.name | 12 | return self.name | ||
13 | 13 | ||||
14 | def __add__(self, other): | 14 | def __add__(self, other): | ||
15 | if isinstance(other, Interval): | 15 | if isinstance(other, Interval): | ||
16 | new_index = (self.index + other.steps) % self.NOTE_COUNT | 16 | new_index = (self.index + other.steps) % self.NOTE_COUNT | ||
17 | return Tone(Tone.NOTES[new_index]) | 17 | return Tone(Tone.NOTES[new_index]) | ||
18 | elif isinstance(other, Tone): | 18 | elif isinstance(other, Tone): | ||
19 | return Chord(self, other) | 19 | return Chord(self, other) | ||
20 | raise TypeError("Invalid operation") | 20 | raise TypeError("Invalid operation") | ||
21 | 21 | ||||
22 | def __sub__(self, other): | 22 | def __sub__(self, other): | ||
23 | if isinstance(other, Interval): | 23 | if isinstance(other, Interval): | ||
24 | new_index = (self.index - other.steps) % self.NOTE_COUNT | 24 | new_index = (self.index - other.steps) % self.NOTE_COUNT | ||
25 | return Tone(Tone.NOTES[new_index]) | 25 | return Tone(Tone.NOTES[new_index]) | ||
26 | elif isinstance(other, Tone): | 26 | elif isinstance(other, Tone): | ||
27 | steps = (self.index - other.index) % self.NOTE_COUNT | 27 | steps = (self.index - other.index) % self.NOTE_COUNT | ||
28 | return Interval(steps) | 28 | return Interval(steps) | ||
29 | raise TypeError("Invalid operation") | 29 | raise TypeError("Invalid operation") | ||
30 | 30 | ||||
31 | def __hash__(self): | 31 | def __hash__(self): | ||
32 | return hash(self.name) | 32 | return hash(self.name) | ||
33 | 33 | ||||
34 | def __eq__(self, other): | 34 | def __eq__(self, other): | ||
35 | if isinstance(other, Tone): | 35 | if isinstance(other, Tone): | ||
36 | return self.name == other.name | 36 | return self.name == other.name | ||
37 | return False | 37 | return False | ||
38 | 38 | ||||
39 | 39 | ||||
40 | class Interval: | 40 | class Interval: | ||
41 | INTERVAL_NAMES = {0: "unison", 1: "minor 2nd", | 41 | INTERVAL_NAMES = {0: "unison", 1: "minor 2nd", | ||
42 | 2: "major 2nd", 3: "minor 3rd", | 42 | 2: "major 2nd", 3: "minor 3rd", | ||
43 | 4: "major 3rd", 5: "perfect 4th", | 43 | 4: "major 3rd", 5: "perfect 4th", | ||
44 | 6: "diminished 5th", 7: "perfect 5th", | 44 | 6: "diminished 5th", 7: "perfect 5th", | ||
45 | 8: "minor 6th", 9: "major 6th", | 45 | 8: "minor 6th", 9: "major 6th", | ||
46 | 10: "minor 7th", 11: "major 7th"} | 46 | 10: "minor 7th", 11: "major 7th"} | ||
47 | 47 | ||||
48 | def __init__(self, steps): | 48 | def __init__(self, steps): | ||
49 | self.steps = steps % Tone.NOTE_COUNT | 49 | self.steps = steps % Tone.NOTE_COUNT | ||
50 | 50 | ||||
51 | def __str__(self): | 51 | def __str__(self): | ||
52 | return Interval.INTERVAL_NAMES[self.steps] | 52 | return Interval.INTERVAL_NAMES[self.steps] | ||
53 | 53 | ||||
54 | def __add__(self, other): | 54 | def __add__(self, other): | ||
55 | if isinstance(other, Interval): | 55 | if isinstance(other, Interval): | ||
56 | return Interval(self.steps + other.steps) | 56 | return Interval(self.steps + other.steps) | ||
57 | raise TypeError("Invalid operation") | 57 | raise TypeError("Invalid operation") | ||
58 | 58 | ||||
59 | def __sub__(self, other): | 59 | def __sub__(self, other): | ||
60 | if isinstance(other, Tone): | 60 | if isinstance(other, Tone): | ||
61 | raise TypeError("Invalid operation") | 61 | raise TypeError("Invalid operation") | ||
62 | 62 | ||||
63 | def __neg__(self): | 63 | def __neg__(self): | ||
64 | return Interval(-self.steps) | 64 | return Interval(-self.steps) | ||
65 | 65 | ||||
66 | class Chord: | 66 | class Chord: | ||
67 | def __init__(self, root, *tones): | 67 | def __init__(self, root, *tones): | ||
68 | unique_tones = {root} | set(tones) | 68 | unique_tones = {root} | set(tones) | ||
69 | if len(unique_tones) < 2: | 69 | if len(unique_tones) < 2: | ||
70 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 70 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
71 | self.root = root | 71 | self.root = root | ||
72 | self.tones = sorted(unique_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT) | 72 | self.tones = sorted(unique_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT) | ||
73 | self.tone_names = set(map(lambda tone: tone.name, self.tones)) | 73 | self.tone_names = set(map(lambda tone: tone.name, self.tones)) | ||
74 | 74 | ||||
75 | def __str__(self): | 75 | def __str__(self): | ||
76 | return "-".join(str(tone) for tone in self.tones) | 76 | return "-".join(str(tone) for tone in self.tones) | ||
77 | 77 | ||||
78 | def __add__(self, other): | 78 | def __add__(self, other): | ||
79 | if isinstance(other, Tone): | 79 | if isinstance(other, Tone): | ||
80 | return Chord(self.root, *self.tones, other) | 80 | return Chord(self.root, *self.tones, other) | ||
81 | elif isinstance(other, Chord): | 81 | elif isinstance(other, Chord): | ||
t | 82 | new_tones = {self.root} | set(self.tones) | set(other.tones) | t | 82 | new_tones = {self.root} | set(self.tones + other.tones) |
83 | return Chord(self.root, *(new_tones)) | 83 | return Chord(self.root, *(new_tones)) | ||
84 | elif isinstance(other, Interval): | 84 | elif isinstance(other, Interval): | ||
85 | return self.transposed(other) | 85 | return self.transposed(other) | ||
86 | raise TypeError("Invalid operation") | 86 | raise TypeError("Invalid operation") | ||
87 | 87 | ||||
88 | def __sub__(self, other): | 88 | def __sub__(self, other): | ||
89 | if isinstance(other, Tone): | 89 | if isinstance(other, Tone): | ||
90 | if other.name not in self.tone_names: | 90 | if other.name not in self.tone_names: | ||
91 | raise TypeError(f"Cannot remove tone {other.name} from chord {self}") | 91 | raise TypeError(f"Cannot remove tone {other.name} from chord {self}") | ||
92 | remaining_tones = set(filter(lambda tone: tone.name != other.name, self.tones)) | 92 | remaining_tones = set(filter(lambda tone: tone.name != other.name, self.tones)) | ||
93 | if len(remaining_tones) < 2: | 93 | if len(remaining_tones) < 2: | ||
94 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 94 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
95 | if self.root not in remaining_tones: | 95 | if self.root not in remaining_tones: | ||
96 | new_root = min(remaining_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT) | 96 | new_root = min(remaining_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT) | ||
97 | return Chord(new_root, *remaining_tones) | 97 | return Chord(new_root, *remaining_tones) | ||
98 | else: | 98 | else: | ||
99 | return Chord(self.root, *remaining_tones) | 99 | return Chord(self.root, *remaining_tones) | ||
100 | raise TypeError("Invalid operation") | 100 | raise TypeError("Invalid operation") | ||
101 | 101 | ||||
102 | def is_minor(self): | 102 | def is_minor(self): | ||
103 | minor_3rd = Interval(3) | 103 | minor_3rd = Interval(3) | ||
104 | return any((tone - self.root).steps == minor_3rd.steps for tone in self.tones) | 104 | return any((tone - self.root).steps == minor_3rd.steps for tone in self.tones) | ||
105 | 105 | ||||
106 | def is_major(self): | 106 | def is_major(self): | ||
107 | major_3rd = Interval(4) | 107 | major_3rd = Interval(4) | ||
108 | return any((tone - self.root).steps == major_3rd.steps for tone in self.tones) | 108 | return any((tone - self.root).steps == major_3rd.steps for tone in self.tones) | ||
109 | 109 | ||||
110 | def is_power_chord(self): | 110 | def is_power_chord(self): | ||
111 | return not (self.is_minor() or self.is_major()) | 111 | return not (self.is_minor() or self.is_major()) | ||
112 | 112 | ||||
113 | def transposed(self, interval): | 113 | def transposed(self, interval): | ||
114 | transposed_tones = list(map(lambda tone: tone + interval, self.tones)) | 114 | transposed_tones = list(map(lambda tone: tone + interval, self.tones)) | ||
115 | return Chord(*transposed_tones) | 115 | return Chord(*transposed_tones) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | class Tone: | f | 1 | class Tone: |
2 | NOTES = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B") | 2 | NOTES = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B") | ||
3 | NOTE_COUNT = 12 | 3 | NOTE_COUNT = 12 | ||
4 | 4 | ||||
5 | def __init__(self, name): | 5 | def __init__(self, name): | ||
6 | if name not in Tone.NOTES: | 6 | if name not in Tone.NOTES: | ||
7 | raise TypeError("Invalid tone") | 7 | raise TypeError("Invalid tone") | ||
8 | self.name = name | 8 | self.name = name | ||
9 | self.index = Tone.NOTES.index(name) | 9 | self.index = Tone.NOTES.index(name) | ||
10 | 10 | ||||
11 | def __str__(self): | 11 | def __str__(self): | ||
12 | return self.name | 12 | return self.name | ||
13 | 13 | ||||
14 | def __add__(self, other): | 14 | def __add__(self, other): | ||
15 | if isinstance(other, Interval): | 15 | if isinstance(other, Interval): | ||
16 | new_index = (self.index + other.steps) % self.NOTE_COUNT | 16 | new_index = (self.index + other.steps) % self.NOTE_COUNT | ||
17 | return Tone(Tone.NOTES[new_index]) | 17 | return Tone(Tone.NOTES[new_index]) | ||
18 | elif isinstance(other, Tone): | 18 | elif isinstance(other, Tone): | ||
19 | return Chord(self, other) | 19 | return Chord(self, other) | ||
20 | raise TypeError("Invalid operation") | 20 | raise TypeError("Invalid operation") | ||
21 | 21 | ||||
22 | def __sub__(self, other): | 22 | def __sub__(self, other): | ||
23 | if isinstance(other, Interval): | 23 | if isinstance(other, Interval): | ||
24 | new_index = (self.index - other.steps) % self.NOTE_COUNT | 24 | new_index = (self.index - other.steps) % self.NOTE_COUNT | ||
25 | return Tone(Tone.NOTES[new_index]) | 25 | return Tone(Tone.NOTES[new_index]) | ||
26 | elif isinstance(other, Tone): | 26 | elif isinstance(other, Tone): | ||
27 | steps = (self.index - other.index) % self.NOTE_COUNT | 27 | steps = (self.index - other.index) % self.NOTE_COUNT | ||
28 | return Interval(steps) | 28 | return Interval(steps) | ||
29 | raise TypeError("Invalid operation") | 29 | raise TypeError("Invalid operation") | ||
30 | 30 | ||||
31 | def __hash__(self): | 31 | def __hash__(self): | ||
32 | return hash(self.name) | 32 | return hash(self.name) | ||
33 | 33 | ||||
34 | def __eq__(self, other): | 34 | def __eq__(self, other): | ||
35 | if isinstance(other, Tone): | 35 | if isinstance(other, Tone): | ||
36 | return self.name == other.name | 36 | return self.name == other.name | ||
37 | return False | 37 | return False | ||
38 | 38 | ||||
39 | 39 | ||||
40 | class Interval: | 40 | class Interval: | ||
41 | INTERVAL_NAMES = {0: "unison", 1: "minor 2nd", | 41 | INTERVAL_NAMES = {0: "unison", 1: "minor 2nd", | ||
42 | 2: "major 2nd", 3: "minor 3rd", | 42 | 2: "major 2nd", 3: "minor 3rd", | ||
43 | 4: "major 3rd", 5: "perfect 4th", | 43 | 4: "major 3rd", 5: "perfect 4th", | ||
44 | 6: "diminished 5th", 7: "perfect 5th", | 44 | 6: "diminished 5th", 7: "perfect 5th", | ||
45 | 8: "minor 6th", 9: "major 6th", | 45 | 8: "minor 6th", 9: "major 6th", | ||
46 | 10: "minor 7th", 11: "major 7th"} | 46 | 10: "minor 7th", 11: "major 7th"} | ||
47 | 47 | ||||
48 | def __init__(self, steps): | 48 | def __init__(self, steps): | ||
49 | self.steps = steps % Tone.NOTE_COUNT | 49 | self.steps = steps % Tone.NOTE_COUNT | ||
50 | 50 | ||||
51 | def __str__(self): | 51 | def __str__(self): | ||
52 | return Interval.INTERVAL_NAMES[self.steps] | 52 | return Interval.INTERVAL_NAMES[self.steps] | ||
53 | 53 | ||||
54 | def __add__(self, other): | 54 | def __add__(self, other): | ||
55 | if isinstance(other, Interval): | 55 | if isinstance(other, Interval): | ||
56 | return Interval(self.steps + other.steps) | 56 | return Interval(self.steps + other.steps) | ||
57 | raise TypeError("Invalid operation") | 57 | raise TypeError("Invalid operation") | ||
58 | 58 | ||||
t | t | 59 | def __sub__(self, other): | ||
60 | if isinstance(other, Tone): | ||||
61 | raise TypeError("Invalid operation") | ||||
62 | |||||
59 | def __neg__(self): | 63 | def __neg__(self): | ||
60 | return Interval(-self.steps) | 64 | return Interval(-self.steps) | ||
61 | 65 | ||||
62 | class Chord: | 66 | class Chord: | ||
63 | def __init__(self, root, *tones): | 67 | def __init__(self, root, *tones): | ||
64 | unique_tones = {root} | set(tones) | 68 | unique_tones = {root} | set(tones) | ||
65 | if len(unique_tones) < 2: | 69 | if len(unique_tones) < 2: | ||
66 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 70 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
67 | self.root = root | 71 | self.root = root | ||
68 | self.tones = sorted(unique_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT) | 72 | self.tones = sorted(unique_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT) | ||
69 | self.tone_names = set(map(lambda tone: tone.name, self.tones)) | 73 | self.tone_names = set(map(lambda tone: tone.name, self.tones)) | ||
70 | 74 | ||||
71 | def __str__(self): | 75 | def __str__(self): | ||
72 | return "-".join(str(tone) for tone in self.tones) | 76 | return "-".join(str(tone) for tone in self.tones) | ||
73 | 77 | ||||
74 | def __add__(self, other): | 78 | def __add__(self, other): | ||
75 | if isinstance(other, Tone): | 79 | if isinstance(other, Tone): | ||
76 | return Chord(self.root, *self.tones, other) | 80 | return Chord(self.root, *self.tones, other) | ||
77 | elif isinstance(other, Chord): | 81 | elif isinstance(other, Chord): | ||
78 | new_tones = {self.root} | set(self.tones) | set(other.tones) | 82 | new_tones = {self.root} | set(self.tones) | set(other.tones) | ||
79 | return Chord(self.root, *(new_tones)) | 83 | return Chord(self.root, *(new_tones)) | ||
80 | elif isinstance(other, Interval): | 84 | elif isinstance(other, Interval): | ||
81 | return self.transposed(other) | 85 | return self.transposed(other) | ||
82 | raise TypeError("Invalid operation") | 86 | raise TypeError("Invalid operation") | ||
83 | 87 | ||||
84 | def __sub__(self, other): | 88 | def __sub__(self, other): | ||
85 | if isinstance(other, Tone): | 89 | if isinstance(other, Tone): | ||
86 | if other.name not in self.tone_names: | 90 | if other.name not in self.tone_names: | ||
87 | raise TypeError(f"Cannot remove tone {other.name} from chord {self}") | 91 | raise TypeError(f"Cannot remove tone {other.name} from chord {self}") | ||
88 | remaining_tones = set(filter(lambda tone: tone.name != other.name, self.tones)) | 92 | remaining_tones = set(filter(lambda tone: tone.name != other.name, self.tones)) | ||
89 | if len(remaining_tones) < 2: | 93 | if len(remaining_tones) < 2: | ||
90 | raise TypeError("Cannot have a chord made of only 1 unique tone") | 94 | raise TypeError("Cannot have a chord made of only 1 unique tone") | ||
91 | if self.root not in remaining_tones: | 95 | if self.root not in remaining_tones: | ||
92 | new_root = min(remaining_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT) | 96 | new_root = min(remaining_tones, key=lambda tone: (tone.index - self.root.index) % Tone.NOTE_COUNT) | ||
93 | return Chord(new_root, *remaining_tones) | 97 | return Chord(new_root, *remaining_tones) | ||
94 | else: | 98 | else: | ||
95 | return Chord(self.root, *remaining_tones) | 99 | return Chord(self.root, *remaining_tones) | ||
96 | raise TypeError("Invalid operation") | 100 | raise TypeError("Invalid operation") | ||
97 | 101 | ||||
98 | def is_minor(self): | 102 | def is_minor(self): | ||
99 | minor_3rd = Interval(3) | 103 | minor_3rd = Interval(3) | ||
100 | return any((tone - self.root).steps == minor_3rd.steps for tone in self.tones) | 104 | return any((tone - self.root).steps == minor_3rd.steps for tone in self.tones) | ||
101 | 105 | ||||
102 | def is_major(self): | 106 | def is_major(self): | ||
103 | major_3rd = Interval(4) | 107 | major_3rd = Interval(4) | ||
104 | return any((tone - self.root).steps == major_3rd.steps for tone in self.tones) | 108 | return any((tone - self.root).steps == major_3rd.steps for tone in self.tones) | ||
105 | 109 | ||||
106 | def is_power_chord(self): | 110 | def is_power_chord(self): | ||
107 | return not (self.is_minor() or self.is_major()) | 111 | return not (self.is_minor() or self.is_major()) | ||
108 | 112 | ||||
109 | def transposed(self, interval): | 113 | def transposed(self, interval): | ||
110 | transposed_tones = list(map(lambda tone: tone + interval, self.tones)) | 114 | transposed_tones = list(map(lambda tone: tone + interval, self.tones)) | ||
111 | return Chord(*transposed_tones) | 115 | return Chord(*transposed_tones) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
07.11.2024 11:09
07.11.2024 11:10
07.11.2024 11:10
07.11.2024 11:11
07.11.2024 11:13
07.11.2024 11:12
07.11.2024 11:17