Домашни > Pitches love the D > Решения > Решението на Жан Георгиев

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

8 точки общо

30 успешни теста
7 неуспешни теста
Код
Скрий всички коментари

  1class Tone:
  2    def __init__(self, name):
  3        self.name = name
  4        self.value = self.get_value()
  5
  6    def get_value(self):
  7        tones_list = ('C', 'C#', 'D', 'D#', 'E',
  8                      'F', 'F#', 'G', 'G#', 'A',
  9                      'A#', 'B', 'C')
 10
 11        for value in range(0, len(tones_list)):
 12            if tones_list[value] == self.name:
 13                return value
 14        raise TypeError('Wrong Tone')
 15
 16    def set_name(self, index):
 17        self.value = index % 12
 18        self.name = ('C', 'C#', 'D', 'D#', 'E',
 19                     'F', 'F#', 'G', 'G#', 'A',
 20                     'A#', 'B', 'C')[self. value]
 21
 22    def __str__(self):
 23        return self.name
 24
 25    def addition(self, other):
 26        if isinstance(other, Tone):
 27            return Chord(self, other)
 28
 29        if isinstance(other, Interval):
 30            result = Tone('C')
 31            result.set_name(self.value + other.value)
 32            return result
 33
 34    def subtraction(self, other):
 35        if isinstance(other, Tone):
 36            return Interval(self.value - other.value)
 37
 38        if isinstance(other, Interval):
 39            result = Tone('C')
 40            result.set_name(self.value - other.value)
 41            return result
 42
 43    __add__ = addition
 44
 45    __sub__ = subtraction
 46
 47
 48class Interval:
 49    def __init__(self, value=0, name='unison'):
 50        if value != 0:
 51            self.value = value % 12
 52            self.name = self.set_name()
 53        else:
 54            self.value = value % 12
 55            self.name = name
 56
 57    def set_name(self):
 58        return ('unison', 'minor 2nd', 'major 2nd',
 59                'minor 3rd', 'major 3rd', 'perfect 4th',
 60                'diminished 5th', 'perfect 5th', 'minor 6th',
 61                'major 6th', 'minor 7th', 'major 7th')[self.value]
 62
 63    def __str__(self):
 64        return self.name
 65
 66    def addition(self, other):
 67        if isinstance(other, Tone):
 68            raise TypeError('Invalid operation')
 69
 70        if isinstance(other, Interval):
 71            return Interval(self.value + other.value)
 72
 73    def subtraction(self, other):
 74        if isinstance(other, Tone):
 75            raise TypeError('Invalid operation')
 76
 77    __add__ = addition
 78
 79    __sub__ = subtraction
 80
 81
 82class Chord:
 83    def __init__(self, *args):
 84        self.unique_tones = []
 85        self.set_unique_tones(*args)
 86        self.is_valid()
 87        self.root = self.unique_tones[0]
 88        self.names = []
 89        self.sort_tones()
 90
 91    def set_unique_tones(self, *args):
 92        names = []
 93        for tones in args:
 94            if not isinstance(tones, Tone):
 95                raise TypeError('Wrong args in Chord')
 96            else:
 97                if tones.name not in names:
 98                    names.append(tones.name)
 99                    self.unique_tones.append(tones)
100
101    def sort_tones(self):
102        tones_values = []
103        for tones in self.unique_tones:
104            if isinstance(tones, Tone) and isinstance(self.root, Tone):
105                if tones.value < self.root.value:
106                    tones_values.append(tones.value + 12)
107                else:
108                    tones_values.append(tones.value)
109
110        tones_values.sort()
111        self.unique_tones.clear()
112
113        for values in tones_values:
114            temp = Tone('C')
115            temp.set_name(values)
116            self.unique_tones.append(temp)
117            self.names.append(temp.name)
118
119    def is_valid(self):
120
121        if len(self.unique_tones) <= 1:
122            raise TypeError('Cannot have a chord made of only 1 unique tone')
123
124    def __str__(self):
125        return '-'.join(f'{tone}' for tone in self.unique_tones)
126
127    def addition(self, other):
128        if isinstance(other, Tone):
129            if other.name not in self.names:
130                self.unique_tones.append(other)
131                self.set_unique_tones()
132                self.is_valid()
133                self.sort_tones()
134            return self
135
136        if isinstance(other, Chord):
137            self.unique_tones = list(set(self.unique_tones + other.unique_tones))
138            self.set_unique_tones()
139            self.is_valid()
140            self.sort_tones()
141            return self
142
143    def subtraction(self, other):
144        if isinstance(other, Tone):
145            for tone in range(0, len(self.unique_tones)):
146                if self.names[tone] == other.name:
147                    self.names.remove(self.names[tone])
148                    self.unique_tones.remove(self.unique_tones[tone])
149                    self.set_unique_tones()
150                    self.is_valid()
151                    self.sort_tones()
152                    return self
153
154            raise TypeError('Cannot remove tone {} from chord {}'.format(other, self))
155
156    __add__ = addition
157
158    __sub__ = subtraction
159
160    def is_minor(self):
161        if isinstance(self.unique_tones[0], Tone):
162            root_value = self.unique_tones[0].value
163
164        for values in range(1, len(self.unique_tones)):
165            if isinstance(self.unique_tones[values], Tone):
166                if (self.unique_tones[values].value + root_value) % 12 == 3:
167                    return True
168        return False
169
170    def is_major(self):
171        if isinstance(self.unique_tones[0], Tone):
172            root_value = self.unique_tones[0].value
173
174        for values in range(1, len(self.unique_tones)):
175            if isinstance(self.unique_tones[values], Tone):
176                if (self.unique_tones[values].value + root_value) % 12 == 4:
177                    return True
178        return False
179
180    def is_power_chord(self):
181        return not self.is_minor() and not self.is_major()
182
183    def transposed(self, interval):
184        if isinstance(interval, Interval):
185            temp1 = Tone(self.names[0]) + interval
186            temp2 = Tone(self.names[1]) + interval
187            result_chord = Chord(temp1, temp2)
188
189            for x in range(2, len(self.names)):
190                result_chord.unique_tones.append(Tone(self.names[x]) + interval)
191
192            result_chord.set_unique_tones()
193            result_chord.is_valid()
194            result_chord.sort_tones()
195
196        return result_chord

....FFF.EE.E....F....................
======================================================================
ERROR: test_transposed_negative (test.TestBasicChordFunctionality.test_transposed_negative)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 136, in test_transposed_negative
result_chord = e_minor_chord.transposed(-Interval(2))
^^^^^^^^^^^^
TypeError: bad operand type for unary -: 'Interval'

======================================================================
ERROR: test_transposed_negative_overflow (test.TestBasicChordFunctionality.test_transposed_negative_overflow)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 150, in test_transposed_negative_overflow
result_chord = e_minor_chord.transposed(-Interval(8))
^^^^^^^^^^^^
TypeError: bad operand type for unary -: 'Interval'

======================================================================
ERROR: test_interval_negative (test.TestBasicIntervalFunctionality.test_interval_negative)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 50, in test_interval_negative
minor_2nd = -major_7th
^^^^^^^^^^
TypeError: bad operand type for unary -: 'Interval'

======================================================================
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_add_chords_repeating_notes (test.TestOperations.test_add_chords_repeating_notes)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 305, in test_add_chords_repeating_notes
self.assertEqual(str(result_chord), "C-G")
AssertionError: 'C-C-G-G' != 'C-G'
- C-C-G-G
+ C-G

----------------------------------------------------------------------
Ran 37 tests in 0.002s

FAILED (failures=4, errors=3)

Дискусия
История
Това решение има само една версия.