Домашни > Pitches love the D > Решения > Решението на Йована Божилов

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

6 точки общо

23 успешни теста
14 неуспешни теста
Код (Домашна работа 3)
Скрий всички коментари

 1class Tone:
 2    VALID_TONES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
 3    INVALID_OPERATION_ERROR_MESSAGE = "Invalid operation"
 4
 5    def __init__(self, tone):
 6        if tone not in Tone.VALID_TONES:
 7            raise TypeError(self.INVALID_OPERATION_ERROR_MESSAGE)
 8        self.tone = tone
 9
10    def __str__(self):
11        return self.tone
12
13    def __add__(self, other):
14        if isinstance(other, Tone):
15            return Chord(self, other)
16        elif isinstance(other, Interval):
17            index = (Tone.VALID_TONES.index(self.tone) + other.length) % len(Tone.VALID_TONES)
18            return Tone(Tone.VALID_TONES[index])
19        else:
20            raise TypeError(self.INVALID_OPERATION_ERROR_MESSAGE)
21
22    def __sub__(self, other):
23        if isinstance(other, Tone):
24            index_diff = (Tone.VALID_TONES.index(self.tone) - Tone.VALID_TONES.index(other.tone)) % len(Tone.VALID_TONES)
25            return Interval(index_diff)
26        elif isinstance(other, Interval):
27            index = (Tone.VALID_TONES.index(self.tone) - other.length) % len(Tone.VALID_TONES)
28            return Tone(Tone.VALID_TONES[index])
29        else:
30            raise TypeError(self.INVALID_OPERATION_ERROR_MESSAGE)
31
32
33class Interval:
34    INTERVAL_NAMES = ['unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th']
35
36    def __init__(self, length):
37        self.length = length % 12
38
39    def __str__(self):
40        return Interval.INTERVAL_NAMES[self.length]
41
42    def __add__(self, other):
43        if isinstance(other, Interval):
44            return Interval(self.length + other.length)
45        else:
46            raise TypeError(Tone.INVALID_OPERATION_ERROR_MESSAGE)
47
48
49class Chord:
50    TONES_COUNT_ERROR_MESSAGE = 'Cannot have a chord made of only 1 unique tone'
51
52    def __init__(self, *tones):
53        unique_tones = {tone.tone for tone in tones}
54        if len(unique_tones) < 2:
55            raise TypeError(self.TONES_COUNT_ERROR_MESSAGE)
56        self.tones = sorted(unique_tones, key=lambda x: Tone.VALID_TONES.index(x))
57
58    def __str__(self):
59        return '-'.join(self.tones)
60
61    def is_minor(self):
62        if 'C' in self.tones and 'D#' in self.tones and 'G' in self.tones:
63            return True
64        return False
65
66    def is_major(self):
67        if 'C' in self.tones and 'E' in self.tones and 'G' in self.tones:
68            return True
69        return False
70
71    def is_power_chord(self):
72        if len(self.tones) == 2 and 'C' in self.tones and 'G' in self.tones:
73            return True
74        return False
75
76    def __add__(self, other):
77        if isinstance(other, Tone):
78            if other.tone not in self.tones:
79                self.tones.append(other.tone)
80            return Chord(*[Tone(t) for t in self.tones])
81        elif isinstance(other, Chord):
82            combined_tones = list(set(self.tones + other.tones))
83            return Chord(*[Tone(t) for t in combined_tones])
84        else:
85            raise TypeError(Tone.INVALID_OPERATION_ERROR_MESSAGE)
86
87    def __sub__(self, tone):
88        if not isinstance(tone, Tone):
89            raise TypeError(Tone.INVALID_OPERATION_ERROR_MESSAGE)
90        if tone.tone not in self.tones:
91            raise TypeError(f"Cannot remove tone {tone.tone} from chord {self}")
92        if len(self.tones) <= 2:
93            raise TypeError(self.TONES_COUNT_ERROR_MESSAGE)
94        self.tones.remove(tone.tone)
95        return Chord(*[Tone(t) for t in self.tones])
96
97    def transposed(self, interval):
98        transposed_tones = [Tone(Tone.VALID_TONES[(Tone.VALID_TONES.index(t) + interval.length) % len(Tone.VALID_TONES)]) for t in self.tones]
99        return Chord(*transposed_tones)

.FFFFFF.EEFE.........FFF...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_chord_ordering (test.TestBasicChordFunctionality.test_chord_ordering)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 65, in test_chord_ordering
self.assertEqual(str(f_sixth_ninth_chord), "F-A-C-E")
AssertionError: 'C-E-F-A' != 'F-A-C-E'
- C-E-F-A
+ F-A-C-E

======================================================================
FAIL: test_chord_str (test.TestBasicChordFunctionality.test_chord_str)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 60, in test_chord_str
self.assertEqual(str(a_major_chord), "A-C#-E")
AssertionError: 'C#-E-A' != 'A-C#-E'
- C#-E-A
+ A-C#-E

======================================================================
FAIL: test_chord_tone_repetition (test.TestBasicChordFunctionality.test_chord_tone_repetition)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 74, in test_chord_tone_repetition
self.assertEqual(str(a_minor_chord), "A-C-E")
AssertionError: 'C-E-A' != 'A-C-E'
- C-E-A
+ A-C-E

======================================================================
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 124, in test_is_power_chord
self.assertTrue(a_kind_of_power_chord.is_power_chord())
AssertionError: False is not true

======================================================================
FAIL: test_transposed_overflow (test.TestBasicChordFunctionality.test_transposed_overflow)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 145, in test_transposed_overflow
self.assertEqual(str(result_chord), "A#-D-F")
AssertionError: 'D-F-A#' != 'A#-D-F'
- D-F-A#
+ A#-D-F

======================================================================
FAIL: test_add_tone_to_chord (test.TestOperations.test_add_tone_to_chord)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 254, in test_add_tone_to_chord
self.assertEqual(str(result_chord), "F-A-C-D")
AssertionError: 'C-D-F-A' != 'F-A-C-D'
- C-D-F-A
+ F-A-C-D

======================================================================
FAIL: 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 270, in test_add_tone_to_chord_existing_tone
self.assertEqual(str(result_chord), "F-G#-C")
AssertionError: 'C-F-G#' != 'F-G#-C'
- C-F-G#
+ F-G#-C

======================================================================
FAIL: test_add_tone_to_chord_order (test.TestOperations.test_add_tone_to_chord_order)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 261, in test_add_tone_to_chord_order
self.assertEqual(str(result_chord), "F-G-A-C")
AssertionError: 'C-F-G-A' != 'F-G-A-C'
- C-F-G-A
? --
+ F-G-A-C
? ++

======================================================================
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.003s

FAILED (failures=11, errors=3)

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