Домашни > Pitches love the D > Решения > Решението на Силвана Николова

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

9 точки общо

33 успешни теста
4 неуспешни теста
Код

  1import copy
  2
  3CHROMATIC_SCALE = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
  4TONES_COUNT = 12
  5
  6class Tone:
  7    def __init__(self, name):
  8        self._name = name
  9    
 10    def __str__(self):
 11        return self._name
 12
 13    def __eq__(self, other):
 14        return str(self) == str(other)
 15
 16    def __hash__(self):
 17        return hash(self._name)
 18    
 19    def __add__(self, other):
 20        if isinstance(other, Tone):
 21            return Chord(self, other)
 22        elif isinstance(other, Interval):
 23            self_index = CHROMATIC_SCALE.index(str(self))
 24            other_index = other.interval_index
 25            return Tone(CHROMATIC_SCALE[(self_index + other_index) % TONES_COUNT])
 26
 27    
 28    def __sub__(self, other):
 29        if isinstance(other, Tone):
 30            return Interval(CHROMATIC_SCALE.index(str(self)) - CHROMATIC_SCALE.index(str(other)))
 31        elif isinstance(other, Interval):
 32            self_index = CHROMATIC_SCALE.index(str(self))
 33            other_index = other.interval_index
 34            return Tone(CHROMATIC_SCALE[TONES_COUNT - (abs(other_index - self_index) % TONES_COUNT)])
 35    
 36class Interval:
 37    __NUMBER_OF_SEMITONES_TO_STRING = ['unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th',
 38                                        'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th']
 39
 40    @property
 41    def interval_index(self):
 42        return self._number_of_semitones
 43    
 44    def __init__(self, number_of_semitones):
 45        self._number_of_semitones = number_of_semitones % TONES_COUNT
 46    
 47    def __str__(self):
 48        return self.__NUMBER_OF_SEMITONES_TO_STRING[abs(self._number_of_semitones)]
 49    
 50    def __neg__(self):
 51        return Interval(-self._number_of_semitones)
 52
 53    def __add__(self, other):
 54        if isinstance(other, Tone):
 55            raise TypeError("Invalid operation")
 56        return Interval(self._number_of_semitones + other._number_of_semitones)
 57    
 58    def __sub__(self, other):
 59        if isinstance(other, Tone):
 60            raise TypeError("Invalid operation")
 61
 62class Chord:
 63    def __init__(self, *args):
 64        seen = set()
 65        self._tones = [tone for tone in args if not (tone in seen or seen.add(tone))]
 66        
 67        if len(self._tones) <= 1:
 68            raise TypeError("Cannot have a chord made of only 1 unique tone")
 69
 70        self._main_tone = self[0]
 71        self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))
 72
 73    def add_tone(self, tone):
 74        if tone not in self._tones:
 75            self._tones.append(tone)
 76    
 77    def remove_tone(self, tone):
 78        if tone not in self._tones:
 79            raise TypeError(f"Cannot remove tone {str(tone)} from chord {str(self)}")
 80        
 81        if tone == self._main_tone:
 82            self._main_tone = self[1]
 83            self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))
 84        self._tones = list(filter(lambda t: str(t) != str(tone), self._tones))
 85
 86    def __get_tone_index(self, tone):
 87        return CHROMATIC_SCALE.index(str(tone))
 88
 89    def __str__(self):
 90        return '-'.join(list(filter(lambda tone: str(tone) in self._tones, CHROMATIC_SCALE[self._main_tone_index:] + CHROMATIC_SCALE[:self._main_tone_index])))
 91    
 92    def __add__(self, other):
 93        if isinstance(other, Tone):
 94            new_chord = copy.deepcopy(self)
 95            new_chord.add_tone(other)
 96            return new_chord
 97        elif isinstance(other, Chord):
 98            new_chord = copy.deepcopy(self)
 99
