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

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

9 точки общо

32 успешни теста
5 неуспешни теста
Код

  1TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
  2INTERVALS = ('unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th')
  3SEMITONES = 12
  4
  5class Tone:
  6    def __init__(self, tone):
  7        self.tone = tone
  8
  9    def __str__(self):
 10        return str(self.tone)
 11
 12    def __add__(self, other):
 13        if isinstance(other, Tone):
 14            return Chord(self, other)
 15        elif isinstance(other, Interval):
 16            semitones = other.semitones % SEMITONES
 17            self_index = TONES.index(str(self))
 18            self_index += semitones
 19            return Tone(TONES[self_index % SEMITONES])
 20        return NotImplemented
 21
 22    def __sub__(self, other):
 23        self_index = TONES.index(str(self))
 24        if isinstance(other, Tone):
 25            other_index = TONES.index(str(other))
 26            return Interval(abs(self_index - other_index))
 27        elif isinstance(other, Interval):
 28            semitones = other.semitones % SEMITONES
 29            self_index -= semitones
 30            return Tone(TONES[self_index % SEMITONES])
 31        return NotImplemented
 32
 33    def __eq__(self, other):
 34        if isinstance(other, Tone):
 35            return self.tone == other.tone
 36        return False
 37
 38    #ne znam kakvo tochno oznachava no mi izleze greshka che Tone trqbva da e hashable
 39    def __hash__(self):
 40        return hash(self.tone)
 41
 42
 43class Interval:
 44    def __init__(self, semitones):
 45        self.semitones = semitones
 46
 47    def __str__(self):
 48        return INTERVALS[self.semitones % SEMITONES] 
 49
 50    def __add__(self, other):
 51        if isinstance(other, Tone):
 52            raise TypeError('Invalid operation')
 53        elif isinstance(other, Interval):
 54            return Interval((self.semitones + other.semitones) % SEMITONES)
 55    
 56    def __sub__(self, other):
 57        if isinstance(other, Tone):
 58            raise TypeError('Invalid operation')
 59    
 60    def __neg__(self):
 61        return Interval(-self.semitones)
 62
 63  
 64class Chord:
 65    def __init__(self, *args):
 66        tones = list(set(args))
 67        if len(tones) == 1:
 68            raise TypeError('Cannot have a chord made of only 1 unique tone')
 69        else:
 70            self.root = args[0]            
 71            self.tones = tones
 72
 73    def __str__(self):
 74        output = str(self.root.tone)
 75        root_index = TONES.index(str(self.root.tone))
 76        tone_names = {str(tone) for tone in self.tones}
 77        for tone in TONES[root_index + 1:]:
 78            if tone in tone_names:
 79                output += '-' + tone
 80        for tone in TONES[:root_index]:
 81            if tone in tone_names:
 82                output += '-' + tone
 83        return output
 84        
 85    def __add__(self, other):
 86        if isinstance(other, Tone):
 87            return Chord(self.root, *self.tones, other)
 88        elif isinstance(other, Chord):
 89            return Chord(*self.tones, *other.tones)
 90        return NotImplemented
 91
 92    def __sub__(self, other):
 93        if isinstance(other, Tone):
 94            if other in self.tones:
 95                other_index = self.tones.index(other)
 96                return Chord(*self.tones[:other_index], *self.tones[other_index + 1:])
 97            else:
 98               raise TypeError(f'Cannot remove tone {other} from chord {self}') 
 99        return NotImplemented
100
101    def is_minor(self):
102        for tone in self.tones:
103            interval = self.root - tone 
104            if str(interval) == 'minor 3rd':
105                return True
106        return False
107
108    def is_major(self):
109        for tone in self.tones:
110            interval = self.root - tone
111            if str(interval) == 'major 3rd':
112                return True
113        return False
114
115    def is_power_chord(self):
116        return not (self.is_minor() or self.is_major())
117    
118    def transposed(self, interval):
119        new_tones = []
120        new_tones.append(self.root + interval)
121        for tone in self.tones:
122            new_tones.append(tone + interval)
123        return Chord(*new_tones)

