Домашни > Pitches love the D > Решения > Решението на Мая Панова

Резултати
10 точки от тестове
0 точки от учител

10 точки общо

37 успешни теста
0 неуспешни теста
Код

  1from collections import OrderedDict
  2
  3class Tone:
  4    TONES_ORDER = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
  5    TONES_TOTAL = len(TONES_ORDER)
  6
  7    def __init__(self, name):
  8        if name not in Tone.TONES_ORDER:
  9           raise Exception(f'{name} is not a valid tone!')
 10        self.name = name
 11
 12    def __str__(self):
 13        return self.name
 14    
 15    def __eq__(self, other):
 16        if not isinstance(other, Tone):
 17
 18            return False
 19        return self.name == other.name
 20
 21    def __add__(self, other):
 22        if isinstance(other, Tone):
 23            return Chord(self, other)
 24        elif isinstance(other, Interval):
 25            current_tone_idx = Tone.TONES_ORDER.index(self.name)
 26            new_tone_idx = (current_tone_idx + other.num_semitones) % Tone.TONES_TOTAL
 27
 28            new_tone = Tone.TONES_ORDER[new_tone_idx]
 29            return Tone(new_tone)
 30    
 31    def __sub__(self, other):
 32        if isinstance(other, Tone):
 33            self_tone_idx = Tone.TONES_ORDER.index(self.name)
 34            other_tone_idx = Tone.TONES_ORDER.index(other.name)
 35
 36            num_semitones = (self_tone_idx - other_tone_idx) % Tone.TONES_TOTAL
 37            return Interval(num_semitones)
 38        elif isinstance(other, Interval):
 39            return self + (-other)
 40    
 41    def __hash__(self):
 42        return hash(self.name)
 43
 44
 45class Interval:
 46    INTERVAL_NAMES = (
 47            'unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 
 48            'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th'
 49                     )
 50    def __init__(self, num_semitones):
 51        if not isinstance(num_semitones, int):
 52            raise TypeError('Number of semitones must be an integer! :)')
 53        self.num_semitones = num_semitones % Tone.TONES_TOTAL
 54    
 55    def __str__(self):
 56        return Interval.INTERVAL_NAMES[self.num_semitones]
 57    
 58    def __add__(self, other):
 59        if isinstance(other, Interval):
 60            new_interval = self.num_semitones + other.num_semitones
 61            return Interval(new_interval)
 62        raise TypeError ('Invalid operation')
 63
 64    def __sub__(self, other):
 65        if isinstance(other, Tone):
 66            raise TypeError ('Invalid operation')
 67        
 68    def __neg__(self):
 69        return Interval(-self.num_semitones)
 70
 71
 72class Chord:
 73    def __init__(self, *args):
 74        if any(not isinstance(t, Tone) for t in args):
 75            raise TypeError('One or more arguments are not of type Tone!')
 76
 77        ordered_tones_set = OrderedDict.fromkeys(args)
 78
 79        self.distinct_tones = list(ordered_tones_set.keys())
 80
 81        if len(self.distinct_tones) == 1:
 82            raise TypeError("Cannot have a chord made of only 1 unique tone")
 83
 84    def __str__(self):
 85        root_tone = self.distinct_tones[0]
 86        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
 87        
 88        final_order_tones = []
 89
 90        for i in range(Tone.TONES_TOTAL):
 91            current_tone_idx = (i + root_tone_idx) % Tone.TONES_TOTAL 
 92            current_tone = Tone.TONES_ORDER[current_tone_idx]
 93            if Tone(current_tone) in self.distinct_tones:
 94                final_order_tones.append(Tone.TONES_ORDER[current_tone_idx])
 95        return '-'.join(final_order_tones)
 96    
 97    def is_minor(self):
 98        root_tone = self.distinct_tones[0]
 99        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
