Домашни > Pitches love the D > Решения > Решението на Надежда Койкова

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

9 точки общо

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

  1NUM_OF_TONES = 12
  2
  3
  4class Tone:
  5    def __init__(self, tone):
  6        self.valid_tones = ['C', 'C#', 'D', 'D#', 'E', 'F', 
  7                            'F#', 'G', 'G#', 'A', 'A#', 'B']
  8        self.tone = tone
  9        
 10    def __str__(self):
 11        return f'{self.tone}'
 12    
 13    def __add__(self, other):
 14        if isinstance(other, Tone):
 15            return Chord(self, other)
 16        elif isinstance(other, Interval):
 17            tone_index = self.valid_tones.index(str(self))
 18            interval_index = other.valid_intervals.index(str(other))
 19            new_tone = (tone_index + interval_index) % NUM_OF_TONES
 20            return Tone(self.valid_tones[new_tone])
 21    
 22    def __sub__(self, other):
 23        if isinstance(other, Tone):
 24            start_index = self.valid_tones.index(str(other))
 25            end_index = self.valid_tones.index(str(self))
 26            new_interval = end_index - start_index
 27            return Interval(new_interval)
 28        elif isinstance(other, Interval):
 29            tone_index = self.valid_tones.index(str(self))
 30            interval_index = other.valid_intervals.index(str(other))
 31            new_tone = tone_index - interval_index
 32            return Tone(self.valid_tones[new_tone])
 33    
 34
 35class Interval:
 36    def __init__(self, interval):
 37        self.valid_intervals = ['unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 
 38                                'major 3rd', 'perfect 4th', 'diminished 5th', 'perfect 5th',
 39                                'minor 6th', 'major 6th', 'minor 7th', 'major 7th']
 40        
 41        all_intervals = interval % NUM_OF_TONES
 42        self.interval = self.valid_intervals[all_intervals]
 43        
 44    def __str__(self):
 45        return f'{self.interval}'
 46    
 47    def __add__(self, other):
 48        if isinstance(other, Interval):
 49            first_index = self.valid_intervals.index(str(self))
 50            second_index = self.valid_intervals.index(str(other))
 51            new_interval = first_index + second_index
 52            return Interval(new_interval)
 53        else:
 54            raise TypeError('Invalid operation')
 55        
 56    def __neg__(self):
 57        current_index = self.valid_intervals.index(str(self))
 58        new_index = (NUM_OF_TONES - current_index) % NUM_OF_TONES
 59        return Interval(new_index)
 60        
 61
 62class Chord(Tone, Interval):
 63    def __init__(self, root, *args):
 64        super().__init__(args)
 65        unique_tones = set()
 66        unique_tones.add(str(root))
 67        for tone in args:
 68                unique_tones.add(str(tone))
 69        if len(unique_tones) < 2:
 70            raise TypeError('Cannot have a chord made of only 1 unique tone')
 71        root_index = self.valid_tones.index(str(root))
 72        new_order = []
 73        for i in range(0, NUM_OF_TONES):
 74            new_order.append(self.valid_tones[(root_index + i) % NUM_OF_TONES])
 75        self.tones = sorted(unique_tones, key=lambda tone: new_order.index(str(tone)))
 76    
 77    def __str__(self):
 78        return f'{'-'.join(str(tone) for tone in self.tones)}'
 79    
 80    def is_minor(self):
 81        root_index = self.valid_tones.index(str(self.tones[0]))
 82        minor_third = self.valid_tones[root_index + 3]
 83        for tone in self.tones:
 84            if str(tone) == minor_third:
 85                return True
 86        return False
 87        
 88    def is_major(self):
 89        root_index = self.valid_tones.index(str(self.tones[0]))
 90        major_third = self.valid_tones[root_index + 4]
 91        for tone in self.tones:
 92            if str(tone) == major_third:
 93                return True
 94        return False
 95        
 96    def is_power_chord(self):
 97        if self.is_minor() or self.is_major():
 98            return False
 99        return True
100
101    def __add__(self, other):
102        if isinstance(other, Chord):
103            tones = other.tones
104        else:
105            tones = other.tone
106        new_chord = self.tones
107        for tone in tones:
108            if str(tone) not in new_chord:
109                new_chord.append(tone)
110        return Chord(*new_chord)
111    
112    def __sub__(self, other):
113        if isinstance(other, Tone):
114            if str(other) in self.tones:
115                new_chord = []
116                for tone in self.tones:
117                    if str(tone) != str(other):
118                        new_chord.append(tone)
119                return Chord(*new_chord)
120            else: 
121                raise TypeError(f'Cannot remove tone {other} from chord {self}')
122    
123    def transposed(self, other):
124        new_chord = []
125        for tone in self.tones:
126            other_interval = other.valid_intervals.index(str(other))
127            tone_index = self.valid_tones.index(str(tone)) + other_interval
128            tone_index %= NUM_OF_TONES
129            new_chord.append(self.valid_tones[tone_index])
130        return Chord(*new_chord)

....EEE...............E....F.........
======================================================================
ERROR: test_is_major (test.TestBasicChordFunctionality.test_is_major)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 103, in test_is_major
self.assertFalse(a_minor_chord.is_major())
^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 90, in is_major
major_third = self.valid_tones[root_index + 4]
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
IndexError: list index out of range

======================================================================
ERROR: 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())
^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 82, in is_minor
minor_third = self.valid_tones[root_index + 3]
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
IndexError: list index out of range

======================================================================
ERROR: 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())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 97, in is_power_chord
if self.is_minor() or self.is_major():
^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 82, in is_minor
minor_third = self.valid_tones[root_index + 3]
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
IndexError: list index out of range

======================================================================
ERROR: test_add_tone_to_chord_existing_tone (test.TestOperations.test_add_tone_to_chord_existing_tone)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 267, in test_add_tone_to_chord_existing_tone
result_chord = result_chord + Tone("G#")
~~~~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 110, in __add__
return Chord(*new_chord)
^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 75, in __init__
self.tones = sorted(unique_tones, key=lambda tone: new_order.index(str(tone)))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 75, in <lambda>
self.tones = sorted(unique_tones, key=lambda tone: new_order.index(str(tone)))
^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: '#' is not in list

======================================================================
FAIL: test_subtract_interval_from_tone_left_side_error (test.TestOperations.test_subtract_interval_from_tone_left_side_error)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 235, in test_subtract_interval_from_tone_left_side_error
self.assertEqual(str(err.exception), INVALID_OPERATION)
AssertionError: "unsupported operand type(s) for -: 'Interval' and 'Tone'" != 'Invalid operation'
- unsupported operand type(s) for -: 'Interval' and 'Tone'
+ Invalid operation

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

FAILED (failures=1, errors=4)

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