....FFF.......................F....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_tone_from_chord (test.TestOperations.test_subtract_tone_from_chord)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 277, in test_subtract_tone_from_chord
self.assertEqual(str(result_chord), "F-G#")
AssertionError: 'G#-F' != 'F-G#'
- G#-F
+ F-G#

======================================================================
FAIL: test_tone_subtraction_inverse (test.TestOperations.test_tone_subtraction_inverse)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 178, in test_tone_subtraction_inverse
self.assertEqual(str(perfect_4th), "perfect 4th")
AssertionError: 'perfect 5th' != 'perfect 4th'
- perfect 5th
? ^
+ perfect 4th
? ^

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

FAILED (failures=5)

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

n1TONES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']n1TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
2INTERVALS = ['unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th']2INTERVALS = ('unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th')
3 3SEMITONES = 12
44
5class Tone:5class Tone:
6    def __init__(self, tone):6    def __init__(self, tone):
7        self.tone = tone7        self.tone = tone
88
9    def __str__(self):9    def __str__(self):
10        return str(self.tone)10        return str(self.tone)
1111
12    def __add__(self, other):12    def __add__(self, other):
13        if isinstance(other, Tone):13        if isinstance(other, Tone):
14            return Chord(self, other)14            return Chord(self, other)
15        elif isinstance(other, Interval):15        elif isinstance(other, Interval):
n16            semitones = other.semitones % 12n16            semitones = other.semitones % SEMITONES
17            self_index = TONES.index(str(self))17            self_index = TONES.index(str(self))
18            self_index += semitones18            self_index += semitones
n19            return Tone(TONES[self_index % 12])n19            return Tone(TONES[self_index % SEMITONES])
20        return NotImplemented20        return NotImplemented
2121
22    def __sub__(self, other):22    def __sub__(self, other):
23        self_index = TONES.index(str(self))23        self_index = TONES.index(str(self))
24        if isinstance(other, Tone):24        if isinstance(other, Tone):
25            other_index = TONES.index(str(other))25            other_index = TONES.index(str(other))
26            return Interval(abs(self_index - other_index))26            return Interval(abs(self_index - other_index))
27        elif isinstance(other, Interval):27        elif isinstance(other, Interval):
n28            semitones = other.semitones % 12n28            semitones = other.semitones % SEMITONES
29            self_index -= semitones29            self_index -= semitones
n30            return Tone(TONES[self_index % 12])n30            return Tone(TONES[self_index % SEMITONES])
31        return NotImplemented31        return NotImplemented
3232
33    def __eq__(self, other):33    def __eq__(self, other):
34        if isinstance(other, Tone):34        if isinstance(other, Tone):
35            return self.tone == other.tone35            return self.tone == other.tone
36        return False36        return False
3737
38    #ne znam kakvo tochno oznachava no mi izleze greshka che Tone trqbva da e hashable38    #ne znam kakvo tochno oznachava no mi izleze greshka che Tone trqbva da e hashable
39    def __hash__(self):39    def __hash__(self):
40        return hash(self.tone)40        return hash(self.tone)
4141
4242
43class Interval:43class Interval:
44    def __init__(self, semitones):44    def __init__(self, semitones):
45        self.semitones = semitones45        self.semitones = semitones
4646
47    def __str__(self):47    def __str__(self):
n48        return INTERVALS[self.semitones % 12n48        return INTERVALS[self.semitones % SEMITONES
4949
50    def __add__(self, other):50    def __add__(self, other):
51        if isinstance(other, Tone):51        if isinstance(other, Tone):
52            raise TypeError('Invalid operation')52            raise TypeError('Invalid operation')
53        elif isinstance(other, Interval):53        elif isinstance(other, Interval):
n54            return Interval((self.semitones + other.semitones) % 12)n54            return Interval((self.semitones + other.semitones) % SEMITONES)
55    55    
56    def __sub__(self, other):56    def __sub__(self, other):
57        if isinstance(other, Tone):57        if isinstance(other, Tone):
58            raise TypeError('Invalid operation')58            raise TypeError('Invalid operation')
59    59    
60    def __neg__(self):60    def __neg__(self):
61        return Interval(-self.semitones)61        return Interval(-self.semitones)
6262
63  63  
64class Chord:64class Chord:
65    def __init__(self, *args):65    def __init__(self, *args):
66        tones = list(set(args))66        tones = list(set(args))
67        if len(tones) == 1:67        if len(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')
69        else:69        else:
70            self.root = args[0]            70            self.root = args[0]            
71            self.tones = tones71            self.tones = tones
7272
73    def __str__(self):73    def __str__(self):
74        output = str(self.root.tone)74        output = str(self.root.tone)
75        root_index = TONES.index(str(self.root.tone))75        root_index = TONES.index(str(self.root.tone))
76        tone_names = {str(tone) for tone in self.tones}76        tone_names = {str(tone) for tone in self.tones}
77        for tone in TONES[root_index + 1:]:77        for tone in TONES[root_index + 1:]:
78            if tone in tone_names:78            if tone in tone_names:
79                output += '-' + tone79                output += '-' + tone
80        for tone in TONES[:root_index]:80        for tone in TONES[:root_index]:
81            if tone in tone_names:81            if tone in tone_names:
82                output += '-' + tone82                output += '-' + tone
83        return output83        return output
84        84        
85    def __add__(self, other):85    def __add__(self, other):
86        if isinstance(other, Tone):86        if isinstance(other, Tone):
87            return Chord(self.root, *self.tones, other)87            return Chord(self.root, *self.tones, other)
88        elif isinstance(other, Chord):88        elif isinstance(other, Chord):
89            return Chord(*self.tones, *other.tones)89            return Chord(*self.tones, *other.tones)
90        return NotImplemented90        return NotImplemented
9191
92    def __sub__(self, other):92    def __sub__(self, other):
93        if isinstance(other, Tone):93        if isinstance(other, Tone):
94            if other in self.tones:94            if other in self.tones:
n95                if len(self.tones) < 3:n
96                    raise TypeError('Cannot have a chord made of only 1 unique tone')
97                else:
98                    other_index = self.tones.index(other)95                other_index = self.tones.index(other)
99                    return Chord(*self.tones[:other_index], *self.tones[other_index + 1:])96                return Chord(*self.tones[:other_index], *self.tones[other_index + 1:])
100            else:97            else:
101               raise TypeError(f'Cannot remove tone {other} from chord {self}') 98               raise TypeError(f'Cannot remove tone {other} from chord {self}') 
102        return NotImplemented99        return NotImplemented
103100
104    def is_minor(self):101    def is_minor(self):
105        for tone in self.tones:102        for tone in self.tones:
106            interval = self.root - tone 103            interval = self.root - tone 
107            if str(interval) == 'minor 3rd':104            if str(interval) == 'minor 3rd':
108                return True105                return True
109        return False106        return False
110107
111    def is_major(self):108    def is_major(self):
112        for tone in self.tones:109        for tone in self.tones:
113            interval = self.root - tone110            interval = self.root - tone
114            if str(interval) == 'major 3rd':111            if str(interval) == 'major 3rd':
115                return True112                return True
116        return False113        return False
117114
118    def is_power_chord(self):115    def is_power_chord(self):
119        return not (self.is_minor() or self.is_major())116        return not (self.is_minor() or self.is_major())
120    117    
121    def transposed(self, interval):118    def transposed(self, interval):
t122        new_tones = list()t119        new_tones = []
123        new_tones.append(self.root + interval)120        new_tones.append(self.root + interval)
124        for tone in self.tones:121        for tone in self.tones:
125            new_tones.append(tone + interval)122            new_tones.append(tone + interval)
126        return Chord(*new_tones)123        return Chord(*new_tones)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op