Домашни > Pitches love the D > Решения > Решението на Асен Красимиров

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

10 точки общо

36 успешни теста
1 неуспешни теста
Код (Сори за цикъла. Преправям го вече за 4ти път.)

  1ALLOWED_TONE_NAMES = [
  2    "A", "A#",
  3    "B",
  4    "C", "C#",
  5    "D", "D#",
  6    "E",
  7    "F", "F#",
  8    "G", "G#",
  9]
 10
 11SEMITONE_REPRESENTATION = [
 12    "unison",
 13    "minor 2nd",
 14    "major 2nd",
 15    "minor 3rd",
 16    "major 3rd",
 17    "perfect 4th",
 18    "diminished 5th",
 19    "perfect 5th",
 20    "minor 6th",
 21    "major 6th",
 22    "minor 7th",
 23    "major 7th",
 24]
 25
 26
 27class Tone:
 28    def __init__(self, name):
 29        if name not in ALLOWED_TONE_NAMES:
 30            raise ValueError("Name should be a valid tone.")
 31
 32        self.__name = name
 33
 34    def __str__(self):
 35        return self.__name
 36    
 37    def __eq__(self, other):
 38        if not isinstance(other, Tone):
 39            raise TypeError("Incompatible types. Tone object should be compared only to Tone object.")
 40        
 41        return str(self) == str(other)
 42
 43    def __ne__(self, other):
 44        return not self.__eq__(other)
 45    
 46    def __hash__(self):
 47        return hash(self.__name)
 48    
 49    def __add__(self, other):
 50        if isinstance(other, Tone):
 51            return Chord(self, other)
 52        elif isinstance(other, Interval):
 53            tone_index = ALLOWED_TONE_NAMES.index(str(self))
 54            new_tone_index = tone_index + other.semitone_number
 55
 56            new_tone_name = ALLOWED_TONE_NAMES[new_tone_index % len(ALLOWED_TONE_NAMES)]
 57
 58            return Tone(new_tone_name)
 59        
 60        raise TypeError("Incompatible types. Tone object should be added up only with Tone or Interval objects.")
 61        
 62    
 63    def __sub__(self, other):
 64        if isinstance(other, Tone):
 65            tone_index = ALLOWED_TONE_NAMES.index(str(self))
 66            other_tone_index = ALLOWED_TONE_NAMES.index(str(other))
 67            
 68            diff = abs(tone_index - other_tone_index)
 69
 70            return Interval(diff)
 71        elif isinstance(other, Interval):
 72            tone_index = ALLOWED_TONE_NAMES.index(str(self))
 73            new_tone_index = tone_index - other.semitone_number
 74
 75            new_tone_name = ALLOWED_TONE_NAMES[new_tone_index % len(ALLOWED_TONE_NAMES)]
 76
 77            return Tone(new_tone_name)
 78        
 79        raise TypeError("Incompatible types. Tone object should be subtracted only by Tone object.")
 80
 81
 82class Interval:
 83    def __init__(self, semitone_number):
 84        self.__semitone_number = semitone_number
 85
 86    def __str__(self):
 87        return SEMITONE_REPRESENTATION[self.__semitone_number % len(SEMITONE_REPRESENTATION)]
 88    
 89    def __add__(self, other):
 90        if isinstance(other, Interval):
 91            new_semitone = self.semitone_number + other.semitone_number
 92
 93            return Interval(new_semitone)
 94
 95        raise TypeError("Invalid operation")
 96    
 97    def __sub__(self, other):
 98        raise TypeError("Invalid operation")
 99    