100
101        minor_3rd_idx =  (root_tone_idx + 3) % Tone.TONES_TOTAL
102        minor_3rd_tone = Tone(Tone.TONES_ORDER[minor_3rd_idx])
103
104        return minor_3rd_tone in self.distinct_tones
105
106    def is_major(self): 
107        root_tone = self.distinct_tones[0]
108        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
109
110        major_3rd_idx =  (root_tone_idx + 4) % Tone.TONES_TOTAL
111        major_3rd_tone = Tone(Tone.TONES_ORDER[major_3rd_idx])
112
113        return major_3rd_tone in self.distinct_tones
114
115    def is_power_chord(self):
116        return not self.is_minor() and not self.is_major()
117    
118    def __add__(self, other):
119        if isinstance(other, Tone):
120            if other in self.distinct_tones:
121                return self 
122            
123            new_distinct_tones = self.distinct_tones[:]
124            new_distinct_tones.append(other)  
125            return Chord(*new_distinct_tones)
126        
127        elif isinstance(other, Chord):
128            combined_tones = self.distinct_tones + other.distinct_tones
129            return Chord(*combined_tones) 
130        
131    def __sub__(self, other):
132        if isinstance(other, Tone):
133            if other not in self.distinct_tones:
134                raise TypeError(f'Cannot remove tone {other.name} from chord {self}')
135            
136            new_distinct_tones = self.distinct_tones[:]
137            new_distinct_tones.remove(other)
138            return Chord(*new_distinct_tones)
139    
140    def transposed(self, interval):
141        if isinstance(interval, Interval):
142            transposed_tones = [tone + interval for tone in self.distinct_tones]
143
144            return Chord(*transposed_tones)
145            

.....................................
----------------------------------------------------------------------
Ran 37 tests in 0.001s

OK

Дискусия
Мая Панова
06.11.2024 16:10

Разбрах, благодаря :)
Виктор Бечев
06.11.2024 15:42

Останалите грешки не са проблем, имах предвид съобщенията на тези, които ни вълнуват. И за двете няма да ти дам повече, защото ще е еквивалентно на това да ти кажа къде имаш проблеми в кода. Споменах колкото споменах, защото не ми се ще в стремежа си да имаш по-хубаво решение да получиш някоя друга точка по-малко.
Мая Панова
06.11.2024 15:35

Изпуснала съм да променя transposed метода..видях
Мая Панова
06.11.2024 14:46

Аз онази грешка я написах просто, защото ми е странно да проверявам няколко различни isinstance, но да не raise-вам грешки, ако стане нещо друго.. въпреки че сте казали, че ще тествате само за грешките, които изрично сте опоменали. Та въпросът ми е останалите грешки, които raise-вам да ги махна ли? Също...да това променя решението вече можем да работим с tone, вместо със str(tone), но тези words of caution са защото все пак съм объркала нещо ли? :D
Виктор Бечев
06.11.2024 13:49

Word of caution - помисли дали тази промяна не е афектирала определени парчета функционалност. Second word of caution - провери си внимателно стринговете на грешките дали спазват условието (включително този, на който се бях засмял).
Мая Панова
06.11.2024 00:11

предефинирах __eq__ и вече сравняваме обекти а не str репрезентации
Виктор Бечев
05.11.2024 15:59

Единствената ми генерална забележка е по отношение на решението да пазиш `str()` версиите на тоновете, вместо самите обекти. В случая работи, защото тоновете не пазят кой знае каква допълнителна информация. Но го имай предвид за по-комплексни обекти и взаимовръзки между тях - понякога може да ти трябва да пазиш самите обекти и техния стейт в момента на подаването им на конструктора. Просто за тази задача са достатъчно прости, че можеш да си позволиш да пазиш стринговата им репрезентация и на базата на нея да ги пре-създаваш когато ти трябват.
История

