Домашни > Pitches love the D > Решения > Решението на Димитър Илиев

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

7 точки общо

25 успешни теста
12 неуспешни теста
Код

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

F..F....EE.E.F.FF.....F....F..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'

======================================================================
ERROR: test_subtract_tone_from_chord (test.TestOperations.test_subtract_tone_from_chord)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 275, in test_subtract_tone_from_chord
result_chord = f_minor_chord - Tone("C")
~~~~~~~~~~~~~~^~~~~~~~~~~
File "/tmp/solution.py", line 87, in __sub__
raise TypeError(f"Cannot remove tone {other} from chord {self}")
TypeError: Cannot remove tone C from chord F-G#-C

======================================================================
FAIL: test_chord_not_enough_tones (test.TestBasicChordFunctionality.test_chord_not_enough_tones)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 83, in test_chord_not_enough_tones
with self.assertRaises(TypeError) as err:
AssertionError: TypeError not raised

======================================================================
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: 'A-A-A-A-A-A-A-C-C-C-C-C-C-C-C-C-C-C-C-C-C-E-E-E-E-E-E-E-E-E-E-E-E-E-E-E-E-E-E' != 'A-C-E'
- A-A-A-A-A-A-A-C-C-C-C-C-C-C-C-C-C-C-C-C-C-E-E-E-E-E-E-E-E-E-E-E-E-E-E-E-E-E-E
+ A-C-E

======================================================================
FAIL: test_interval_str (test.TestBasicIntervalFunctionality.test_interval_str)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 42, in test_interval_str
self.assertEqual(str(Interval(index)), interval)
AssertionError: 'augmented 4th' != 'diminished 5th'
- augmented 4th
+ diminished 5th

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

======================================================================
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: 'G-G-C-C' != 'C-G'
- G-G-C-C
+ C-G

======================================================================
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: 'F-F-G#-G#-C-C' != 'F-G#-C'
- F-F-G#-G#-C-C
+ F-G#-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

======================================================================
FAIL: test_tone_addition_same_tone (test.TestOperations.test_tone_addition_same_tone)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 166, in test_tone_addition_same_tone
with self.assertRaises(TypeError) as err:
AssertionError: TypeError not raised

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

FAILED (failures=8, errors=4)

Дискусия
Виктор Бечев
05.11.2024 10:34

Тъй е по-добре... Че иначе имаше 1 точка защото беше сменил името с главни букви горе и после го беше ползвал пак с малки.
Димитър Илиев
05.11.2024 10:10

Качих трети вариант, надявам се да се вижда! Поздрави! Халанд от Алиекспрес
Виктор Бечев
04.11.2024 16:20

А пусна ли новата версия? П.П. Това, което ти казах за константата важи и на други места, не само където съм го отбелязал изрично.
Димитър Илиев
04.11.2024 11:11

Привет, благодаря за обратната връзка, ще кача нова версия! Поздрави! Димитър
Виктор Бечев
02.11.2024 21:55

Отвъд горните забележки - изглежда добре. :)
История