100    def __neg__(self):
101        return Interval(-self.semitone_number)
102    
103    @property
104    def semitone_number(self):
105        return self.__semitone_number
106
107
108class Chord:
109    def __init__(self, main_tone, *args):
110        self.__main_tone = main_tone
111        others_tones = [str(tone) for tone in set([tone for tone in args if tone != main_tone])]
112
113        if len(others_tones) == 0:
114            raise TypeError("Cannot have a chord made of only 1 unique tone")
115        
116        # fix order
117        fixed_order_tones = []
118
119        current_tone_index = ALLOWED_TONE_NAMES.index(str(main_tone))
120        
121        while True:
122            current_tone_index += 1
123            current_tone = ALLOWED_TONE_NAMES[current_tone_index % len(ALLOWED_TONE_NAMES)]
124
125            if current_tone == str(main_tone):
126                break
127
128            if current_tone in others_tones:
129                fixed_order_tones.append(Tone(current_tone))
130
131        self.__other_tones = fixed_order_tones
132
133    def __str__(self):
134        joined_other_tones = "-".join(map(str, self.__other_tones))
135
136        return f"{str(self.__main_tone)}-{joined_other_tones}"
137    
138    def __add__(self, other):
139        if isinstance(other, Tone):
140            return Chord(self.__main_tone, *self.__other_tones, other)
141        elif isinstance(other, Chord):
142            return Chord(self.__main_tone, *self.__other_tones, other.__main_tone, *other.__other_tones)
143        
144        raise TypeError("Incompatible types. Chord object should be added up only with Tone object.")
145    
146    def __sub__(self, other):
147        if not isinstance(other, Tone):
148            raise TypeError("Incompatible types. Chord object should be subtracted only by Tone object.")
149        
150        if other not in self.__other_tones:
151            raise TypeError(f"Cannot remove tone {other} from chord {self}")
152
153        return Chord(self.__main_tone, *[tone for tone in self.__other_tones if tone != other])
154
155    def __check_majority(self, majority="minor"):
156        main_tone_index = ALLOWED_TONE_NAMES.index(str(self.__main_tone))
157
158        for tone in self.__other_tones:
159            tone_index = ALLOWED_TONE_NAMES.index(str(tone))
160            diff = abs(main_tone_index - tone_index)
161
162            if SEMITONE_REPRESENTATION[diff] == f"{majority} 3rd":
163                return True
164        
165        return False
166
167    def is_minor(self):
168        return self.__check_majority("minor")
169    
170    def is_major(self):
171        return self.__check_majority("major")
172    
173    def is_power_chord(self):
174        return not self.is_minor() and not self.is_major()
175    
176    def transposed(self, interval):
177        if not isinstance(interval, Interval):
178            raise TypeError("Function expects Interval object to work properly but other object type was given.")
179        
180        new_main_tone = self.__main_tone + interval
181        new_other_tones = [tone + interval for tone in self.__other_tones]
182
183        return Chord(new_main_tone, *new_other_tones)

...................................F.
======================================================================
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.001s

FAILED (failures=1)

Дискусия
История