f1from collections import OrderedDictf1from collections import OrderedDict
22
3class Tone:3class Tone:
4    TONES_ORDER = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']4    TONES_ORDER = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
5    TONES_TOTAL = len(TONES_ORDER)5    TONES_TOTAL = len(TONES_ORDER)
66
7    def __init__(self, name):7    def __init__(self, name):
8        if name not in Tone.TONES_ORDER:8        if name not in Tone.TONES_ORDER:
9           raise Exception(f'{name} is not a valid tone!')9           raise Exception(f'{name} is not a valid tone!')
10        self.name = name10        self.name = name
1111
12    def __str__(self):12    def __str__(self):
13        return self.name13        return self.name
14    14    
15    def __eq__(self, other):15    def __eq__(self, other):
16        if not isinstance(other, Tone):16        if not isinstance(other, Tone):
nn17 
17            return False18            return False
18        return self.name == other.name19        return self.name == other.name
1920
20    def __add__(self, other):21    def __add__(self, other):
21        if isinstance(other, Tone):22        if isinstance(other, Tone):
22            return Chord(self, other)23            return Chord(self, other)
23        elif isinstance(other, Interval):24        elif isinstance(other, Interval):
24            current_tone_idx = Tone.TONES_ORDER.index(self.name)25            current_tone_idx = Tone.TONES_ORDER.index(self.name)
25            new_tone_idx = (current_tone_idx + other.num_semitones) % Tone.TONES_TOTAL26            new_tone_idx = (current_tone_idx + other.num_semitones) % Tone.TONES_TOTAL
2627
27            new_tone = Tone.TONES_ORDER[new_tone_idx]28            new_tone = Tone.TONES_ORDER[new_tone_idx]
28            return Tone(new_tone)29            return Tone(new_tone)
29    30    
30    def __sub__(self, other):31    def __sub__(self, other):
31        if isinstance(other, Tone):32        if isinstance(other, Tone):
32            self_tone_idx = Tone.TONES_ORDER.index(self.name)33            self_tone_idx = Tone.TONES_ORDER.index(self.name)
33            other_tone_idx = Tone.TONES_ORDER.index(other.name)34            other_tone_idx = Tone.TONES_ORDER.index(other.name)
3435
35            num_semitones = (self_tone_idx - other_tone_idx) % Tone.TONES_TOTAL36            num_semitones = (self_tone_idx - other_tone_idx) % Tone.TONES_TOTAL
36            return Interval(num_semitones)37            return Interval(num_semitones)
37        elif isinstance(other, Interval):38        elif isinstance(other, Interval):
38            return self + (-other)39            return self + (-other)
39    40    
40    def __hash__(self):41    def __hash__(self):
41        return hash(self.name)42        return hash(self.name)
4243
4344
44class Interval:45class Interval:
45    INTERVAL_NAMES = (46    INTERVAL_NAMES = (
46            'unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 47            'unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 
47            'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th'48            'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th'
48                     )49                     )
49    def __init__(self, num_semitones):50    def __init__(self, num_semitones):
50        if not isinstance(num_semitones, int):51        if not isinstance(num_semitones, int):
51            raise TypeError('Number of semitones must be an integer! :)')52            raise TypeError('Number of semitones must be an integer! :)')
52        self.num_semitones = num_semitones % Tone.TONES_TOTAL53        self.num_semitones = num_semitones % Tone.TONES_TOTAL
53    54    
54    def __str__(self):55    def __str__(self):
55        return Interval.INTERVAL_NAMES[self.num_semitones]56        return Interval.INTERVAL_NAMES[self.num_semitones]
56    57    
57    def __add__(self, other):58    def __add__(self, other):
58        if isinstance(other, Interval):59        if isinstance(other, Interval):
59            new_interval = self.num_semitones + other.num_semitones60            new_interval = self.num_semitones + other.num_semitones
60            return Interval(new_interval)61            return Interval(new_interval)
n61        raise TypeError ('nqkva greshka, ne znam veche...')n62        raise TypeError ('Invalid operation')
6263
63    def __sub__(self, other):64    def __sub__(self, other):
64        if isinstance(other, Tone):65        if isinstance(other, Tone):
n65            raise TypeError ('Invalid operation.')n66            raise TypeError ('Invalid operation')
66        67        
67    def __neg__(self):68    def __neg__(self):
68        return Interval(-self.num_semitones)69        return Interval(-self.num_semitones)
6970
7071
71class Chord:72class Chord:
72    def __init__(self, *args):73    def __init__(self, *args):
73        if any(not isinstance(t, Tone) for t in args):74        if any(not isinstance(t, Tone) for t in args):
74            raise TypeError('One or more arguments are not of type Tone!')75            raise TypeError('One or more arguments are not of type Tone!')
7576
76        ordered_tones_set = OrderedDict.fromkeys(args)77        ordered_tones_set = OrderedDict.fromkeys(args)
7778
78        self.distinct_tones = list(ordered_tones_set.keys())79        self.distinct_tones = list(ordered_tones_set.keys())
7980
80        if len(self.distinct_tones) == 1:81        if len(self.distinct_tones) == 1:
81            raise TypeError("Cannot have a chord made of only 1 unique tone")82            raise TypeError("Cannot have a chord made of only 1 unique tone")
8283
83    def __str__(self):84    def __str__(self):
84        root_tone = self.distinct_tones[0]85        root_tone = self.distinct_tones[0]
85        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)86        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
86        87        
87        final_order_tones = []88        final_order_tones = []
8889
89        for i in range(Tone.TONES_TOTAL):90        for i in range(Tone.TONES_TOTAL):
90            current_tone_idx = (i + root_tone_idx) % Tone.TONES_TOTAL 91            current_tone_idx = (i + root_tone_idx) % Tone.TONES_TOTAL 
91            current_tone = Tone.TONES_ORDER[current_tone_idx]92            current_tone = Tone.TONES_ORDER[current_tone_idx]
92            if Tone(current_tone) in self.distinct_tones:93            if Tone(current_tone) in self.distinct_tones:
93                final_order_tones.append(Tone.TONES_ORDER[current_tone_idx])94                final_order_tones.append(Tone.TONES_ORDER[current_tone_idx])
94        return '-'.join(final_order_tones)95        return '-'.join(final_order_tones)
95    96    
96    def is_minor(self):97    def is_minor(self):
97        root_tone = self.distinct_tones[0]98        root_tone = self.distinct_tones[0]
98        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)99        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
99100
100        minor_3rd_idx =  (root_tone_idx + 3) % Tone.TONES_TOTAL101        minor_3rd_idx =  (root_tone_idx + 3) % Tone.TONES_TOTAL
101        minor_3rd_tone = Tone(Tone.TONES_ORDER[minor_3rd_idx])102        minor_3rd_tone = Tone(Tone.TONES_ORDER[minor_3rd_idx])
102103
103        return minor_3rd_tone in self.distinct_tones104        return minor_3rd_tone in self.distinct_tones
104105
105    def is_major(self): 106    def is_major(self): 
106        root_tone = self.distinct_tones[0]107        root_tone = self.distinct_tones[0]
107        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)108        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
108109
109        major_3rd_idx =  (root_tone_idx + 4) % Tone.TONES_TOTAL110        major_3rd_idx =  (root_tone_idx + 4) % Tone.TONES_TOTAL
110        major_3rd_tone = Tone(Tone.TONES_ORDER[major_3rd_idx])111        major_3rd_tone = Tone(Tone.TONES_ORDER[major_3rd_idx])
111112
112        return major_3rd_tone in self.distinct_tones113        return major_3rd_tone in self.distinct_tones
113114
114    def is_power_chord(self):115    def is_power_chord(self):
115        return not self.is_minor() and not self.is_major()116        return not self.is_minor() and not self.is_major()
116    117    
117    def __add__(self, other):118    def __add__(self, other):
118        if isinstance(other, Tone):119        if isinstance(other, Tone):
119            if other in self.distinct_tones:120            if other in self.distinct_tones:
120                return self 121                return self 
121            122            
122            new_distinct_tones = self.distinct_tones[:]123            new_distinct_tones = self.distinct_tones[:]
123            new_distinct_tones.append(other)  124            new_distinct_tones.append(other)  
124            return Chord(*new_distinct_tones)125            return Chord(*new_distinct_tones)
125        126        
126        elif isinstance(other, Chord):127        elif isinstance(other, Chord):
127            combined_tones = self.distinct_tones + other.distinct_tones128            combined_tones = self.distinct_tones + other.distinct_tones
128            return Chord(*combined_tones) 129            return Chord(*combined_tones) 
129        130        
130    def __sub__(self, other):131    def __sub__(self, other):
131        if isinstance(other, Tone):132        if isinstance(other, Tone):
132            if other not in self.distinct_tones:133            if other not in self.distinct_tones:
n133                raise TypeError(f'Cannot remove tone {other.name} from chord {str(self)}')n134                raise TypeError(f'Cannot remove tone {other.name} from chord {self}')
134            135            
135            new_distinct_tones = self.distinct_tones[:]136            new_distinct_tones = self.distinct_tones[:]
136            new_distinct_tones.remove(other)137            new_distinct_tones.remove(other)
137            return Chord(*new_distinct_tones)138            return Chord(*new_distinct_tones)
138    139    
n139    def transposed(self, inverval):n140    def transposed(self, interval):
140        if isinstance(inverval, Interval):141        if isinstance(interval, Interval):
141            transposed_tones = [Tone(tone) + inverval for tone in self.distinct_tones]142            transposed_tones = [tone + interval for tone in self.distinct_tones]
142143
143            return Chord(*transposed_tones)144            return Chord(*transposed_tones)
tt145            
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