100            for tone in other._tones:
101                if tone not in new_chord._tones:
102                    new_chord._tones.append(tone)
103
104            return new_chord
105
106    def __sub__(self, other):
107        if isinstance(other, Tone):
108            new_chord = copy.deepcopy(self)
109            new_chord.remove_tone(other)
110
111            if len(new_chord._tones) < 2:
112                raise TypeError("Cannot have a chord made of only 1 unique tone")
113            return new_chord
114
115    def __getitem__(self, index):
116        return self._tones[index]
117    
118    def __setitem__(self, index, value):
119        self._tones[index] = value
120    
121    def is_minor(self):
122        for tone in self[1:]:
123            curr_tone_idx = self.__get_tone_index(tone)
124            if(abs(self._main_tone_index - curr_tone_idx) == 3):
125                return True
126        
127        return False
128    
129    def is_major(self):
130        for tone in self[1:]:
131            curr_tone_idx = self.__get_tone_index(tone)
132            if(abs(self._main_tone_index - curr_tone_idx) == 4):
133                return True
134        
135        return False
136    
137    def is_power_chord(self):
138        return not (self.is_major() or self.is_minor())
139        
140    def transposed(self, interval):
141        step = interval.interval_index
142        new_chord = copy.deepcopy(self)
143        new_chord._tones.clear()
144
145        for tone in self._tones:
146            tone_index = self.__get_tone_index(tone)
147            new_tone_index = (tone_index + step) % TONES_COUNT
148            if tone == self._main_tone:
149                new_chord._main_tone = Tone(CHROMATIC_SCALE[new_tone_index])
150                new_chord._main_tone_index = new_tone_index
151            new_chord._tones.append(Tone(CHROMATIC_SCALE[new_tone_index]))
152        
153        return new_chord

....FFF......................F.......
======================================================================
FAIL: test_is_major (test.TestBasicChordFunctionality.test_is_major)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 107, in test_is_major
self.assertTrue(a_major_chord.is_major())
AssertionError: False is not true

======================================================================
FAIL: test_is_minor (test.TestBasicChordFunctionality.test_is_minor)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 90, in test_is_minor
self.assertTrue(a_minor_chord.is_minor())
AssertionError: False is not true

======================================================================
FAIL: test_is_power_chord (test.TestBasicChordFunctionality.test_is_power_chord)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 116, in test_is_power_chord
self.assertFalse(a_minor_chord.is_power_chord())
AssertionError: True is not false

======================================================================
FAIL: test_subtract_interval_from_tone_same_tone (test.TestOperations.test_subtract_interval_from_tone_same_tone)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 223, in test_subtract_interval_from_tone_same_tone
self.assertEqual(str(still_g), "G")
AssertionError: 'F' != 'G'
- F
+ G

----------------------------------------------------------------------
Ran 37 tests in 0.003s

FAILED (failures=4)

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

