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

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

10 точки общо

37 успешни теста
0 неуспешни теста
Код (Ненужен list)

  1TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
  2INTERVALS = ('unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd',
  3             'perfect 4th', 'diminished 5th', 'perfect 5th',
  4             'minor 6th', 'major 6th', 'minor 7th', 'major 7th')
  5
  6
  7class Tone(int):
  8    """Represent a musical tone."""
  9
 10    def __new__(cls, tone):
 11        """Create instance based on string or normalized int."""
 12        if isinstance(tone, str):
 13            tone = TONES.index(tone)
 14        if isinstance(tone, int):
 15            tone = tone % len(TONES)
 16        return super().__new__(cls, tone)
 17    
 18    def __str__(self):
 19        """String representation of a tone."""
 20        return TONES[self]
 21    
 22    def __add__(self, other):
 23        """Define adding something to tone."""
 24        if isinstance(other, Tone):
 25            return Chord(Tone(self), Tone(other))
 26        if isinstance(other, Interval):
 27            return Tone(int(self) + int(other))
 28        return super().__add__(other)
 29    
 30    def __sub__(self, other):
 31        """Define subtracting something from tone."""
 32        if isinstance(other, Tone):
 33            return Interval(int(self) - int(other))
 34        if isinstance(other, Interval):
 35            return Tone(int(self) - int(other))
 36        return super().__sub__(other)
 37
 38
 39class Interval(int):
 40    """Represent a musical interval."""
 41
 42    def __new__(cls, length):
 43        """Create instance based on normalized int."""
 44        if isinstance(length, int):
 45            length = length % len(INTERVALS)
 46        return super().__new__(cls, length)
 47
 48    def __str__(self):
 49        """String representation of an interval."""
 50        return INTERVALS[self]
 51
 52    def __neg__(self):
 53        """Negative value of an interval."""
 54        return Interval(-int(self))
 55
 56    def __add__(self, other):
 57        """Define adding something to interval."""
 58        if isinstance(other, Tone):
 59            raise TypeError('Invalid operation')
 60        if isinstance(other, Interval):
 61            return Interval(int(self) + int(other))
 62        return super().__add__(other)
 63    
 64    def __sub__(self, other):
 65        """Define subtacting something from interval."""
 66        if isinstance(other, Tone):
 67            raise TypeError('Invalid operation')
 68        if isinstance(other, Interval):
 69            return Interval(int(self) - int(other))
 70        return super().__add__(other)
 71
 72
 73class Chord:
 74    """Represent a musical chord."""
 75
 76    MIN_TONES = 2
 77    MINOR_3RD = 'minor 3rd'
 78    MAJOR_3RD = 'major 3rd'
 79    MINOR_3RD_INTERVAL = Interval(INTERVALS.index(MINOR_3RD))
 80    MAJOR_3RD_INTERVAL = Interval(INTERVALS.index(MAJOR_3RD))
 81
 82    def __init__(self, root, *rest):
 83        """Initialize, keeping all tones passed as input."""
 84        sorted_tones = sorted(set((root,) + rest),
 85                              key=lambda tone: TONES.index(str(tone)))
 86        root_index = sorted_tones.index(root)
 87        self.tones = sorted_tones[root_index:] + sorted_tones[:root_index]
 88        if len(self.tones) < self.MIN_TONES:
 89            raise TypeError('Cannot have a chord made of only 1 unique tone')
 90
 91    def __str__(self):
 92        """String representation of the chord."""
 93        return "-".join(map(str, self.tones))
 94    
 95    def __add__(self, other):
 96        """Define adding something to a chord."""
 97        if isinstance(other, Tone):
 98            # Root is also found in self.tones, but who cares...
 99            # Initializing a Chord will remove the duplicates anyway.
100            # No need to duplicate this behaviour here.
101            return Chord(self.root, *(self.tones + [other]))
102        if isinstance(other, Chord):
103            return Chord(*(self.tones + other.tones))
104        raise NotImplementedError
105    
106    def __sub__(self, other):
107        """Define subtracting something from a chord."""
108        if isinstance(other, Tone):
109            if other not in self.tones:
110                raise TypeError(f'Cannot remove tone {other} from chord {self}')
111            return Chord(*list(filter(other.__ne__, self.tones)))
112        raise NotImplementedError
113
114    @property
115    def root(self):
116        """Get root of the chord."""
117        return self.tones[0]
118
119    def transposed(self, interval):
120        """Transpose a chord by an interval."""
121        return Chord(*map(Tone, map(interval.__radd__, self.tones)))
122    
123    def is_minor(self):
124        """Return boolean based on whether the chord is minor."""
125        return self.root + self.MINOR_3RD_INTERVAL in self.tones
126    
127    def is_major(self):
128        """Return boolean based on whether the chord is major."""
129        return self.root + self.MAJOR_3RD_INTERVAL in self.tones
130    
131    def is_power_chord(self):
132        """Return boolean based on whether the chord is power."""
133        return not (self.is_minor() or self.is_major())

