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

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

10 точки общо

37 успешни теста
0 неуспешни теста
Код

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

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

OK

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

f1TONE_ORDER = ["C", "C#", "D", "D#", "E",f1TONE_ORDER = ["C", "C#", "D", "D#", "E",
2              "F", "F#", "G", "G#", "A", "A#", "B"]2              "F", "F#", "G", "G#", "A", "A#", "B"]
3TONE_ORDER_MAP = {tone: index for index, tone in enumerate(TONE_ORDER)}3TONE_ORDER_MAP = {tone: index for index, tone in enumerate(TONE_ORDER)}
44
55
6class Tone:6class Tone:
77
8    def __init__(self, tone):8    def __init__(self, tone):
9        self.name = tone9        self.name = tone
1010
11    def __str__(self):11    def __str__(self):
12        return self.name12        return self.name
1313
14    def __eq__(self, other):14    def __eq__(self, other):
15        return isinstance(other, Tone) and self.name == other.name15        return isinstance(other, Tone) and self.name == other.name
1616
17    def __hash__(self):17    def __hash__(self):
18        return hash(self.name)18        return hash(self.name)
1919
20    def __add__(self, other):20    def __add__(self, other):
21        if isinstance(other, Tone):21        if isinstance(other, Tone):
22            return Chord(self, other)22            return Chord(self, other)
23        elif isinstance(other, Interval):23        elif isinstance(other, Interval):
n24            index = (TONE_ORDER_MAP[self.name]+other.number_of_semitones) % 12n24            index = (TONE_ORDER_MAP[self.name] + other.number_of_semitones) % 12
25            return Tone(TONE_ORDER[index])25            return Tone(TONE_ORDER[index])
2626
27    def __sub__(self, other):27    def __sub__(self, other):
28        if isinstance(other, Tone):28        if isinstance(other, Tone):
n29            return Interval((12 + TONE_ORDER_MAP[self.name]-TONE_ORDER_MAP[other.name]) % 12)n29            return Interval((12 + TONE_ORDER_MAP[self.name] - TONE_ORDER_MAP[other.name]) % 12)
30        elif isinstance(other, Interval):30        elif isinstance(other, Interval):
n31            index = (12 + TONE_ORDER_MAP[self.name] -n31            index = (12 + TONE_ORDER_MAP[self.name] - other.number_of_semitones) % 12
32                     other.number_of_semitones) % 12
33            return Tone(TONE_ORDER[index])32            return Tone(TONE_ORDER[index])
3433
3534
36class Interval:35class Interval:
37    intervals = {0: 'unison',36    intervals = {0: 'unison',
38                 1: 'minor 2nd',37                 1: 'minor 2nd',
39                 2: 'major 2nd',38                 2: 'major 2nd',
40                 3: 'minor 3rd',39                 3: 'minor 3rd',
41                 4: 'major 3rd',40                 4: 'major 3rd',
42                 5: 'perfect 4th',41                 5: 'perfect 4th',
43                 6: 'diminished 5th',42                 6: 'diminished 5th',
44                 7: 'perfect 5th',43                 7: 'perfect 5th',
45                 8: 'minor 6th',44                 8: 'minor 6th',
46                 9: 'major 6th',45                 9: 'major 6th',
47                 10: 'minor 7th',46                 10: 'minor 7th',
48                 11: 'major 7th'}47                 11: 'major 7th'}
4948
50    def __init__(self, number):49    def __init__(self, number):
n51        number = number % 12n
52        self.number_of_semitones = number50        self.number_of_semitones = number % 12
5351
54    def __str__(self):52    def __str__(self):
55        return self.intervals[self.number_of_semitones]53        return self.intervals[self.number_of_semitones]
5654
57    def __add__(self, other):55    def __add__(self, other):
58        if isinstance(other, Interval):56        if isinstance(other, Interval):
59            return Interval(self.number_of_semitones + other.number_of_semitones)57            return Interval(self.number_of_semitones + other.number_of_semitones)
60        elif isinstance(other, Tone):58        elif isinstance(other, Tone):
61            raise TypeError("Invalid operation")59            raise TypeError("Invalid operation")
6260
63    def __sub__(self, other):61    def __sub__(self, other):
64        if isinstance(other, Tone):62        if isinstance(other, Tone):
65            raise TypeError("Invalid operation")63            raise TypeError("Invalid operation")
6664
67    def __neg__(self):65    def __neg__(self):
68        return Interval(12 - self.number_of_semitones)66        return Interval(12 - self.number_of_semitones)
6967
7068
71class Chord:69class Chord:
7270
73    def __init__(self, root, *args):71    def __init__(self, root, *args):
74        unique_tones = {root, *args}72        unique_tones = {root, *args}
7573
76        if len(unique_tones) < 2:74        if len(unique_tones) < 2:
77            raise TypeError('Cannot have a chord made of only 1 unique tone')75            raise TypeError('Cannot have a chord made of only 1 unique tone')
7876
79        self.main_tone = root77        self.main_tone = root
80        self.root_index = TONE_ORDER_MAP[root.name]78        self.root_index = TONE_ORDER_MAP[root.name]
8179
82        self.tones = sorted(80        self.tones = sorted(
83            unique_tones,81            unique_tones,
84            key=lambda tone: (TONE_ORDER_MAP[tone.name] - self.root_index) % len(TONE_ORDER))82            key=lambda tone: (TONE_ORDER_MAP[tone.name] - self.root_index) % len(TONE_ORDER))
8583
86    def __str__(self):84    def __str__(self):
87        return "-".join(tone.name for tone in self.tones)85        return "-".join(tone.name for tone in self.tones)
8886
89    def is_minor(self):87    def is_minor(self):
90        for tone in self.tones:88        for tone in self.tones:
n91            if (TONE_ORDER_MAP[tone.name]-self.root_index+12) % 12 == 3:n89            if (TONE_ORDER_MAP[tone.name] - self.root_index + 12) % 12 == 3:
92                return True90                return True
93        return False91        return False
9492
95    def is_major(self):93    def is_major(self):
96        for tone in self.tones:94        for tone in self.tones:
n97            if (TONE_ORDER_MAP[tone.name]-self.root_index+12) % 12 == 4:n95            if (TONE_ORDER_MAP[tone.name] - self.root_index + 12) % 12 == 4:
98                return True96                return True
99        return False97        return False
10098
101    def is_power_chord(self):99    def is_power_chord(self):
102        return not self.is_major() and not self.is_minor()100        return not self.is_major() and not self.is_minor()
103101
104    def __add__(self, other):102    def __add__(self, other):
105        if isinstance(other, Tone):103        if isinstance(other, Tone):
106            return Chord(self.main_tone, *self.tones, other)104            return Chord(self.main_tone, *self.tones, other)
107        elif isinstance(other, Chord):105        elif isinstance(other, Chord):
108            return Chord(self.main_tone, *self.tones, *other.tones)106            return Chord(self.main_tone, *self.tones, *other.tones)
109107
110    def __sub__(self, other):108    def __sub__(self, other):
111        if isinstance(other, Tone):109        if isinstance(other, Tone):
112            if other in self.tones:110            if other in self.tones:
113                new_tones = [tone for tone in self.tones if tone != other]111                new_tones = [tone for tone in self.tones if tone != other]
n114                if other == self.main_tone:n112                new_main_tone = self.main_tone if self.main_tone != other else new_tones[0]
115                    self.main_tone = new_tones[0]
116                return Chord(self.main_tone, *new_tones)113                return Chord(new_main_tone, *new_tones)
117            else:114            else:
118                raise TypeError(115                raise TypeError(
119                    f'Cannot remove tone {other} from chord {self}')116                    f'Cannot remove tone {other} from chord {self}')
120117
121    def transposed(self, interval):118    def transposed(self, interval):
t122        newRoot = self.main_tone + intervalt119        new_root = self.main_tone + interval
123        newTones = tuple(tone + interval for tone in self.tones)120        new_tones = tuple(tone + interval for tone in self.tones)
124        return Chord(newRoot, *newTones)121        return Chord(new_root, *new_tones)
125122
126123
127124
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op