Домашни > Pitches love the D > Решения > Решението на Виктория Гарджева

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

11 точки общо

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

  1class Tone:
  2
  3    TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
  4    TONES_COUNT = len(TONES)
  5
  6    def __init__(self, name):
  7        self.name = name
  8        self.position = self.TONES.index(self.name)
  9
 10    def __eq__(self, other):
 11        return self.name == other.name
 12
 13    def __str__(self):
 14        return self.name
 15
 16    def __add__(self, other):
 17        if isinstance(other, Tone):
 18            return Chord(self, other)
 19        elif isinstance(other, Interval):
 20            result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT
 21            return Tone(self.TONES[result_tone_position])
 22
 23    def __sub__(self, other):
 24        if isinstance(other, Tone):
 25            return Interval(self.position - other.position)
 26        elif isinstance(other, Interval):
 27            result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT
 28            return Tone(self.TONES[result_tone_position])
 29
 30
 31class Interval:
 32
 33    POSSIBLE_INTERVALS = ["unison", "minor 2nd", "major 2nd",
 34         "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th",
 35         "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"
 36    ]
 37    INTERVALS_COUNT = len(POSSIBLE_INTERVALS)
 38
 39    def __init__(self, number_of_semitones):
 40        self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT
 41
 42    def __str__(self):
 43        return self.POSSIBLE_INTERVALS[self.number_of_semitones]
 44
 45    def __add__(self, other):
 46        if isinstance(other, Interval):
 47            return Interval(self.number_of_semitones + other.number_of_semitones)
 48        elif isinstance(other, Tone):
 49            raise TypeError("Invalid operation")
 50
 51    def __sub__(self, other):
 52        if isinstance(other, Tone):
 53            raise TypeError("Invalid operation")
 54
 55    def __neg__(self):
 56        return Interval(-self.number_of_semitones)
 57
 58
 59class Chord:
 60
 61    def __init__(self, root_tone, *args):
 62        self.tones = [root_tone]
 63        for tone in args:
 64            if tone.name not in [t.name for t in self.tones]:
 65                self.tones.append(tone)
 66        if len(self.tones) < 2:
 67            raise TypeError("Cannot have a chord made of only 1 unique tone")
 68
 69    def position_of_tone(self, tone):
 70        return (tone.position - self.tones[0].position) % Tone.TONES_COUNT
 71
 72    def __str__(self):
 73        sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t))
 74        return '-'.join(str(tone) for tone in sorted_tones)
 75
 76    def __add__(self, other):
 77        if isinstance(other, Tone):
 78            return Chord(*self.tones, other)
 79        if isinstance(other, Chord):
 80            return Chord(*self.tones, *other.tones)
 81
 82    def __sub__(self, other):
 83        """В тази функция приемам, че при премахване на root акорда, root става следващия акорд
 84        по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид."""
 85        if isinstance(other, Tone):
 86            if other not in self.tones:
 87                raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
 88            if len(self.tones) <= 2:
 89                raise TypeError("Cannot have a chord made of only 1 unique tone")
 90            new_tones = [tone for tone in self.tones if tone != other]
 91            return Chord(*new_tones)
 92
 93    def is_minor(self):
 94        root_tone = self.tones[0]
 95        for tone in self.tones[1:]:
 96            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3:
 97                return True
 98        return False
 99
100    def is_major(self):
101        root_tone = self.tones[0]
102        for tone in self.tones[1:]:
103            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4:
104                return True
105        return False
106
107    def is_power_chord(self):
108        return not (self.is_minor() or self.is_major())
109
110    def transposed(self, interval):
111        transpose_by = interval.number_of_semitones
112        new_tones = []
113        for tone in self.tones:
114            if transpose_by >= 0:
115                new_tones.append(tone + interval)
116            else:
117                new_tones.append(tone + (-interval))
118        return Chord(*new_tones)

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

OK

Дискусия
Виктор Бечев
06.11.2024 16:01

Много чисто, браво!
История