f1import copyf1import copy
22
3CHROMATIC_SCALE = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']3CHROMATIC_SCALE = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
4TONES_COUNT = 124TONES_COUNT = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self._name = name8        self._name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return self._name11        return self._name
1212
13    def __eq__(self, other):13    def __eq__(self, other):
14        return str(self) == str(other)14        return str(self) == str(other)
1515
16    def __hash__(self):16    def __hash__(self):
17        return hash(self._name)17        return hash(self._name)
18    18    
19    def __add__(self, other):19    def __add__(self, other):
20        if isinstance(other, Tone):20        if isinstance(other, Tone):
21            return Chord(self, other)21            return Chord(self, other)
22        elif isinstance(other, Interval):22        elif isinstance(other, Interval):
23            self_index = CHROMATIC_SCALE.index(str(self))23            self_index = CHROMATIC_SCALE.index(str(self))
24            other_index = other.interval_index24            other_index = other.interval_index
25            return Tone(CHROMATIC_SCALE[(self_index + other_index) % TONES_COUNT])25            return Tone(CHROMATIC_SCALE[(self_index + other_index) % TONES_COUNT])
2626
27    27    
28    def __sub__(self, other):28    def __sub__(self, other):
29        if isinstance(other, Tone):29        if isinstance(other, Tone):
30            return Interval(CHROMATIC_SCALE.index(str(self)) - CHROMATIC_SCALE.index(str(other)))30            return Interval(CHROMATIC_SCALE.index(str(self)) - CHROMATIC_SCALE.index(str(other)))
31        elif isinstance(other, Interval):31        elif isinstance(other, Interval):
32            self_index = CHROMATIC_SCALE.index(str(self))32            self_index = CHROMATIC_SCALE.index(str(self))
33            other_index = other.interval_index33            other_index = other.interval_index
34            return Tone(CHROMATIC_SCALE[TONES_COUNT - (abs(other_index - self_index) % TONES_COUNT)])34            return Tone(CHROMATIC_SCALE[TONES_COUNT - (abs(other_index - self_index) % TONES_COUNT)])
35    35    
36class Interval:36class Interval:
37    __NUMBER_OF_SEMITONES_TO_STRING = ['unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th',37    __NUMBER_OF_SEMITONES_TO_STRING = ['unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th',
38                                        'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th']38                                        'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th']
3939
40    @property40    @property
41    def interval_index(self):41    def interval_index(self):
42        return self._number_of_semitones42        return self._number_of_semitones
43    43    
44    def __init__(self, number_of_semitones):44    def __init__(self, number_of_semitones):
45        self._number_of_semitones = number_of_semitones % TONES_COUNT45        self._number_of_semitones = number_of_semitones % TONES_COUNT
46    46    
47    def __str__(self):47    def __str__(self):
48        return self.__NUMBER_OF_SEMITONES_TO_STRING[abs(self._number_of_semitones)]48        return self.__NUMBER_OF_SEMITONES_TO_STRING[abs(self._number_of_semitones)]
49    49    
50    def __neg__(self):50    def __neg__(self):
51        return Interval(-self._number_of_semitones)51        return Interval(-self._number_of_semitones)
5252
53    def __add__(self, other):53    def __add__(self, other):
54        if isinstance(other, Tone):54        if isinstance(other, Tone):
55            raise TypeError("Invalid operation")55            raise TypeError("Invalid operation")
56        return Interval(self._number_of_semitones + other._number_of_semitones)56        return Interval(self._number_of_semitones + other._number_of_semitones)
57    57    
58    def __sub__(self, other):58    def __sub__(self, other):
59        if isinstance(other, Tone):59        if isinstance(other, Tone):
60            raise TypeError("Invalid operation")60            raise TypeError("Invalid operation")
6161
62class Chord:62class Chord:
63    def __init__(self, *args):63    def __init__(self, *args):
64        seen = set()64        seen = set()
65        self._tones = [tone for tone in args if not (tone in seen or seen.add(tone))]65        self._tones = [tone for tone in args if not (tone in seen or seen.add(tone))]
66        66        
67        if len(self._tones) <= 1:67        if len(self._tones) <= 1:
68            raise TypeError("Cannot have a chord made of only 1 unique tone")68            raise TypeError("Cannot have a chord made of only 1 unique tone")
6969
70        self._main_tone = self[0]70        self._main_tone = self[0]
71        self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))71        self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))
7272
73    def add_tone(self, tone):73    def add_tone(self, tone):
74        if tone not in self._tones:74        if tone not in self._tones:
75            self._tones.append(tone)75            self._tones.append(tone)
76    76    
77    def remove_tone(self, tone):77    def remove_tone(self, tone):
78        if tone not in self._tones:78        if tone not in self._tones:
79            raise TypeError(f"Cannot remove tone {str(tone)} from chord {str(self)}")79            raise TypeError(f"Cannot remove tone {str(tone)} from chord {str(self)}")
80        80        
81        if tone == self._main_tone:81        if tone == self._main_tone:
82            self._main_tone = self[1]82            self._main_tone = self[1]
83            self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))83            self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))
84        self._tones = list(filter(lambda t: str(t) != str(tone), self._tones))84        self._tones = list(filter(lambda t: str(t) != str(tone), self._tones))
8585
86    def __get_tone_index(self, tone):86    def __get_tone_index(self, tone):
87        return CHROMATIC_SCALE.index(str(tone))87        return CHROMATIC_SCALE.index(str(tone))
8888
89    def __str__(self):89    def __str__(self):
90        return '-'.join(list(filter(lambda tone: str(tone) in self._tones, CHROMATIC_SCALE[self._main_tone_index:] + CHROMATIC_SCALE[:self._main_tone_index])))90        return '-'.join(list(filter(lambda tone: str(tone) in self._tones, CHROMATIC_SCALE[self._main_tone_index:] + CHROMATIC_SCALE[:self._main_tone_index])))
91    91    
92    def __add__(self, other):92    def __add__(self, other):
93        if isinstance(other, Tone):93        if isinstance(other, Tone):
94            new_chord = copy.deepcopy(self)94            new_chord = copy.deepcopy(self)
95            new_chord.add_tone(other)95            new_chord.add_tone(other)
96            return new_chord96            return new_chord
97        elif isinstance(other, Chord):97        elif isinstance(other, Chord):
98            new_chord = copy.deepcopy(self)98            new_chord = copy.deepcopy(self)
9999
100            for tone in other._tones:100            for tone in other._tones:
101                if tone not in new_chord._tones:101                if tone not in new_chord._tones:
102                    new_chord._tones.append(tone)102                    new_chord._tones.append(tone)
103103
104            return new_chord104            return new_chord
105105
106    def __sub__(self, other):106    def __sub__(self, other):
107        if isinstance(other, Tone):107        if isinstance(other, Tone):
108            new_chord = copy.deepcopy(self)108            new_chord = copy.deepcopy(self)
109            new_chord.remove_tone(other)109            new_chord.remove_tone(other)
110110
111            if len(new_chord._tones) < 2:111            if len(new_chord._tones) < 2:
112                raise TypeError("Cannot have a chord made of only 1 unique tone")112                raise TypeError("Cannot have a chord made of only 1 unique tone")
113            return new_chord113            return new_chord
114114
115    def __getitem__(self, index):115    def __getitem__(self, index):
116        return self._tones[index]116        return self._tones[index]
117    117    
118    def __setitem__(self, index, value):118    def __setitem__(self, index, value):
119        self._tones[index] = value119        self._tones[index] = value
120    120    
121    def is_minor(self):121    def is_minor(self):
n122        for tone in self._tones[1:]:n122        for tone in self[1:]:
123            curr_tone_idx = self.__get_tone_index(tone)123            curr_tone_idx = self.__get_tone_index(tone)
124            if(abs(self._main_tone_index - curr_tone_idx) == 3):124            if(abs(self._main_tone_index - curr_tone_idx) == 3):
125                return True125                return True
126        126        
127        return False127        return False
128    128    
129    def is_major(self):129    def is_major(self):
t130        for tone in self._tones[1:]:t130        for tone in self[1:]:
131            curr_tone_idx = self.__get_tone_index(tone)131            curr_tone_idx = self.__get_tone_index(tone)
132            if(abs(self._main_tone_index - curr_tone_idx) == 4):132            if(abs(self._main_tone_index - curr_tone_idx) == 4):
133                return True133                return True
134        134        
135        return False135        return False
136    136    
137    def is_power_chord(self):137    def is_power_chord(self):
138        return not (self.is_major() or self.is_minor())138        return not (self.is_major() or self.is_minor())
139        139        
140    def transposed(self, interval):140    def transposed(self, interval):
141        step = interval.interval_index141        step = interval.interval_index
142        new_chord = copy.deepcopy(self)142        new_chord = copy.deepcopy(self)
143        new_chord._tones.clear()143        new_chord._tones.clear()
144144
145        for tone in self._tones:145        for tone in self._tones:
146            tone_index = self.__get_tone_index(tone)146            tone_index = self.__get_tone_index(tone)
147            new_tone_index = (tone_index + step) % TONES_COUNT147            new_tone_index = (tone_index + step) % TONES_COUNT
148            if tone == self._main_tone:148            if tone == self._main_tone:
149                new_chord._main_tone = Tone(CHROMATIC_SCALE[new_tone_index])149                new_chord._main_tone = Tone(CHROMATIC_SCALE[new_tone_index])
150                new_chord._main_tone_index = new_tone_index150                new_chord._main_tone_index = new_tone_index
151            new_chord._tones.append(Tone(CHROMATIC_SCALE[new_tone_index]))151            new_chord._tones.append(Tone(CHROMATIC_SCALE[new_tone_index]))
152        152        
153        return new_chord153        return new_chord
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import copyf1import copy
22
3CHROMATIC_SCALE = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']3CHROMATIC_SCALE = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
4TONES_COUNT = 124TONES_COUNT = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self._name = name8        self._name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return self._name11        return self._name
1212
13    def __eq__(self, other):13    def __eq__(self, other):
14        return str(self) == str(other)14        return str(self) == str(other)
1515
16    def __hash__(self):16    def __hash__(self):
17        return hash(self._name)17        return hash(self._name)
18    18    
19    def __add__(self, other):19    def __add__(self, other):
20        if isinstance(other, Tone):20        if isinstance(other, Tone):
21            return Chord(self, other)21            return Chord(self, other)
22        elif isinstance(other, Interval):22        elif isinstance(other, Interval):
23            self_index = CHROMATIC_SCALE.index(str(self))23            self_index = CHROMATIC_SCALE.index(str(self))
n24            other_index = other.get_interval_indexn24            other_index = other.interval_index
25            return Tone(CHROMATIC_SCALE[(self_index + other_index) % TONES_COUNT])25            return Tone(CHROMATIC_SCALE[(self_index + other_index) % TONES_COUNT])
2626
27    27    
28    def __sub__(self, other):28    def __sub__(self, other):
29        if isinstance(other, Tone):29        if isinstance(other, Tone):
30            return Interval(CHROMATIC_SCALE.index(str(self)) - CHROMATIC_SCALE.index(str(other)))30            return Interval(CHROMATIC_SCALE.index(str(self)) - CHROMATIC_SCALE.index(str(other)))
31        elif isinstance(other, Interval):31        elif isinstance(other, Interval):
32            self_index = CHROMATIC_SCALE.index(str(self))32            self_index = CHROMATIC_SCALE.index(str(self))
n33            other_index = other.get_interval_indexn33            other_index = other.interval_index
34            return Tone(CHROMATIC_SCALE[TONES_COUNT - (abs(other_index - self_index) % TONES_COUNT)])34            return Tone(CHROMATIC_SCALE[TONES_COUNT - (abs(other_index - self_index) % TONES_COUNT)])
n35 n
36 
37    35    
38class Interval:36class Interval:
n39    __number_of_semitones_to_string = {0: 'unison', 1: 'minor 2nd', 2: 'major 2nd', 3: 'minor 3rd', 4: 'major 3rd', 5: 'perfect 4th',n37    __NUMBER_OF_SEMITONES_TO_STRING = ['unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th',
40                            6: 'diminished 5th', 7: 'perfect 5th', 8: 'minor 6th', 9: 'major 6th', 10: 'minor 7th', 11: 'major 7th'}38                                        'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th']
4139
42    @property40    @property
n43    def get_interval_index(self):n41    def interval_index(self):
44        return self._number_of_semitones42        return self._number_of_semitones
45    43    
46    def __init__(self, number_of_semitones):44    def __init__(self, number_of_semitones):
47        self._number_of_semitones = number_of_semitones % TONES_COUNT45        self._number_of_semitones = number_of_semitones % TONES_COUNT
48    46    
49    def __str__(self):47    def __str__(self):
n50        return self.__number_of_semitones_to_string[abs(self._number_of_semitones)]n48        return self.__NUMBER_OF_SEMITONES_TO_STRING[abs(self._number_of_semitones)]
51    49    
52    def __neg__(self):50    def __neg__(self):
53        return Interval(-self._number_of_semitones)51        return Interval(-self._number_of_semitones)
5452
55    def __add__(self, other):53    def __add__(self, other):
56        if isinstance(other, Tone):54        if isinstance(other, Tone):
57            raise TypeError("Invalid operation")55            raise TypeError("Invalid operation")
n58        else:n
59            return Interval(self._number_of_semitones + other._number_of_semitones)56        return Interval(self._number_of_semitones + other._number_of_semitones)
60    57    
61    def __sub__(self, other):58    def __sub__(self, other):
62        if isinstance(other, Tone):59        if isinstance(other, Tone):
63            raise TypeError("Invalid operation")60            raise TypeError("Invalid operation")
6461
65class Chord:62class Chord:
66    def __init__(self, *args):63    def __init__(self, *args):
n67        self._tones = []n
68        seen = set()64        seen = set()
69        self._tones = [tone for tone in args if not (tone in seen or seen.add(tone))]65        self._tones = [tone for tone in args if not (tone in seen or seen.add(tone))]
70        66        
71        if len(self._tones) <= 1:67        if len(self._tones) <= 1:
72            raise TypeError("Cannot have a chord made of only 1 unique tone")68            raise TypeError("Cannot have a chord made of only 1 unique tone")
7369
74        self._main_tone = self[0]70        self._main_tone = self[0]
75        self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))71        self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))
7672
n77    def __add_tone(self, tone):n73    def add_tone(self, tone):
78        if tone not in self._tones:74        if tone not in self._tones:
79            self._tones.append(tone)75            self._tones.append(tone)
80    76    
n81    def __remove_tone(self, tone):n77    def remove_tone(self, tone):
82        if tone not in self._tones:78        if tone not in self._tones:
83            raise TypeError(f"Cannot remove tone {str(tone)} from chord {str(self)}")79            raise TypeError(f"Cannot remove tone {str(tone)} from chord {str(self)}")
84        80        
85        if tone == self._main_tone:81        if tone == self._main_tone:
86            self._main_tone = self[1]82            self._main_tone = self[1]
n87            #print(self._main_tone)n
88            self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))83            self._main_tone_index = CHROMATIC_SCALE.index(str(self._main_tone))
89        self._tones = list(filter(lambda t: str(t) != str(tone), self._tones))84        self._tones = list(filter(lambda t: str(t) != str(tone), self._tones))
9085
91    def __get_tone_index(self, tone):86    def __get_tone_index(self, tone):
92        return CHROMATIC_SCALE.index(str(tone))87        return CHROMATIC_SCALE.index(str(tone))
9388
94    def __str__(self):89    def __str__(self):
n95        return '-'.join(list(filter(lambda tone: str(tone) in list(map(str, self._tones)), CHROMATIC_SCALE[self._main_tone_index:])) + n90        return '-'.join(list(filter(lambda tone: str(tone) in self._tones, CHROMATIC_SCALE[self._main_tone_index:] + CHROMATIC_SCALE[:self._main_tone_index])))
96                        list(filter(lambda tone: str(tone) in list(map(str, self._tones)), CHROMATIC_SCALE[:self._main_tone_index])))91    
97 
98    def __add__(self, other):92    def __add__(self, other):
99        if isinstance(other, Tone):93        if isinstance(other, Tone):
100            new_chord = copy.deepcopy(self)94            new_chord = copy.deepcopy(self)
n101            new_chord.__add_tone(other)n95            new_chord.add_tone(other)
102            return new_chord96            return new_chord
103        elif isinstance(other, Chord):97        elif isinstance(other, Chord):
104            new_chord = copy.deepcopy(self)98            new_chord = copy.deepcopy(self)
10599
106            for tone in other._tones:100            for tone in other._tones:
107                if tone not in new_chord._tones:101                if tone not in new_chord._tones:
108                    new_chord._tones.append(tone)102                    new_chord._tones.append(tone)
109103
110            return new_chord104            return new_chord
111105
n112 n
113    def __sub__(self, other):106    def __sub__(self, other):
114        if isinstance(other, Tone):107        if isinstance(other, Tone):
nn108            new_chord = copy.deepcopy(self)
109            new_chord.remove_tone(other)
110 
115            if len(self._tones) < 3:111            if len(new_chord._tones) < 2:
116                raise TypeError("Cannot have a chord made of only 1 unique tone")112                raise TypeError("Cannot have a chord made of only 1 unique tone")
n117            n
118            new_chord = copy.deepcopy(self)
119            new_chord.__remove_tone(other)
120            return new_chord113            return new_chord
121114
122    def __getitem__(self, index):115    def __getitem__(self, index):
123        return self._tones[index]116        return self._tones[index]
124    117    
125    def __setitem__(self, index, value):118    def __setitem__(self, index, value):
126        self._tones[index] = value119        self._tones[index] = value
127    120    
n128    #Не знам дали трябва да проверяваме отляво на главния тон получава ли се минор/мажор (закоментирания код в двете функции)n
129    def is_minor(self):121    def is_minor(self):
n130        for tone in self._tones:n122        for tone in self._tones[1:]:
131            if tone == self._main_tone:
132                continue
133            curr_tone_idx = self.__get_tone_index(tone)123            curr_tone_idx = self.__get_tone_index(tone)
134            if(abs(self._main_tone_index - curr_tone_idx) == 3):124            if(abs(self._main_tone_index - curr_tone_idx) == 3):
135                return True125                return True
n136            # if(abs(self._main_tone_index - curr_tone_idx) == 3 or abs(self._main_tone_index - curr_tone_idx) == 8):n
137            #     return True
138        126        
139        return False127        return False
140    128    
141    def is_major(self):129    def is_major(self):
n142        for tone in self._tones:n130        for tone in self._tones[1:]:
143            if tone == self._main_tone:
144                continue
145            curr_tone_idx = self.__get_tone_index(tone)131            curr_tone_idx = self.__get_tone_index(tone)
146            if(abs(self._main_tone_index - curr_tone_idx) == 4):132            if(abs(self._main_tone_index - curr_tone_idx) == 4):
147                return True133                return True
n148            # if(abs(self._main_tone_index - curr_tone_idx) == 4 or abs(self._main_tone_index - curr_tone_idx) == 7):n
149            #     return True
150        134        
151        return False135        return False
152    136    
153    def is_power_chord(self):137    def is_power_chord(self):
n154        return self.is_major() == False and self.is_minor() == Falsen138        return not (self.is_major() or self.is_minor())
155        139        
156    def transposed(self, interval):140    def transposed(self, interval):
n157        step = interval.get_interval_indexn141        step = interval.interval_index
158        new_chord = copy.deepcopy(self)142        new_chord = copy.deepcopy(self)
159        new_chord._tones.clear()143        new_chord._tones.clear()
160144
161        for tone in self._tones:145        for tone in self._tones:
162            tone_index = self.__get_tone_index(tone)146            tone_index = self.__get_tone_index(tone)
163            new_tone_index = (tone_index + step) % TONES_COUNT147            new_tone_index = (tone_index + step) % TONES_COUNT
164            if tone == self._main_tone:148            if tone == self._main_tone:
165                new_chord._main_tone = Tone(CHROMATIC_SCALE[new_tone_index])149                new_chord._main_tone = Tone(CHROMATIC_SCALE[new_tone_index])
166                new_chord._main_tone_index = new_tone_index150                new_chord._main_tone_index = new_tone_index
167            new_chord._tones.append(Tone(CHROMATIC_SCALE[new_tone_index]))151            new_chord._tones.append(Tone(CHROMATIC_SCALE[new_tone_index]))
168        152        
169        return new_chord153        return new_chord
t170            t
171#CHROMATIC_SCALE = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
172 
173# Това условие също ми е неясно - отляво в смисъл като позиция в таблицата (CHROMATIC_SCALE) или отляво, като първи параметър (а + б // а е отляво)
174# Забележка: Искаме това да работи само когато тонът е отляво. Когато тонът е отдясно, го приемаме за недефинирано поведение и искаме да се възбуди TypeError с текст "Invalid operation". Семпло, но няма да ви вгорчаваме живота… Повече.
175 
176#Тук не трябва ли да хвърли грешка първо за това, че chord е с <3 тона? Смисъл, има ли значение коя грешка ще се хвърли първо?
177# Изваждането на несъществуващ тон също е недефинирано поведение, отново искаме TypeError, но този път искаме текстът да бъде "Cannot remove tone <Tone> from chord <Chord>", където <Tone> и <Chord> са съотвените стрингови репрезентации на тона и акорда:
178 
179# c_power_chord = Chord(Tone("C"), Tone("G"))
180# result_chord = c_power_chord - Tone("E")
181# Traceback (most recent call last):
182#   File ...
183#     ...
184# TypeError: Cannot remove tone E from chord C-G
185 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op