f1f1
2ALLOWED_TONE_NAMES = [2ALLOWED_TONE_NAMES = [
3    "A", "A#",3    "A", "A#",
4    "B",4    "B",
5    "C", "C#",5    "C", "C#",
6    "D", "D#",6    "D", "D#",
7    "E",7    "E",
8    "F", "F#",8    "F", "F#",
9    "G", "G#",9    "G", "G#",
10]10]
1111
12SEMITONE_REPRESENTATION = [12SEMITONE_REPRESENTATION = [
13    "unison",13    "unison",
14    "minor 2nd",14    "minor 2nd",
15    "major 2nd",15    "major 2nd",
16    "minor 3rd",16    "minor 3rd",
17    "major 3rd",17    "major 3rd",
18    "perfect 4th",18    "perfect 4th",
19    "diminished 5th",19    "diminished 5th",
20    "perfect 5th",20    "perfect 5th",
21    "minor 6th",21    "minor 6th",
22    "major 6th",22    "major 6th",
23    "minor 7th",23    "minor 7th",
24    "major 7th",24    "major 7th",
25]25]
2626
2727
28class Tone:28class Tone:
29    def __init__(self, name):29    def __init__(self, name):
30        if name not in ALLOWED_TONE_NAMES:30        if name not in ALLOWED_TONE_NAMES:
31            raise ValueError("Name should be a valid tone.")31            raise ValueError("Name should be a valid tone.")
3232
33        self.__name = name33        self.__name = name
3434
35    def __str__(self):35    def __str__(self):
36        return self.__name36        return self.__name
37    37    
38    def __eq__(self, other):38    def __eq__(self, other):
39        if not isinstance(other, Tone):39        if not isinstance(other, Tone):
40            raise TypeError("Incompatible types. Tone object should be compared only to Tone object.")40            raise TypeError("Incompatible types. Tone object should be compared only to Tone object.")
41        41        
42        return str(self) == str(other)42        return str(self) == str(other)
4343
44    def __ne__(self, other):44    def __ne__(self, other):
45        return not self.__eq__(other)45        return not self.__eq__(other)
46    46    
47    def __hash__(self):47    def __hash__(self):
48        return hash(self.__name)48        return hash(self.__name)
49    49    
50    def __add__(self, other):50    def __add__(self, other):
51        if isinstance(other, Tone):51        if isinstance(other, Tone):
52            return Chord(self, other)52            return Chord(self, other)
53        elif isinstance(other, Interval):53        elif isinstance(other, Interval):
54            tone_index = ALLOWED_TONE_NAMES.index(str(self))54            tone_index = ALLOWED_TONE_NAMES.index(str(self))
55            new_tone_index = tone_index + other.semitone_number55            new_tone_index = tone_index + other.semitone_number
5656
57            new_tone_name = ALLOWED_TONE_NAMES[new_tone_index % len(ALLOWED_TONE_NAMES)]57            new_tone_name = ALLOWED_TONE_NAMES[new_tone_index % len(ALLOWED_TONE_NAMES)]
5858
59            return Tone(new_tone_name)59            return Tone(new_tone_name)
60        60        
61        raise TypeError("Incompatible types. Tone object should be added up only with Tone or Interval objects.")61        raise TypeError("Incompatible types. Tone object should be added up only with Tone or Interval objects.")
62        62        
63    63    
64    def __sub__(self, other):64    def __sub__(self, other):
65        if isinstance(other, Tone):65        if isinstance(other, Tone):
66            tone_index = ALLOWED_TONE_NAMES.index(str(self))66            tone_index = ALLOWED_TONE_NAMES.index(str(self))
67            other_tone_index = ALLOWED_TONE_NAMES.index(str(other))67            other_tone_index = ALLOWED_TONE_NAMES.index(str(other))
68            68            
69            diff = abs(tone_index - other_tone_index)69            diff = abs(tone_index - other_tone_index)
7070
71            return Interval(diff)71            return Interval(diff)
72        elif isinstance(other, Interval):72        elif isinstance(other, Interval):
73            tone_index = ALLOWED_TONE_NAMES.index(str(self))73            tone_index = ALLOWED_TONE_NAMES.index(str(self))
74            new_tone_index = tone_index - other.semitone_number74            new_tone_index = tone_index - other.semitone_number
7575
76            new_tone_name = ALLOWED_TONE_NAMES[new_tone_index % len(ALLOWED_TONE_NAMES)]76            new_tone_name = ALLOWED_TONE_NAMES[new_tone_index % len(ALLOWED_TONE_NAMES)]
7777
78            return Tone(new_tone_name)78            return Tone(new_tone_name)
79        79        
80        raise TypeError("Incompatible types. Tone object should be subtracted only by Tone object.")80        raise TypeError("Incompatible types. Tone object should be subtracted only by Tone object.")
8181
8282
83class Interval:83class Interval:
84    def __init__(self, semitone_number):84    def __init__(self, semitone_number):
85        self.__semitone_number = semitone_number85        self.__semitone_number = semitone_number
8686
87    def __str__(self):87    def __str__(self):
88        return SEMITONE_REPRESENTATION[self.__semitone_number % len(SEMITONE_REPRESENTATION)]88        return SEMITONE_REPRESENTATION[self.__semitone_number % len(SEMITONE_REPRESENTATION)]
89    89    
90    def __add__(self, other):90    def __add__(self, other):
91        if isinstance(other, Interval):91        if isinstance(other, Interval):
92            new_semitone = self.semitone_number + other.semitone_number92            new_semitone = self.semitone_number + other.semitone_number
9393
94            return Interval(new_semitone)94            return Interval(new_semitone)
9595
96        raise TypeError("Invalid operation")96        raise TypeError("Invalid operation")
97    97    
98    def __sub__(self, other):98    def __sub__(self, other):
99        raise TypeError("Invalid operation")99        raise TypeError("Invalid operation")
100    100    
101    def __neg__(self):101    def __neg__(self):
102        return Interval(-self.semitone_number)102        return Interval(-self.semitone_number)
103    103    
104    @property104    @property
105    def semitone_number(self):105    def semitone_number(self):
106        return self.__semitone_number106        return self.__semitone_number
107107
108108
109class Chord:109class Chord:
110    def __init__(self, main_tone, *args):110    def __init__(self, main_tone, *args):
111        self.__main_tone = main_tone111        self.__main_tone = main_tone
112        others_tones = [str(tone) for tone in set([tone for tone in args if tone != main_tone])]112        others_tones = [str(tone) for tone in set([tone for tone in args if tone != main_tone])]
113113
114        if len(others_tones) == 0:114        if len(others_tones) == 0:
115            raise TypeError("Cannot have a chord made of only 1 unique tone")115            raise TypeError("Cannot have a chord made of only 1 unique tone")
116        116        
117        # fix order117        # fix order
118        fixed_order_tones = []118        fixed_order_tones = []
119119
120        current_tone_index = ALLOWED_TONE_NAMES.index(str(main_tone))120        current_tone_index = ALLOWED_TONE_NAMES.index(str(main_tone))
121        121        
n122        while (True):n122        while True:
123            current_tone_index += 1123            current_tone_index += 1
124            current_tone = ALLOWED_TONE_NAMES[current_tone_index % len(ALLOWED_TONE_NAMES)]124            current_tone = ALLOWED_TONE_NAMES[current_tone_index % len(ALLOWED_TONE_NAMES)]
125125
126            if current_tone == str(main_tone):126            if current_tone == str(main_tone):
127                break127                break
128128
129            if current_tone in others_tones:129            if current_tone in others_tones:
130                fixed_order_tones.append(Tone(current_tone))130                fixed_order_tones.append(Tone(current_tone))
131131
132        self.__other_tones = fixed_order_tones132        self.__other_tones = fixed_order_tones
133133
134    def __str__(self):134    def __str__(self):
n135        return str(self.__main_tone) + "-" + "-".join(map(str, self.__other_tones))n135        joined_other_tones = "-".join(map(str, self.__other_tones))
136 
137        return f"{str(self.__main_tone)}-{joined_other_tones}"
136    138    
137    def __add__(self, other):139    def __add__(self, other):
138        if isinstance(other, Tone):140        if isinstance(other, Tone):
139            return Chord(self.__main_tone, *self.__other_tones, other)141            return Chord(self.__main_tone, *self.__other_tones, other)
140        elif isinstance(other, Chord):142        elif isinstance(other, Chord):
141            return Chord(self.__main_tone, *self.__other_tones, other.__main_tone, *other.__other_tones)143            return Chord(self.__main_tone, *self.__other_tones, other.__main_tone, *other.__other_tones)
142        144        
143        raise TypeError("Incompatible types. Chord object should be added up only with Tone object.")145        raise TypeError("Incompatible types. Chord object should be added up only with Tone object.")
144    146    
145    def __sub__(self, other):147    def __sub__(self, other):
146        if not isinstance(other, Tone):148        if not isinstance(other, Tone):
147            raise TypeError("Incompatible types. Chord object should be subtracted only by Tone object.")149            raise TypeError("Incompatible types. Chord object should be subtracted only by Tone object.")
148        150        
149        if other not in self.__other_tones:151        if other not in self.__other_tones:
150            raise TypeError(f"Cannot remove tone {other} from chord {self}")152            raise TypeError(f"Cannot remove tone {other} from chord {self}")
151153
152        return Chord(self.__main_tone, *[tone for tone in self.__other_tones if tone != other])154        return Chord(self.__main_tone, *[tone for tone in self.__other_tones if tone != other])
153155
154    def __check_majority(self, majority="minor"):156    def __check_majority(self, majority="minor"):
155        main_tone_index = ALLOWED_TONE_NAMES.index(str(self.__main_tone))157        main_tone_index = ALLOWED_TONE_NAMES.index(str(self.__main_tone))
156158
157        for tone in self.__other_tones:159        for tone in self.__other_tones:
158            tone_index = ALLOWED_TONE_NAMES.index(str(tone))160            tone_index = ALLOWED_TONE_NAMES.index(str(tone))
159            diff = abs(main_tone_index - tone_index)161            diff = abs(main_tone_index - tone_index)
160162
161            if SEMITONE_REPRESENTATION[diff] == f"{majority} 3rd":163            if SEMITONE_REPRESENTATION[diff] == f"{majority} 3rd":
162                return True164                return True
163        165        
164        return False166        return False
165167
166    def is_minor(self):168    def is_minor(self):
167        return self.__check_majority("minor")169        return self.__check_majority("minor")
168    170    
169    def is_major(self):171    def is_major(self):
170        return self.__check_majority("major")172        return self.__check_majority("major")
171    173    
172    def is_power_chord(self):174    def is_power_chord(self):
173        return not self.is_minor() and not self.is_major()175        return not self.is_minor() and not self.is_major()
174    176    
175    def transposed(self, interval):177    def transposed(self, interval):
176        if not isinstance(interval, Interval):178        if not isinstance(interval, Interval):
177            raise TypeError("Function expects Interval object to work properly but other object type was given.")179            raise TypeError("Function expects Interval object to work properly but other object type was given.")
178        180        
179        new_main_tone = self.__main_tone + interval181        new_main_tone = self.__main_tone + interval
t180        new_other_tones = []t182        new_other_tones = [tone + interval for tone in self.__other_tones]
181 
182        for tone in self.__other_tones:
183            new_other_tones.append(tone + interval)
184183
185        return Chord(new_main_tone, *new_other_tones)184        return Chord(new_main_tone, *new_other_tones)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1f1
n2allowed_tone_names = [n2ALLOWED_TONE_NAMES = [
3    "A", "A#",3    "A", "A#",
4    "B",4    "B",
5    "C", "C#",5    "C", "C#",
6    "D", "D#",6    "D", "D#",
7    "E",7    "E",
8    "F", "F#",8    "F", "F#",
9    "G", "G#",9    "G", "G#",
10]10]
1111
n12semitone_representation = [n12SEMITONE_REPRESENTATION = [
13    "unison",13    "unison",
14    "minor 2nd",14    "minor 2nd",
15    "major 2nd",15    "major 2nd",
16    "minor 3rd",16    "minor 3rd",
17    "major 3rd",17    "major 3rd",
18    "perfect 4th",18    "perfect 4th",
19    "diminished 5th",19    "diminished 5th",
20    "perfect 5th",20    "perfect 5th",
21    "minor 6th",21    "minor 6th",
22    "major 6th",22    "major 6th",
23    "minor 7th",23    "minor 7th",
24    "major 7th",24    "major 7th",
25]25]
2626
2727
28class Tone:28class Tone:
29    def __init__(self, name):29    def __init__(self, name):
n30        if name not in allowed_tone_names:n30        if name not in ALLOWED_TONE_NAMES:
31            raise ValueError("Name should be a valid tone.")31            raise ValueError("Name should be a valid tone.")
3232
33        self.__name = name33        self.__name = name
3434
35    def __str__(self):35    def __str__(self):
36        return self.__name36        return self.__name
37    37    
38    def __eq__(self, other):38    def __eq__(self, other):
39        if not isinstance(other, Tone):39        if not isinstance(other, Tone):
40            raise TypeError("Incompatible types. Tone object should be compared only to Tone object.")40            raise TypeError("Incompatible types. Tone object should be compared only to Tone object.")
41        41        
42        return str(self) == str(other)42        return str(self) == str(other)
4343
44    def __ne__(self, other):44    def __ne__(self, other):
45        return not self.__eq__(other)45        return not self.__eq__(other)
46    46    
47    def __hash__(self):47    def __hash__(self):
48        return hash(self.__name)48        return hash(self.__name)
49    49    
50    def __add__(self, other):50    def __add__(self, other):
51        if isinstance(other, Tone):51        if isinstance(other, Tone):
52            return Chord(self, other)52            return Chord(self, other)
53        elif isinstance(other, Interval):53        elif isinstance(other, Interval):
n54            tone_index = allowed_tone_names.index(str(self))n54            tone_index = ALLOWED_TONE_NAMES.index(str(self))
55            new_tone_index = tone_index + other.get_semitone_number()55            new_tone_index = tone_index + other.semitone_number
5656
n57            new_tone_name = allowed_tone_names[new_tone_index % len(allowed_tone_names)]n57            new_tone_name = ALLOWED_TONE_NAMES[new_tone_index % len(ALLOWED_TONE_NAMES)]
5858
59            return Tone(new_tone_name)59            return Tone(new_tone_name)
60        60        
61        raise TypeError("Incompatible types. Tone object should be added up only with Tone or Interval objects.")61        raise TypeError("Incompatible types. Tone object should be added up only with Tone or Interval objects.")
62        62        
63    63    
64    def __sub__(self, other):64    def __sub__(self, other):
65        if isinstance(other, Tone):65        if isinstance(other, Tone):
n66            tone_index = allowed_tone_names.index(str(self))n66            tone_index = ALLOWED_TONE_NAMES.index(str(self))
67            other_tone_index = allowed_tone_names.index(str(other))67            other_tone_index = ALLOWED_TONE_NAMES.index(str(other))
68            68            
69            diff = abs(tone_index - other_tone_index)69            diff = abs(tone_index - other_tone_index)
7070
71            return Interval(diff)71            return Interval(diff)
72        elif isinstance(other, Interval):72        elif isinstance(other, Interval):
n73            tone_index = allowed_tone_names.index(str(self))n73            tone_index = ALLOWED_TONE_NAMES.index(str(self))
74            new_tone_index = tone_index - other.get_semitone_number()74            new_tone_index = tone_index - other.semitone_number
7575
n76            new_tone_name = allowed_tone_names[new_tone_index % len(allowed_tone_names)]n76            new_tone_name = ALLOWED_TONE_NAMES[new_tone_index % len(ALLOWED_TONE_NAMES)]
7777
78            return Tone(new_tone_name)78            return Tone(new_tone_name)
79        79        
80        raise TypeError("Incompatible types. Tone object should be subtracted only by Tone object.")80        raise TypeError("Incompatible types. Tone object should be subtracted only by Tone object.")
8181
8282
83class Interval:83class Interval:
84    def __init__(self, semitone_number):84    def __init__(self, semitone_number):
85        self.__semitone_number = semitone_number85        self.__semitone_number = semitone_number
8686
87    def __str__(self):87    def __str__(self):
n88        return semitone_representation[self.__semitone_number % len(semitone_representation)]n88        return SEMITONE_REPRESENTATION[self.__semitone_number % len(SEMITONE_REPRESENTATION)]
89    89    
90    def __add__(self, other):90    def __add__(self, other):
91        if isinstance(other, Interval):91        if isinstance(other, Interval):
n92            new_semitone = self.get_semitone_number() + other.get_semitone_number()n92            new_semitone = self.semitone_number + other.semitone_number
9393
94            return Interval(new_semitone)94            return Interval(new_semitone)
9595
96        raise TypeError("Invalid operation")96        raise TypeError("Invalid operation")
97    97    
98    def __sub__(self, other):98    def __sub__(self, other):
99        raise TypeError("Invalid operation")99        raise TypeError("Invalid operation")
100    100    
101    def __neg__(self):101    def __neg__(self):
n102        return Interval(self.get_semitone_number() * -1)n102        return Interval(-self.semitone_number)
103    103    
nn104    @property
104    def get_semitone_number(self):105    def semitone_number(self):
105        return self.__semitone_number106        return self.__semitone_number
106107
107108
108class Chord:109class Chord:
109    def __init__(self, main_tone, *args):110    def __init__(self, main_tone, *args):
110        self.__main_tone = main_tone111        self.__main_tone = main_tone
111        others_tones = [str(tone) for tone in set([tone for tone in args if tone != main_tone])]112        others_tones = [str(tone) for tone in set([tone for tone in args if tone != main_tone])]
112113
113        if len(others_tones) == 0:114        if len(others_tones) == 0:
114            raise TypeError("Cannot have a chord made of only 1 unique tone")115            raise TypeError("Cannot have a chord made of only 1 unique tone")
115        116        
116        # fix order117        # fix order
117        fixed_order_tones = []118        fixed_order_tones = []
118119
n119        current_tone_index = allowed_tone_names.index(str(main_tone))n120        current_tone_index = ALLOWED_TONE_NAMES.index(str(main_tone))
120        121        
121        while (True):122        while (True):
122            current_tone_index += 1123            current_tone_index += 1
n123            current_tone = allowed_tone_names[current_tone_index % len(allowed_tone_names)]n124            current_tone = ALLOWED_TONE_NAMES[current_tone_index % len(ALLOWED_TONE_NAMES)]
124125
125            if current_tone == str(main_tone):126            if current_tone == str(main_tone):
126                break127                break
127128
128            if current_tone in others_tones:129            if current_tone in others_tones:
129                fixed_order_tones.append(Tone(current_tone))130                fixed_order_tones.append(Tone(current_tone))
130131
131        self.__other_tones = fixed_order_tones132        self.__other_tones = fixed_order_tones
132133
133    def __str__(self):134    def __str__(self):
134        return str(self.__main_tone) + "-" + "-".join(map(str, self.__other_tones))135        return str(self.__main_tone) + "-" + "-".join(map(str, self.__other_tones))
135    136    
136    def __add__(self, other):137    def __add__(self, other):
137        if isinstance(other, Tone):138        if isinstance(other, Tone):
138            return Chord(self.__main_tone, *self.__other_tones, other)139            return Chord(self.__main_tone, *self.__other_tones, other)
139        elif isinstance(other, Chord):140        elif isinstance(other, Chord):
140            return Chord(self.__main_tone, *self.__other_tones, other.__main_tone, *other.__other_tones)141            return Chord(self.__main_tone, *self.__other_tones, other.__main_tone, *other.__other_tones)
141        142        
142        raise TypeError("Incompatible types. Chord object should be added up only with Tone object.")143        raise TypeError("Incompatible types. Chord object should be added up only with Tone object.")
143    144    
144    def __sub__(self, other):145    def __sub__(self, other):
145        if not isinstance(other, Tone):146        if not isinstance(other, Tone):
146            raise TypeError("Incompatible types. Chord object should be subtracted only by Tone object.")147            raise TypeError("Incompatible types. Chord object should be subtracted only by Tone object.")
147        148        
148        if other not in self.__other_tones:149        if other not in self.__other_tones:
149            raise TypeError(f"Cannot remove tone {other} from chord {self}")150            raise TypeError(f"Cannot remove tone {other} from chord {self}")
150151
151        return Chord(self.__main_tone, *[tone for tone in self.__other_tones if tone != other])152        return Chord(self.__main_tone, *[tone for tone in self.__other_tones if tone != other])
152153
153    def __check_majority(self, majority="minor"):154    def __check_majority(self, majority="minor"):
n154        main_tone_index = allowed_tone_names.index(str(self.__main_tone))n155        main_tone_index = ALLOWED_TONE_NAMES.index(str(self.__main_tone))
155156
156        for tone in self.__other_tones:157        for tone in self.__other_tones:
n157            tone_index = allowed_tone_names.index(str(tone))n158            tone_index = ALLOWED_TONE_NAMES.index(str(tone))
158            diff = abs(main_tone_index - tone_index)159            diff = abs(main_tone_index - tone_index)
159160
t160            if semitone_representation[diff] == f"{majority} 3rd":t161            if SEMITONE_REPRESENTATION[diff] == f"{majority} 3rd":
161                return True162                return True
162        163        
163        return False164        return False
164165
165    def is_minor(self):166    def is_minor(self):
166        return self.__check_majority("minor")167        return self.__check_majority("minor")
167    168    
168    def is_major(self):169    def is_major(self):
169        return self.__check_majority("major")170        return self.__check_majority("major")
170    171    
171    def is_power_chord(self):172    def is_power_chord(self):
172        return not self.is_minor() and not self.is_major()173        return not self.is_minor() and not self.is_major()
173    174    
174    def transposed(self, interval):175    def transposed(self, interval):
175        if not isinstance(interval, Interval):176        if not isinstance(interval, Interval):
176            raise TypeError("Function expects Interval object to work properly but other object type was given.")177            raise TypeError("Function expects Interval object to work properly but other object type was given.")
177        178        
178        new_main_tone = self.__main_tone + interval179        new_main_tone = self.__main_tone + interval
179        new_other_tones = []180        new_other_tones = []
180181
181        for tone in self.__other_tones:182        for tone in self.__other_tones:
182            new_other_tones.append(tone + interval)183            new_other_tones.append(tone + interval)
183184
184        return Chord(new_main_tone, *new_other_tones)185        return Chord(new_main_tone, *new_other_tones)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op