f1class Tone:f1class Tone:
22
3    TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]3    TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
4    TONES_COUNT = len(TONES)4    TONES_COUNT = len(TONES)
55
6    def __init__(self, name):6    def __init__(self, name):
7        self.name = name7        self.name = name
8        self.position = self.TONES.index(self.name)8        self.position = self.TONES.index(self.name)
99
10    def __eq__(self, other):10    def __eq__(self, other):
11        return self.name == other.name11        return self.name == other.name
1212
13    def __str__(self):13    def __str__(self):
14        return self.name14        return self.name
1515
16    def __add__(self, other):16    def __add__(self, other):
17        if isinstance(other, Tone):17        if isinstance(other, Tone):
18            return Chord(self, other)18            return Chord(self, other)
19        elif isinstance(other, Interval):19        elif isinstance(other, Interval):
20            result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT20            result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT
21            return Tone(self.TONES[result_tone_position])21            return Tone(self.TONES[result_tone_position])
2222
23    def __sub__(self, other):23    def __sub__(self, other):
24        if isinstance(other, Tone):24        if isinstance(other, Tone):
25            return Interval(self.position - other.position)25            return Interval(self.position - other.position)
26        elif isinstance(other, Interval):26        elif isinstance(other, Interval):
27            result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT27            result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT
28            return Tone(self.TONES[result_tone_position])28            return Tone(self.TONES[result_tone_position])
2929
3030
31class Interval:31class Interval:
3232
n33    POSSIBLE_INTERVALS = {n33    POSSIBLE_INTERVALS = ["unison", "minor 2nd", "major 2nd",
34        0: "unison",34         "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th",
35        1 : "minor 2nd",35         "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"
36        2 : "major 2nd",
37        3 : "minor 3rd",
38        4 : "major 3rd",
39        5 : "perfect 4th",
40        6 : "diminished 5th",
41        7 : "perfect 5th",
42        8 : "minor 6th",
43        9 : "major 6th",
44        10: "minor 7th",
45        11: "major 7th"
46    }36    ]
47    INTERVALS_COUNT = len(POSSIBLE_INTERVALS)37    INTERVALS_COUNT = len(POSSIBLE_INTERVALS)
4838
49    def __init__(self, number_of_semitones):39    def __init__(self, number_of_semitones):
50        self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT40        self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT
5141
52    def __str__(self):42    def __str__(self):
53        return self.POSSIBLE_INTERVALS[self.number_of_semitones]43        return self.POSSIBLE_INTERVALS[self.number_of_semitones]
5444
55    def __add__(self, other):45    def __add__(self, other):
56        if isinstance(other, Interval):46        if isinstance(other, Interval):
57            return Interval(self.number_of_semitones + other.number_of_semitones)47            return Interval(self.number_of_semitones + other.number_of_semitones)
58        elif isinstance(other, Tone):48        elif isinstance(other, Tone):
59            raise TypeError("Invalid operation")49            raise TypeError("Invalid operation")
6050
61    def __sub__(self, other):51    def __sub__(self, other):
62        if isinstance(other, Tone):52        if isinstance(other, Tone):
63            raise TypeError("Invalid operation")53            raise TypeError("Invalid operation")
6454
65    def __neg__(self):55    def __neg__(self):
66        return Interval(-self.number_of_semitones)56        return Interval(-self.number_of_semitones)
6757
6858
69class Chord:59class Chord:
7060
71    def __init__(self, root_tone, *args):61    def __init__(self, root_tone, *args):
72        self.tones = [root_tone]62        self.tones = [root_tone]
73        for tone in args:63        for tone in args:
74            if tone.name not in [t.name for t in self.tones]:64            if tone.name not in [t.name for t in self.tones]:
75                self.tones.append(tone)65                self.tones.append(tone)
76        if len(self.tones) < 2:66        if len(self.tones) < 2:
77            raise TypeError("Cannot have a chord made of only 1 unique tone")67            raise TypeError("Cannot have a chord made of only 1 unique tone")
7868
79    def position_of_tone(self, tone):69    def position_of_tone(self, tone):
80        return (tone.position - self.tones[0].position) % Tone.TONES_COUNT70        return (tone.position - self.tones[0].position) % Tone.TONES_COUNT
8171
82    def __str__(self):72    def __str__(self):
83        sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t))73        sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t))
n84        string_representation = '-'.join(str(tone) for tone in sorted_tones)n74        return '-'.join(str(tone) for tone in sorted_tones)
85        return string_representation
8675
87    def __add__(self, other):76    def __add__(self, other):
88        if isinstance(other, Tone):77        if isinstance(other, Tone):
89            return Chord(*self.tones, other)78            return Chord(*self.tones, other)
90        if isinstance(other, Chord):79        if isinstance(other, Chord):
91            return Chord(*self.tones, *other.tones)80            return Chord(*self.tones, *other.tones)
9281
93    def __sub__(self, other):82    def __sub__(self, other):
94        """В тази функция приемам, че при премахване на root акорда, root става следващия акорд83        """В тази функция приемам, че при премахване на root акорда, root става следващия акорд
95        по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид."""84        по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид."""
96        if isinstance(other, Tone):85        if isinstance(other, Tone):
97            if other not in self.tones:86            if other not in self.tones:
98                raise TypeError(f"Cannot remove tone {other.name} from chord {self}")87                raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
99            if len(self.tones) <= 2:88            if len(self.tones) <= 2:
100                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")
101            new_tones = [tone for tone in self.tones if tone != other]90            new_tones = [tone for tone in self.tones if tone != other]
102            return Chord(*new_tones)91            return Chord(*new_tones)
10392
104    def is_minor(self):93    def is_minor(self):
105        root_tone = self.tones[0]94        root_tone = self.tones[0]
106        for tone in self.tones[1:]:95        for tone in self.tones[1:]:
107            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3:96            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3:
108                return True97                return True
109        return False98        return False
11099
111    def is_major(self):100    def is_major(self):
112        root_tone = self.tones[0]101        root_tone = self.tones[0]
113        for tone in self.tones[1:]:102        for tone in self.tones[1:]:
114            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4:103            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4:
115                return True104                return True
116        return False105        return False
117106
118    def is_power_chord(self):107    def is_power_chord(self):
t119        if not (self.is_minor() or self.is_major()):t108        return not (self.is_minor() or self.is_major())
120            return True
121        return False
122109
123    def transposed(self, interval):110    def transposed(self, interval):
124        transpose_by = interval.number_of_semitones111        transpose_by = interval.number_of_semitones
125        new_tones = []112        new_tones = []
126        for tone in self.tones:113        for tone in self.tones:
127            if transpose_by >= 0:114            if transpose_by >= 0:
128                new_tones.append(tone + interval)115                new_tones.append(tone + interval)
129            else:116            else:
130                new_tones.append(tone + (-interval))117                new_tones.append(tone + (-interval))
131        return Chord(*new_tones)118        return Chord(*new_tones)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Tone:f1class Tone:
22
3    TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]3    TONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
4    TONES_COUNT = len(TONES)4    TONES_COUNT = len(TONES)
55
6    def __init__(self, name):6    def __init__(self, name):
7        self.name = name7        self.name = name
8        self.position = self.TONES.index(self.name)8        self.position = self.TONES.index(self.name)
99
10    def __eq__(self, other):10    def __eq__(self, other):
11        return self.name == other.name11        return self.name == other.name
1212
13    def __str__(self):13    def __str__(self):
14        return self.name14        return self.name
1515
16    def __add__(self, other):16    def __add__(self, other):
17        if isinstance(other, Tone):17        if isinstance(other, Tone):
18            return Chord(self, other)18            return Chord(self, other)
19        elif isinstance(other, Interval):19        elif isinstance(other, Interval):
20            result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT20            result_tone_position = (self.position + other.number_of_semitones) % self.TONES_COUNT
21            return Tone(self.TONES[result_tone_position])21            return Tone(self.TONES[result_tone_position])
2222
23    def __sub__(self, other):23    def __sub__(self, other):
24        if isinstance(other, Tone):24        if isinstance(other, Tone):
25            return Interval(self.position - other.position)25            return Interval(self.position - other.position)
26        elif isinstance(other, Interval):26        elif isinstance(other, Interval):
27            result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT27            result_tone_position = (self.position - other.number_of_semitones) % self.TONES_COUNT
28            return Tone(self.TONES[result_tone_position])28            return Tone(self.TONES[result_tone_position])
2929
3030
31class Interval:31class Interval:
3232
33    POSSIBLE_INTERVALS = {33    POSSIBLE_INTERVALS = {
34        0: "unison",34        0: "unison",
35        1 : "minor 2nd",35        1 : "minor 2nd",
36        2 : "major 2nd",36        2 : "major 2nd",
37        3 : "minor 3rd",37        3 : "minor 3rd",
38        4 : "major 3rd",38        4 : "major 3rd",
39        5 : "perfect 4th",39        5 : "perfect 4th",
40        6 : "diminished 5th",40        6 : "diminished 5th",
41        7 : "perfect 5th",41        7 : "perfect 5th",
42        8 : "minor 6th",42        8 : "minor 6th",
43        9 : "major 6th",43        9 : "major 6th",
44        10: "minor 7th",44        10: "minor 7th",
45        11: "major 7th"45        11: "major 7th"
46    }46    }
47    INTERVALS_COUNT = len(POSSIBLE_INTERVALS)47    INTERVALS_COUNT = len(POSSIBLE_INTERVALS)
4848
49    def __init__(self, number_of_semitones):49    def __init__(self, number_of_semitones):
50        self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT50        self.number_of_semitones = number_of_semitones % self.INTERVALS_COUNT
5151
52    def __str__(self):52    def __str__(self):
53        return self.POSSIBLE_INTERVALS[self.number_of_semitones]53        return self.POSSIBLE_INTERVALS[self.number_of_semitones]
5454
55    def __add__(self, other):55    def __add__(self, other):
56        if isinstance(other, Interval):56        if isinstance(other, Interval):
57            return Interval(self.number_of_semitones + other.number_of_semitones)57            return Interval(self.number_of_semitones + other.number_of_semitones)
58        elif isinstance(other, Tone):58        elif isinstance(other, Tone):
n59            return TypeError("Invalid operation")n59            raise TypeError("Invalid operation")
6060
61    def __sub__(self, other):61    def __sub__(self, other):
62        if isinstance(other, Tone):62        if isinstance(other, Tone):
t63            return TypeError("Invalid operation")t63            raise TypeError("Invalid operation")
6464
65    def __neg__(self):65    def __neg__(self):
66        return Interval(-self.number_of_semitones)66        return Interval(-self.number_of_semitones)
6767
6868
69class Chord:69class Chord:
7070
71    def __init__(self, root_tone, *args):71    def __init__(self, root_tone, *args):
72        self.tones = [root_tone]72        self.tones = [root_tone]
73        for tone in args:73        for tone in args:
74            if tone.name not in [t.name for t in self.tones]:74            if tone.name not in [t.name for t in self.tones]:
75                self.tones.append(tone)75                self.tones.append(tone)
76        if len(self.tones) < 2:76        if len(self.tones) < 2:
77            raise TypeError("Cannot have a chord made of only 1 unique tone")77            raise TypeError("Cannot have a chord made of only 1 unique tone")
7878
79    def position_of_tone(self, tone):79    def position_of_tone(self, tone):
80        return (tone.position - self.tones[0].position) % Tone.TONES_COUNT80        return (tone.position - self.tones[0].position) % Tone.TONES_COUNT
8181
82    def __str__(self):82    def __str__(self):
83        sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t))83        sorted_tones = sorted(self.tones, key = lambda t: self.position_of_tone(t))
84        string_representation = '-'.join(str(tone) for tone in sorted_tones)84        string_representation = '-'.join(str(tone) for tone in sorted_tones)
85        return string_representation85        return string_representation
8686
87    def __add__(self, other):87    def __add__(self, other):
88        if isinstance(other, Tone):88        if isinstance(other, Tone):
89            return Chord(*self.tones, other)89            return Chord(*self.tones, other)
90        if isinstance(other, Chord):90        if isinstance(other, Chord):
91            return Chord(*self.tones, *other.tones)91            return Chord(*self.tones, *other.tones)
9292
93    def __sub__(self, other):93    def __sub__(self, other):
94        """В тази функция приемам, че при премахване на root акорда, root става следващия акорд94        """В тази функция приемам, че при премахване на root акорда, root става следващия акорд
95        по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид."""95        по реда на подаване в конструктора, а не следващия акорд спрямо "сортирания" вид."""
96        if isinstance(other, Tone):96        if isinstance(other, Tone):
97            if other not in self.tones:97            if other not in self.tones:
98                raise TypeError(f"Cannot remove tone {other.name} from chord {self}")98                raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
99            if len(self.tones) <= 2:99            if len(self.tones) <= 2:
100                raise TypeError("Cannot have a chord made of only 1 unique tone")100                raise TypeError("Cannot have a chord made of only 1 unique tone")
101            new_tones = [tone for tone in self.tones if tone != other]101            new_tones = [tone for tone in self.tones if tone != other]
102            return Chord(*new_tones)102            return Chord(*new_tones)
103103
104    def is_minor(self):104    def is_minor(self):
105        root_tone = self.tones[0]105        root_tone = self.tones[0]
106        for tone in self.tones[1:]:106        for tone in self.tones[1:]:
107            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3:107            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 3:
108                return True108                return True
109        return False109        return False
110110
111    def is_major(self):111    def is_major(self):
112        root_tone = self.tones[0]112        root_tone = self.tones[0]
113        for tone in self.tones[1:]:113        for tone in self.tones[1:]:
114            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4:114            if (tone.position - root_tone.position) % Tone.TONES_COUNT == 4:
115                return True115                return True
116        return False116        return False
117117
118    def is_power_chord(self):118    def is_power_chord(self):
119        if not (self.is_minor() or self.is_major()):119        if not (self.is_minor() or self.is_major()):
120            return True120            return True
121        return False121        return False
122122
123    def transposed(self, interval):123    def transposed(self, interval):
124        transpose_by = interval.number_of_semitones124        transpose_by = interval.number_of_semitones
125        new_tones = []125        new_tones = []
126        for tone in self.tones:126        for tone in self.tones:
127            if transpose_by >= 0:127            if transpose_by >= 0:
128                new_tones.append(tone + interval)128                new_tones.append(tone + interval)
129            else:129            else:
130                new_tones.append(tone + (-interval))130                new_tones.append(tone + (-interval))
131        return Chord(*new_tones)131        return Chord(*new_tones)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op