nn1from collections import OrderedDict
2 
1class Tone():3class Tone:
2    tones_order = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']4    TONES_ORDER = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
3    tones_total = len(tones_order)5    TONES_TOTAL = len(TONES_ORDER)
46
5    def __init__(self, name):7    def __init__(self, name):
n6        if name not in Tone.tones_order:n8        if name not in Tone.TONES_ORDER:
7           raise Exception(f'{name} is not a valid tone!')9           raise Exception(f'{name} is not a valid tone!')
n8 n
9        self.name = name10        self.name = name
1011
11    def __str__(self):12    def __str__(self):
12        return self.name13        return self.name
nn14    
15    def __eq__(self, other):
16        if not isinstance(other, Tone):
17            return False
18        return self.name == other.name
1319
14    def __add__(self, other):20    def __add__(self, other):
15        if isinstance(other, Tone):21        if isinstance(other, Tone):
n16            return Chord(other, self)n22            return Chord(self, other)
17        elif isinstance(other, Interval):23        elif isinstance(other, Interval):
n18            current_tone_idx = Tone.tones_order.index(self.name)n24            current_tone_idx = Tone.TONES_ORDER.index(self.name)
19            new_tone_idx = (current_tone_idx + other.num_semitones) % Tone.tones_total25            new_tone_idx = (current_tone_idx + other.num_semitones) % Tone.TONES_TOTAL
2026
n21            new_tone = Tone.tones_order[new_tone_idx]n27            new_tone = Tone.TONES_ORDER[new_tone_idx]
22            return Tone(new_tone)28            return Tone(new_tone)
23    29    
24    def __sub__(self, other):30    def __sub__(self, other):
25        if isinstance(other, Tone):31        if isinstance(other, Tone):
n26            self_tone_idx = Tone.tones_order.index(self.name)n32            self_tone_idx = Tone.TONES_ORDER.index(self.name)
27            other_tone_idx = Tone.tones_order.index(other.name)33            other_tone_idx = Tone.TONES_ORDER.index(other.name)
2834
n29            num_semitones = (self_tone_idx - other_tone_idx) % Tone.tones_totaln35            num_semitones = (self_tone_idx - other_tone_idx) % Tone.TONES_TOTAL
30            return Interval(num_semitones)36            return Interval(num_semitones)
31        elif isinstance(other, Interval):37        elif isinstance(other, Interval):
32            return self + (-other)38            return self + (-other)
nn39    
40    def __hash__(self):
41        return hash(self.name)
3342
3443
n35class Interval():n44class Interval:
45    INTERVAL_NAMES = (
46            'unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 
47            'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th'
48                     )
36    def __init__(self, num_semitones):49    def __init__(self, num_semitones):
37        if not isinstance(num_semitones, int):50        if not isinstance(num_semitones, int):
38            raise TypeError('Number of semitones must be an integer! :)')51            raise TypeError('Number of semitones must be an integer! :)')
n39 n
40        self.num_semitones = num_semitones % Tone.tones_total52        self.num_semitones = num_semitones % Tone.TONES_TOTAL
41    53    
42    def __str__(self):54    def __str__(self):
n43        return (n55        return Interval.INTERVAL_NAMES[self.num_semitones]
44            'unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 
45            'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th'
46               )[self.num_semitones]
47    56    
48    def __add__(self, other):57    def __add__(self, other):
49        if isinstance(other, Interval):58        if isinstance(other, Interval):
50            new_interval = self.num_semitones + other.num_semitones59            new_interval = self.num_semitones + other.num_semitones
51            return Interval(new_interval)60            return Interval(new_interval)
52        raise TypeError ('nqkva greshka, ne znam veche...')61        raise TypeError ('nqkva greshka, ne znam veche...')
5362
54    def __sub__(self, other):63    def __sub__(self, other):
55        if isinstance(other, Tone):64        if isinstance(other, Tone):
56            raise TypeError ('Invalid operation.')65            raise TypeError ('Invalid operation.')
57        66        
58    def __neg__(self):67    def __neg__(self):
59        return Interval(-self.num_semitones)68        return Interval(-self.num_semitones)
6069
6170
n62class Chord():n71class Chord:
63    def __init__(self, *args):72    def __init__(self, *args):
64        if any(not isinstance(t, Tone) for t in args):73        if any(not isinstance(t, Tone) for t in args):
65            raise TypeError('One or more arguments are not of type Tone!')74            raise TypeError('One or more arguments are not of type Tone!')
6675
n67        ordered_tones_set = dict.fromkeys([str(tone) for tone in args])n76        ordered_tones_set = OrderedDict.fromkeys(args)
77 
68        self.distinct_tones = list(ordered_tones_set.keys())78        self.distinct_tones = list(ordered_tones_set.keys())
6979
70        if len(self.distinct_tones) == 1:80        if len(self.distinct_tones) == 1:
71            raise TypeError("Cannot have a chord made of only 1 unique tone")81            raise TypeError("Cannot have a chord made of only 1 unique tone")
7282
73    def __str__(self):83    def __str__(self):
74        root_tone = self.distinct_tones[0]84        root_tone = self.distinct_tones[0]
n75        root_tone_idx = Tone.tones_order.index(root_tone)n85        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
76        86        
77        final_order_tones = []87        final_order_tones = []
7888
n79        for i in range(0, Tone.tones_total):n89        for i in range(Tone.TONES_TOTAL):
80            current_tone_idx = (i + root_tone_idx) % Tone.tones_total 90            current_tone_idx = (i + root_tone_idx) % Tone.TONES_TOTAL 
81            current_tone = Tone.tones_order[current_tone_idx]91            current_tone = Tone.TONES_ORDER[current_tone_idx]
82            if current_tone in self.distinct_tones:92            if Tone(current_tone) in self.distinct_tones:
83                final_order_tones.append(Tone.tones_order[current_tone_idx])93                final_order_tones.append(Tone.TONES_ORDER[current_tone_idx])
84 
85        return '-'.join(final_order_tones)94        return '-'.join(final_order_tones)
86    95    
87    def is_minor(self):96    def is_minor(self):
88        root_tone = self.distinct_tones[0]97        root_tone = self.distinct_tones[0]
n89        root_tone_idx = Tone.tones_order.index(root_tone)n98        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
9099
n91        minor_3rd_idx =  (root_tone_idx + 3) % Tone.tones_totaln100        minor_3rd_idx =  (root_tone_idx + 3) % Tone.TONES_TOTAL
92        minor_3rd_tone = Tone.tones_order[minor_3rd_idx]101        minor_3rd_tone = Tone(Tone.TONES_ORDER[minor_3rd_idx])
93102
94        return minor_3rd_tone in self.distinct_tones103        return minor_3rd_tone in self.distinct_tones
95104
96    def is_major(self): 105    def is_major(self): 
97        root_tone = self.distinct_tones[0]106        root_tone = self.distinct_tones[0]
n98        root_tone_idx = Tone.tones_order.index(root_tone)n107        root_tone_idx = Tone.TONES_ORDER.index(root_tone.name)
99108
n100        major_3rd_idx =  (root_tone_idx + 4) % Tone.tones_totaln109        major_3rd_idx =  (root_tone_idx + 4) % Tone.TONES_TOTAL
101        major_3rd_tone = Tone.tones_order[major_3rd_idx]110        major_3rd_tone = Tone(Tone.TONES_ORDER[major_3rd_idx])
102111
103        return major_3rd_tone in self.distinct_tones112        return major_3rd_tone in self.distinct_tones
104113
105    def is_power_chord(self):114    def is_power_chord(self):
106        return not self.is_minor() and not self.is_major()115        return not self.is_minor() and not self.is_major()
107    116    
108    def __add__(self, other):117    def __add__(self, other):
109        if isinstance(other, Tone):118        if isinstance(other, Tone):
n110            if str(other) in self.distinct_tones:n119            if other in self.distinct_tones:
111                return self  120                return self 
112        121            
113            new_distinct_tones = self.distinct_tones.copy()122            new_distinct_tones = self.distinct_tones[:]
114            new_distinct_tones.append(str(other))  123            new_distinct_tones.append(other)  
115            tones = [Tone(tone) for tone in new_distinct_tones]
116 
117            return Chord(*tones)124            return Chord(*new_distinct_tones)
118        125        
119        elif isinstance(other, Chord):126        elif isinstance(other, Chord):
n120            combined_tones = set(self.distinct_tones + other.distinct_tones)n127            combined_tones = self.distinct_tones + other.distinct_tones
121            tones = [Tone(tone) for tone in combined_tones]
122            return Chord(*tones) 128            return Chord(*combined_tones) 
123        129        
124    def __sub__(self, other):130    def __sub__(self, other):
125        if isinstance(other, Tone):131        if isinstance(other, Tone):
n126            if str(other) not in self.distinct_tones:n132            if other not in self.distinct_tones:
127                raise TypeError(f'Cannot remove tone {other.name} from chord {str(self)}')133                raise TypeError(f'Cannot remove tone {other.name} from chord {str(self)}')
128            134            
t129            new_distinct_tones = self.distinct_tones.copy()t135            new_distinct_tones = self.distinct_tones[:]
130            new_distinct_tones.remove(other.name)136            new_distinct_tones.remove(other)
131            tones = [Tone(tone) for tone in new_distinct_tones]
132 
133            return Chord(*tones)137            return Chord(*new_distinct_tones)
134    138    
135    def transposed(self, inverval):139    def transposed(self, inverval):
136        if isinstance(inverval, Interval):140        if isinstance(inverval, Interval):
137            transposed_tones = [Tone(tone) + inverval for tone in self.distinct_tones]141            transposed_tones = [Tone(tone) + inverval for tone in self.distinct_tones]
138142
139            return Chord(*transposed_tones)143            return Chord(*transposed_tones)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op