f1class Tone:f1class Tone:
2    TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]2    TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
n3    n3 
4    def __init__(self, name):4    def __init__(self, name):
n5        if name not in Tone.tones:n5        if name not in Tone.TONES:
6            raise ValueError("Invalid tone name.")6            raise ValueError("Invalid tone name.")
7        self.name = name7        self.name = name
n8        self.index = Tone.tones.index(name)n8        self.index = Tone.TONES.index(name)
9    9 
10    def __str__(self):10    def __str__(self):
11        return self.name11        return self.name
n12    n12 
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other, Tone):14        if isinstance(other, Tone):
15            return Chord(self, other)15            return Chord(self, other)
16        elif isinstance(other, Interval):16        elif isinstance(other, Interval):
17            new_index = (self.index + other.semitones) % 1217            new_index = (self.index + other.semitones) % 12
n18            return Tone(Tone.tones[new_index])n18            return Tone(Tone.TONES[new_index])
19        raise TypeError("Invalid operation")19        raise TypeError("Invalid operation")
n20    n20 
21    def __sub__(self, other):21    def __sub__(self, other):
22        if isinstance(other, Tone):22        if isinstance(other, Tone):
23            semitone_diff = (self.index - other.index) % 1223            semitone_diff = (self.index - other.index) % 12
24            return Interval(semitone_diff)24            return Interval(semitone_diff)
25        elif isinstance(other, Interval):25        elif isinstance(other, Interval):
26            new_index = (self.index - other.semitones) % 1226            new_index = (self.index - other.semitones) % 12
n27            return Tone(Tone.tones[new_index])n27            return Tone(Tone.TONES[new_index])
28        raise TypeError("Invalid operation")28        raise TypeError("Invalid operation")
2929
3030
31class Interval:31class Interval:
n32    intervals = [n32    INTERVAL_NAMES = [
33        "unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd",33        "unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd",
34        "perfect 4th", "augmented 4th", "perfect 5th", "minor 6th",34        "perfect 4th", "augmented 4th", "perfect 5th", "minor 6th",
35        "major 6th", "minor 7th", "major 7th"35        "major 6th", "minor 7th", "major 7th"
36    ]36    ]
3737
38    def __init__(self, semitones):38    def __init__(self, semitones):
39        self.semitones = semitones % 1239        self.semitones = semitones % 12
4040
41    def __str__(self):41    def __str__(self):
n42        return self.intervals[self.semitones]n42        return self.INTERVAL_NAMES[self.semitones]
4343
44    def __add__(self, other):44    def __add__(self, other):
45        if isinstance(other, Interval):45        if isinstance(other, Interval):
46            return Interval(self.semitones + other.semitones)46            return Interval(self.semitones + other.semitones)
47        raise TypeError("Invalid operation")47        raise TypeError("Invalid operation")
4848
4949
50class Chord:50class Chord:
51    def __init__(self, root, *tones):51    def __init__(self, root, *tones):
52        self.root = root52        self.root = root
53        unique_tones = {root}53        unique_tones = {root}
54        for tone in tones:54        for tone in tones:
55            unique_tones.add(tone)55            unique_tones.add(tone)
56        if len(unique_tones) < 2:56        if len(unique_tones) < 2:
57            raise TypeError("Cannot have a chord made of only 1 unique tone")57            raise TypeError("Cannot have a chord made of only 1 unique tone")
58        self.tones = sorted(unique_tones, key=lambda tone: (tone.index - root.index) % 12)58        self.tones = sorted(unique_tones, key=lambda tone: (tone.index - root.index) % 12)
n59    n59 
60    def __str__(self):60    def __str__(self):
61        return "-".join(str(tone) for tone in self.tones)61        return "-".join(str(tone) for tone in self.tones)
n62    n62 
63    def is_minor(self):63    def is_minor(self):
64        return any((tone - self.root).semitones == 3 for tone in self.tones if tone != self.root)64        return any((tone - self.root).semitones == 3 for tone in self.tones if tone != self.root)
n65    n65 
66    def is_major(self):66    def is_major(self):
67        return any((tone - self.root).semitones == 4 for tone in self.tones if tone != self.root)67        return any((tone - self.root).semitones == 4 for tone in self.tones if tone != self.root)
n68    n68 
69    def is_power_chord(self):69    def is_power_chord(self):
70        return not self.is_minor() and not self.is_major()70        return not self.is_minor() and not self.is_major()
n71    n71 
72    def __add__(self, other):72    def __add__(self, other):
73        if isinstance(other, Tone):73        if isinstance(other, Tone):
n74            new_tones = self.tones + [other] if other not in self.tones else self.tonesn74            if other not in self.tones:
75                new_tones = self.tones + [other]
76            else:
77                new_tones = self.tones
75            return Chord(*new_tones)78            return Chord(*new_tones)
76        elif isinstance(other, Chord):79        elif isinstance(other, Chord):
77            combined_tones = set(self.tones) | set(other.tones)80            combined_tones = set(self.tones) | set(other.tones)
78            return Chord(*combined_tones)81            return Chord(*combined_tones)
79        raise TypeError("Invalid operation")82        raise TypeError("Invalid operation")
n80    n83 
81    def __sub__(self, other):84    def __sub__(self, other):
82        if isinstance(other, Tone):85        if isinstance(other, Tone):
83            if other not in self.tones:86            if other not in self.tones:
84                raise TypeError(f"Cannot remove tone {other} from chord {self}")87                raise TypeError(f"Cannot remove tone {other} from chord {self}")
85            new_tones = [tone for tone in self.tones if tone != other]88            new_tones = [tone for tone in self.tones if tone != other]
86            if len(new_tones) < 2:89            if len(new_tones) < 2:
87                raise TypeError("Cannot have a chord made of only 1 unique tone")90                raise TypeError("Cannot have a chord made of only 1 unique tone")
88            return Chord(*new_tones)91            return Chord(*new_tones)
89        raise TypeError("Invalid operation")92        raise TypeError("Invalid operation")
t90    t93 
91    def transposed(self, interval):94    def transposed(self, interval):
92        if not isinstance(interval, Interval):95        if not isinstance(interval, Interval):
93            raise TypeError("Invalid interval type for transposition")96            raise TypeError("Invalid interval type for transposition")
94        transposed_tones = [tone + interval for tone in self.tones]97        transposed_tones = [tone + interval for tone in self.tones]
95        return Chord(*transposed_tones)98        return Chord(*transposed_tones)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Tone:f1class Tone:
n2    tones = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]n2    TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
3    3    
4    def __init__(self, name):4    def __init__(self, name):
5        if name not in Tone.tones:5        if name not in Tone.tones:
6            raise ValueError("Invalid tone name.")6            raise ValueError("Invalid tone name.")
7        self.name = name7        self.name = name
8        self.index = Tone.tones.index(name)8        self.index = Tone.tones.index(name)
9    9    
10    def __str__(self):10    def __str__(self):
11        return self.name11        return self.name
12    12    
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other, Tone):14        if isinstance(other, Tone):
15            return Chord(self, other)15            return Chord(self, other)
16        elif isinstance(other, Interval):16        elif isinstance(other, Interval):
17            new_index = (self.index + other.semitones) % 1217            new_index = (self.index + other.semitones) % 12
18            return Tone(Tone.tones[new_index])18            return Tone(Tone.tones[new_index])
19        raise TypeError("Invalid operation")19        raise TypeError("Invalid operation")
20    20    
21    def __sub__(self, other):21    def __sub__(self, other):
22        if isinstance(other, Tone):22        if isinstance(other, Tone):
23            semitone_diff = (self.index - other.index) % 1223            semitone_diff = (self.index - other.index) % 12
24            return Interval(semitone_diff)24            return Interval(semitone_diff)
25        elif isinstance(other, Interval):25        elif isinstance(other, Interval):
26            new_index = (self.index - other.semitones) % 1226            new_index = (self.index - other.semitones) % 12
27            return Tone(Tone.tones[new_index])27            return Tone(Tone.tones[new_index])
28        raise TypeError("Invalid operation")28        raise TypeError("Invalid operation")
2929
3030
31class Interval:31class Interval:
n32    intervals = {n32    intervals = [
33        1: "minor 2nd", 2: "major 2nd", 3: "minor 3rd", 4: "major 3rd", 33        "unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd",
34        5: "perfect 4th", 6: "augmented 4th", 7: "perfect 5th", 34        "perfect 4th", "augmented 4th", "perfect 5th", "minor 6th",
35        8: "minor 6th", 9: "major 6th", 10: "minor 7th", 11: "major 7th", 0: "unison"35        "major 6th", "minor 7th", "major 7th"
36    }36    ]
3737
38    def __init__(self, semitones):38    def __init__(self, semitones):
39        self.semitones = semitones % 1239        self.semitones = semitones % 12
n40    n40 
41    def __str__(self):41    def __str__(self):
t42        return self.intervals.get(self.semitones, "unison")t42        return self.intervals[self.semitones]
43    43 
44    def __add__(self, other):44    def __add__(self, other):
45        if isinstance(other, Interval):45        if isinstance(other, Interval):
46            return Interval(self.semitones + other.semitones)46            return Interval(self.semitones + other.semitones)
47        raise TypeError("Invalid operation")47        raise TypeError("Invalid operation")
4848
4949
50class Chord:50class Chord:
51    def __init__(self, root, *tones):51    def __init__(self, root, *tones):
52        self.root = root52        self.root = root
53        unique_tones = {root}53        unique_tones = {root}
54        for tone in tones:54        for tone in tones:
55            unique_tones.add(tone)55            unique_tones.add(tone)
56        if len(unique_tones) < 2:56        if len(unique_tones) < 2:
57            raise TypeError("Cannot have a chord made of only 1 unique tone")57            raise TypeError("Cannot have a chord made of only 1 unique tone")
58        self.tones = sorted(unique_tones, key=lambda tone: (tone.index - root.index) % 12)58        self.tones = sorted(unique_tones, key=lambda tone: (tone.index - root.index) % 12)
59    59    
60    def __str__(self):60    def __str__(self):
61        return "-".join(str(tone) for tone in self.tones)61        return "-".join(str(tone) for tone in self.tones)
62    62    
63    def is_minor(self):63    def is_minor(self):
64        return any((tone - self.root).semitones == 3 for tone in self.tones if tone != self.root)64        return any((tone - self.root).semitones == 3 for tone in self.tones if tone != self.root)
65    65    
66    def is_major(self):66    def is_major(self):
67        return any((tone - self.root).semitones == 4 for tone in self.tones if tone != self.root)67        return any((tone - self.root).semitones == 4 for tone in self.tones if tone != self.root)
68    68    
69    def is_power_chord(self):69    def is_power_chord(self):
70        return not self.is_minor() and not self.is_major()70        return not self.is_minor() and not self.is_major()
71    71    
72    def __add__(self, other):72    def __add__(self, other):
73        if isinstance(other, Tone):73        if isinstance(other, Tone):
74            new_tones = self.tones + [other] if other not in self.tones else self.tones74            new_tones = self.tones + [other] if other not in self.tones else self.tones
75            return Chord(*new_tones)75            return Chord(*new_tones)
76        elif isinstance(other, Chord):76        elif isinstance(other, Chord):
77            combined_tones = set(self.tones) | set(other.tones)77            combined_tones = set(self.tones) | set(other.tones)
78            return Chord(*combined_tones)78            return Chord(*combined_tones)
79        raise TypeError("Invalid operation")79        raise TypeError("Invalid operation")
80    80    
81    def __sub__(self, other):81    def __sub__(self, other):
82        if isinstance(other, Tone):82        if isinstance(other, Tone):
83            if other not in self.tones:83            if other not in self.tones:
84                raise TypeError(f"Cannot remove tone {other} from chord {self}")84                raise TypeError(f"Cannot remove tone {other} from chord {self}")
85            new_tones = [tone for tone in self.tones if tone != other]85            new_tones = [tone for tone in self.tones if tone != other]
86            if len(new_tones) < 2:86            if len(new_tones) < 2:
87                raise TypeError("Cannot have a chord made of only 1 unique tone")87                raise TypeError("Cannot have a chord made of only 1 unique tone")
88            return Chord(*new_tones)88            return Chord(*new_tones)
89        raise TypeError("Invalid operation")89        raise TypeError("Invalid operation")
90    90    
91    def transposed(self, interval):91    def transposed(self, interval):
92        if not isinstance(interval, Interval):92        if not isinstance(interval, Interval):
93            raise TypeError("Invalid interval type for transposition")93            raise TypeError("Invalid interval type for transposition")
94        transposed_tones = [tone + interval for tone in self.tones]94        transposed_tones = [tone + interval for tone in self.tones]
95        return Chord(*transposed_tones)95        return Chord(*transposed_tones)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op