Домашни > Pitches love the D > Решения > Решението на Надежда Донева

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

11 точки общо

37 успешни теста
0 неуспешни теста
Код
Скрий всички коментари

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

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

OK

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

f1class Tone:f1class Tone:
2    CHROMATIC_SCALE = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")2    CHROMATIC_SCALE = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")
33
4    def __init__(self, name):4    def __init__(self, name):
5        self.name = name5        self.name = name
6        self.index = self.CHROMATIC_SCALE.index(name)6        self.index = self.CHROMATIC_SCALE.index(name)
77
8    def __str__(self):8    def __str__(self):
9        return self.name9        return self.name
10    10    
11    def __eq__(self, other):11    def __eq__(self, other):
12        return self.name == other.name12        return self.name == other.name
13    13    
14    def __hash__(self):14    def __hash__(self):
15        return hash(self.name)15        return hash(self.name)
16    16    
17    def __add__(self, other):17    def __add__(self, other):
nn18        """Add Tone and Tone or Tone and Interval"""
18        if isinstance(other, Tone):19        if isinstance(other, Tone):
19            return Chord(self, other)20            return Chord(self, other)
20        if isinstance(other, Interval):21        if isinstance(other, Interval):
21            return Tone(self.CHROMATIC_SCALE[(self.index + other.semitones) % 12])22            return Tone(self.CHROMATIC_SCALE[(self.index + other.semitones) % 12])
22    23    
23    def __sub__(self, other):24    def __sub__(self, other):
nn25        """Substract Tone from Tone or Tone from Interval"""
24        if isinstance(other, Tone):26        if isinstance(other, Tone):
25            return Interval((self.index - other.index) % 12)27            return Interval((self.index - other.index) % 12)
26        if isinstance(other, Interval):28        if isinstance(other, Interval):
27            return Tone(self.CHROMATIC_SCALE[(self.index - other.semitones) % 12])29            return Tone(self.CHROMATIC_SCALE[(self.index - other.semitones) % 12])
2830
29    31    
3032
31class Interval:33class Interval:
32    INTERVAL_NAMES = (34    INTERVAL_NAMES = (
33        "unison",35        "unison",
34        "minor 2nd",36        "minor 2nd",
35        "major 2nd",    37        "major 2nd",    
36        "minor 3rd",38        "minor 3rd",
37        "major 3rd",39        "major 3rd",
38        "perfect 4th",40        "perfect 4th",
39        "diminished 5th",41        "diminished 5th",
40        "perfect 5th",42        "perfect 5th",
41        "minor 6th",43        "minor 6th",
42        "major 6th",44        "major 6th",
43        "minor 7th",45        "minor 7th",
44        "major 7th"46        "major 7th"
45    )47    )
4648
47    def __init__(self, semitones):49    def __init__(self, semitones):
48        self.semitones = semitones % 1250        self.semitones = semitones % 12
4951
50    def __str__(self):52    def __str__(self):
51        return self.INTERVAL_NAMES[self.semitones % 12]53        return self.INTERVAL_NAMES[self.semitones % 12]
52    54    
53    def __add__(self, other):55    def __add__(self, other):
nn56        """Throw err when adding Interval and Tone; Add Interval and Interval"""
54        if isinstance(other, Tone):57        if isinstance(other, Tone):
55            raise TypeError("Invalid operation")58            raise TypeError("Invalid operation")
56        if isinstance(other, Interval):59        if isinstance(other, Interval):
57            return Interval((self.semitones + other.semitones) % 12)60            return Interval((self.semitones + other.semitones) % 12)
58        61        
59    def __sub__(self, other):62    def __sub__(self, other):
nn63        """Throw err when substracting Tone from Interval"""
60        if isinstance(other, Tone):64        if isinstance(other, Tone):
61            raise TypeError("Invalid operation")65            raise TypeError("Invalid operation")
62        66        
63    def __neg__(self):67    def __neg__(self):
64        return Interval(-self.semitones)68        return Interval(-self.semitones)
65    69    
6670
67class Chord:71class Chord:
68    def __init__(self, root, *tones):72    def __init__(self, root, *tones):
69        unique_tones = {root, *tones}73        unique_tones = {root, *tones}
70        if len(unique_tones) < 2:74        if len(unique_tones) < 2:
71            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")
72        self.root = root76        self.root = root
73        self.tones = sorted(unique_tones, key=lambda tone: (tone.index - root.index) % 12)77        self.tones = sorted(unique_tones, key=lambda tone: (tone.index - root.index) % 12)
7478
75    def __str__(self):79    def __str__(self):
76        return "-".join(str(t) for t in self.tones)80        return "-".join(str(t) for t in self.tones)
77    81    
78    def is_minor(self):82    def is_minor(self):
nn83        """Has minor 3rd"""
79        return any((t.index - self.root.index) % 12 == 3 for t in self.tones)84        return any((t.index - self.root.index) % 12 == 3 for t in self.tones)
80    85    
81    def is_major(self):86    def is_major(self):
nn87        """Has major 3rd"""
82        return any((t.index - self.root.index) % 12 == 4 for t in self.tones)88        return any((t.index - self.root.index) % 12 == 4 for t in self.tones)
83    89    
84    def is_power_chord(self):90    def is_power_chord(self):
nn91        """Is not minor and major"""
85        return not (self.is_minor() or self.is_major())92        return not (self.is_minor() or self.is_major())
86    93    
87    def __sub__(self, other):94    def __sub__(self, other):
nn95        """Substract Tone from Chord"""
88        if isinstance(other, Tone):96        if isinstance(other, Tone):
89            if other not in self.tones:97            if other not in self.tones:
90                raise TypeError(f"Cannot remove tone {other} from chord {self}")98                raise TypeError(f"Cannot remove tone {other} from chord {self}")
91            new_tones = [tone for tone in self.tones if tone != other]99            new_tones = [tone for tone in self.tones if tone != other]
92            if len(new_tones) < 2:100            if len(new_tones) < 2:
93                raise TypeError("Cannot have a chord made of only 1 unique tone")101                raise TypeError("Cannot have a chord made of only 1 unique tone")
94            if other == self.root:102            if other == self.root:
95                new_root = new_tones[0]103                new_root = new_tones[0]
96                return Chord(new_root, *new_tones)104                return Chord(new_root, *new_tones)
97            return Chord(self.root, *new_tones)105            return Chord(self.root, *new_tones)
98        106        
99    def __add__(self, other):107    def __add__(self, other):
nn108        """Add Chord and Tone or Chord and Chord"""
109        if isinstance(other, Tone):
110            self.tones.append(other)
111            unique_tones = {self.root, *self.tones}
112            self.tones = sorted(unique_tones, key=lambda tone: (tone.index - self.root.index) % 12)
113            return Chord(self.root, *self.tones)
100        if isinstance(other, Chord):114        if isinstance(other, Chord):
101            tones_sum = {self.root, *self.tones, *other.tones}115            tones_sum = {self.root, *self.tones, *other.tones}
102            return Chord(self.root, *tones_sum)116            return Chord(self.root, *tones_sum)
103        117        
104    def transposed(self, interval):118    def transposed(self, interval):
nn119        """Move with interval positions each tone in the chord"""
105        transposed_tones = [tone + interval for tone in self.tones]120        transposed_tones = [tone + interval for tone in self.tones]
106        return Chord(transposed_tones[0], *transposed_tones)121        return Chord(transposed_tones[0], *transposed_tones)
t107 t
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op