.....................................
----------------------------------------------------------------------
Ran 37 tests in 0.001s

OK

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

f1TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')f1TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
2INTERVALS = ('unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd',2INTERVALS = ('unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd',
3             'perfect 4th', 'diminished 5th', 'perfect 5th',3             'perfect 4th', 'diminished 5th', 'perfect 5th',
4             'minor 6th', 'major 6th', 'minor 7th', 'major 7th')4             'minor 6th', 'major 6th', 'minor 7th', 'major 7th')
55
66
7class Tone(int):7class Tone(int):
8    """Represent a musical tone."""8    """Represent a musical tone."""
99
10    def __new__(cls, tone):10    def __new__(cls, tone):
11        """Create instance based on string or normalized int."""11        """Create instance based on string or normalized int."""
12        if isinstance(tone, str):12        if isinstance(tone, str):
13            tone = TONES.index(tone)13            tone = TONES.index(tone)
14        if isinstance(tone, int):14        if isinstance(tone, int):
15            tone = tone % len(TONES)15            tone = tone % len(TONES)
16        return super().__new__(cls, tone)16        return super().__new__(cls, tone)
17    17    
18    def __str__(self):18    def __str__(self):
19        """String representation of a tone."""19        """String representation of a tone."""
20        return TONES[self]20        return TONES[self]
21    21    
22    def __add__(self, other):22    def __add__(self, other):
23        """Define adding something to tone."""23        """Define adding something to tone."""
24        if isinstance(other, Tone):24        if isinstance(other, Tone):
25            return Chord(Tone(self), Tone(other))25            return Chord(Tone(self), Tone(other))
26        if isinstance(other, Interval):26        if isinstance(other, Interval):
27            return Tone(int(self) + int(other))27            return Tone(int(self) + int(other))
28        return super().__add__(other)28        return super().__add__(other)
29    29    
30    def __sub__(self, other):30    def __sub__(self, other):
31        """Define subtracting something from tone."""31        """Define subtracting something from tone."""
32        if isinstance(other, Tone):32        if isinstance(other, Tone):
33            return Interval(int(self) - int(other))33            return Interval(int(self) - int(other))
34        if isinstance(other, Interval):34        if isinstance(other, Interval):
35            return Tone(int(self) - int(other))35            return Tone(int(self) - int(other))
36        return super().__sub__(other)36        return super().__sub__(other)
3737
3838
39class Interval(int):39class Interval(int):
40    """Represent a musical interval."""40    """Represent a musical interval."""
4141
42    def __new__(cls, length):42    def __new__(cls, length):
43        """Create instance based on normalized int."""43        """Create instance based on normalized int."""
44        if isinstance(length, int):44        if isinstance(length, int):
45            length = length % len(INTERVALS)45            length = length % len(INTERVALS)
46        return super().__new__(cls, length)46        return super().__new__(cls, length)
4747
48    def __str__(self):48    def __str__(self):
49        """String representation of an interval."""49        """String representation of an interval."""
50        return INTERVALS[self]50        return INTERVALS[self]
5151
52    def __neg__(self):52    def __neg__(self):
53        """Negative value of an interval."""53        """Negative value of an interval."""
54        return Interval(-int(self))54        return Interval(-int(self))
5555
56    def __add__(self, other):56    def __add__(self, other):
57        """Define adding something to interval."""57        """Define adding something to interval."""
58        if isinstance(other, Tone):58        if isinstance(other, Tone):
59            raise TypeError('Invalid operation')59            raise TypeError('Invalid operation')
60        if isinstance(other, Interval):60        if isinstance(other, Interval):
61            return Interval(int(self) + int(other))61            return Interval(int(self) + int(other))
62        return super().__add__(other)62        return super().__add__(other)
63    63    
64    def __sub__(self, other):64    def __sub__(self, other):
65        """Define subtacting something from interval."""65        """Define subtacting something from interval."""
66        if isinstance(other, Tone):66        if isinstance(other, Tone):
67            raise TypeError('Invalid operation')67            raise TypeError('Invalid operation')
68        if isinstance(other, Interval):68        if isinstance(other, Interval):
69            return Interval(int(self) - int(other))69            return Interval(int(self) - int(other))
70        return super().__add__(other)70        return super().__add__(other)
7171
7272
73class Chord:73class Chord:
74    """Represent a musical chord."""74    """Represent a musical chord."""
7575
76    MIN_TONES = 276    MIN_TONES = 2
77    MINOR_3RD = 'minor 3rd'77    MINOR_3RD = 'minor 3rd'
78    MAJOR_3RD = 'major 3rd'78    MAJOR_3RD = 'major 3rd'
79    MINOR_3RD_INTERVAL = Interval(INTERVALS.index(MINOR_3RD))79    MINOR_3RD_INTERVAL = Interval(INTERVALS.index(MINOR_3RD))
80    MAJOR_3RD_INTERVAL = Interval(INTERVALS.index(MAJOR_3RD))80    MAJOR_3RD_INTERVAL = Interval(INTERVALS.index(MAJOR_3RD))
8181
82    def __init__(self, root, *rest):82    def __init__(self, root, *rest):
83        """Initialize, keeping all tones passed as input."""83        """Initialize, keeping all tones passed as input."""
84        sorted_tones = sorted(set((root,) + rest),84        sorted_tones = sorted(set((root,) + rest),
85                              key=lambda tone: TONES.index(str(tone)))85                              key=lambda tone: TONES.index(str(tone)))
86        root_index = sorted_tones.index(root)86        root_index = sorted_tones.index(root)
87        self.tones = sorted_tones[root_index:] + sorted_tones[:root_index]87        self.tones = sorted_tones[root_index:] + sorted_tones[:root_index]
88        if len(self.tones) < self.MIN_TONES:88        if len(self.tones) < self.MIN_TONES:
89            raise TypeError('Cannot have a chord made of only 1 unique tone')89            raise TypeError('Cannot have a chord made of only 1 unique tone')
9090
91    def __str__(self):91    def __str__(self):
92        """String representation of the chord."""92        """String representation of the chord."""
93        return "-".join(map(str, self.tones))93        return "-".join(map(str, self.tones))
94    94    
95    def __add__(self, other):95    def __add__(self, other):
96        """Define adding something to a chord."""96        """Define adding something to a chord."""
97        if isinstance(other, Tone):97        if isinstance(other, Tone):
98            # Root is also found in self.tones, but who cares...98            # Root is also found in self.tones, but who cares...
99            # Initializing a Chord will remove the duplicates anyway.99            # Initializing a Chord will remove the duplicates anyway.
100            # No need to duplicate this behaviour here.100            # No need to duplicate this behaviour here.
101            return Chord(self.root, *(self.tones + [other]))101            return Chord(self.root, *(self.tones + [other]))
102        if isinstance(other, Chord):102        if isinstance(other, Chord):
103            return Chord(*(self.tones + other.tones))103            return Chord(*(self.tones + other.tones))
104        raise NotImplementedError104        raise NotImplementedError
105    105    
106    def __sub__(self, other):106    def __sub__(self, other):
107        """Define subtracting something from a chord."""107        """Define subtracting something from a chord."""
108        if isinstance(other, Tone):108        if isinstance(other, Tone):
109            if other not in self.tones:109            if other not in self.tones:
110                raise TypeError(f'Cannot remove tone {other} from chord {self}')110                raise TypeError(f'Cannot remove tone {other} from chord {self}')
111            return Chord(*list(filter(other.__ne__, self.tones)))111            return Chord(*list(filter(other.__ne__, self.tones)))
112        raise NotImplementedError112        raise NotImplementedError
113113
114    @property114    @property
115    def root(self):115    def root(self):
116        """Get root of the chord."""116        """Get root of the chord."""
117        return self.tones[0]117        return self.tones[0]
118118
119    def transposed(self, interval):119    def transposed(self, interval):
120        """Transpose a chord by an interval."""120        """Transpose a chord by an interval."""
n121        return Chord(*list(map(Tone, map(interval.__radd__, self.tones))))n121        return Chord(*map(Tone, map(interval.__radd__, self.tones)))
122    122    
123    def is_minor(self):123    def is_minor(self):
124        """Return boolean based on whether the chord is minor."""124        """Return boolean based on whether the chord is minor."""
125        return self.root + self.MINOR_3RD_INTERVAL in self.tones125        return self.root + self.MINOR_3RD_INTERVAL in self.tones
126    126    
127    def is_major(self):127    def is_major(self):
128        """Return boolean based on whether the chord is major."""128        """Return boolean based on whether the chord is major."""
129        return self.root + self.MAJOR_3RD_INTERVAL in self.tones129        return self.root + self.MAJOR_3RD_INTERVAL in self.tones
130    130    
131    def is_power_chord(self):131    def is_power_chord(self):
132        """Return boolean based on whether the chord is power."""132        """Return boolean based on whether the chord is power."""
133        return not (self.is_minor() or self.is_major())133        return not (self.is_minor() or self.is_major())
tt134 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op