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

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

10 точки общо

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

  1INVALID_OPERATION_MESSAGE = "Invalid operation"
  2
  3
  4class Tone(str):
  5    """Class that represents a musical tone."""
  6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
  7
  8    def __add__(self, other):
  9        """Add two tones or an interval to a tone."""
 10        if isinstance(other, Tone):
 11            return Chord(self, other)
 12        if isinstance(other, Interval):
 13            current = self.TONES.index(self)
 14            new = self.TONES[(current + int(other)) % len(self.TONES)]
 15            return Tone(new)
 16
 17    def __sub__(self, other):
 18        """Subtract two tones or an interval from a tone."""
 19        if isinstance(other, Tone):
 20            return Interval(self.TONES.index(self) - self.TONES.index(other))
 21        if isinstance(other, Interval):
 22            return self.__add__(-other)
 23
 24    def __radd__(self, other):
 25        """Raise an exception attempting right-hand addition."""
 26        raise TypeError(INVALID_OPERATION_MESSAGE)
 27
 28    __rsub__ = __radd__
 29
 30
 31class Interval:
 32    """Class that represents a musical interval."""
 33    INTERVAL_NAMES = (
 34        "unison",
 35        "minor 2nd",
 36        "major 2nd",
 37        "minor 3rd",
 38        "major 3rd",
 39        "perfect 4th",
 40        "diminished 5th",
 41        "perfect 5th",
 42        "minor 6th",
 43        "major 6th",
 44        "minor 7th",
 45        "major 7th"
 46    )
 47
 48    def __init__(self, value):
 49        """Save the normalized initialization value for the interval."""
 50        self._value = value % len(self.INTERVAL_NAMES)
 51
 52    def __str__(self):
 53        return self.INTERVAL_NAMES[self._value]
 54
 55    def __add__(self, other):
 56        """Add two intervals or raise an error if adding anything else to an interval."""
 57        if isinstance(other, Interval):
 58            return Interval(self._value + other._value)
 59        raise TypeError(INVALID_OPERATION_MESSAGE)
 60
 61    def __neg__(self):
 62        return Interval(-self._value)
 63
 64    def __int__(self):
 65        return self._value
 66
 67
 68class Chord:
 69    """Class that represents a musical chord."""
 70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"
 71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"
 72
 73    def __init__(self, *notes):
 74        """Leave only unique notes and sort relative to the root."""
 75        root = notes[0]
 76        unique_and_sorted = sorted(list(set(notes)))
 77        root_index = unique_and_sorted.index(root)
 78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]
 79        if len(unique_and_sorted) <= 1:
 80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)
 81        self.notes = unique_and_sorted
 82
 83    def __str__(self):
 84        return "-".join(self.notes)
 85
 86    def __add__(self, other):
 87        """Add a tone to a chord."""
 88        if isinstance(other, Tone):
 89            return Chord(*self.notes, other)
 90        if isinstance(other, Chord):
 91            return Chord(*self.notes, *other.notes)
 92
 93    def __sub__(self, other):
 94        """Remove a tone from a chord if possible."""
 95        if isinstance(other, Tone):
 96            if other not in self.notes:
 97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))
 98            return Chord(*[note for note in self.notes if note != other])
 99
100    def is_minor(self):
101        """Determine the age of the chord."""
102        return (Tone(self.notes[0]) + Interval(3)) in self.notes
103
104    def is_major(self):
105        """Determine the military rank of the chord."""
106        return (Tone(self.notes[0]) + Interval(4)) in self.notes
107
108    def is_power_chord(self):
109        """Determine the strenght of the chord."""
110        return not (self.is_minor() or self.is_major())
111
112    def transposed(self, interval):
113        """Return a new chord with different tones, I'm tired of docstrings."""
114        new_notes = [note + interval for note in self.notes]
115        return Chord(*new_notes)

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

OK

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

f1INVALID_OPERATION_MESSAGE = "Invalid operation"f1INVALID_OPERATION_MESSAGE = "Invalid operation"
22
33
4class Tone(str):4class Tone(str):
5    """Class that represents a musical tone."""5    """Class that represents a musical tone."""
6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
77
8    def __add__(self, other):8    def __add__(self, other):
9        """Add two tones or an interval to a tone."""9        """Add two tones or an interval to a tone."""
10        if isinstance(other, Tone):10        if isinstance(other, Tone):
11            return Chord(self, other)11            return Chord(self, other)
12        if isinstance(other, Interval):12        if isinstance(other, Interval):
13            current = self.TONES.index(self)13            current = self.TONES.index(self)
14            new = self.TONES[(current + int(other)) % len(self.TONES)]14            new = self.TONES[(current + int(other)) % len(self.TONES)]
15            return Tone(new)15            return Tone(new)
1616
17    def __sub__(self, other):17    def __sub__(self, other):
18        """Subtract two tones or an interval from a tone."""18        """Subtract two tones or an interval from a tone."""
19        if isinstance(other, Tone):19        if isinstance(other, Tone):
20            return Interval(self.TONES.index(self) - self.TONES.index(other))20            return Interval(self.TONES.index(self) - self.TONES.index(other))
21        if isinstance(other, Interval):21        if isinstance(other, Interval):
22            return self.__add__(-other)22            return self.__add__(-other)
2323
24    def __radd__(self, other):24    def __radd__(self, other):
25        """Raise an exception attempting right-hand addition."""25        """Raise an exception attempting right-hand addition."""
26        raise TypeError(INVALID_OPERATION_MESSAGE)26        raise TypeError(INVALID_OPERATION_MESSAGE)
2727
28    __rsub__ = __radd__28    __rsub__ = __radd__
2929
3030
31class Interval:31class Interval:
32    """Class that represents a musical interval."""32    """Class that represents a musical interval."""
33    INTERVAL_NAMES = (33    INTERVAL_NAMES = (
34        "unison",34        "unison",
35        "minor 2nd",35        "minor 2nd",
36        "major 2nd",36        "major 2nd",
37        "minor 3rd",37        "minor 3rd",
38        "major 3rd",38        "major 3rd",
39        "perfect 4th",39        "perfect 4th",
40        "diminished 5th",40        "diminished 5th",
41        "perfect 5th",41        "perfect 5th",
42        "minor 6th",42        "minor 6th",
43        "major 6th",43        "major 6th",
44        "minor 7th",44        "minor 7th",
45        "major 7th"45        "major 7th"
46    )46    )
4747
48    def __init__(self, value):48    def __init__(self, value):
49        """Save the normalized initialization value for the interval."""49        """Save the normalized initialization value for the interval."""
50        self._value = value % len(self.INTERVAL_NAMES)50        self._value = value % len(self.INTERVAL_NAMES)
5151
52    def __str__(self):52    def __str__(self):
53        return self.INTERVAL_NAMES[self._value]53        return self.INTERVAL_NAMES[self._value]
5454
55    def __add__(self, other):55    def __add__(self, other):
56        """Add two intervals or raise an error if adding anything else to an interval."""56        """Add two intervals or raise an error if adding anything else to an interval."""
57        if isinstance(other, Interval):57        if isinstance(other, Interval):
58            return Interval(self._value + other._value)58            return Interval(self._value + other._value)
59        raise TypeError(INVALID_OPERATION_MESSAGE)59        raise TypeError(INVALID_OPERATION_MESSAGE)
6060
61    def __neg__(self):61    def __neg__(self):
62        return Interval(-self._value)62        return Interval(-self._value)
6363
64    def __int__(self):64    def __int__(self):
65        return self._value65        return self._value
6666
6767
68class Chord:68class Chord:
69    """Class that represents a musical chord."""69    """Class that represents a musical chord."""
70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"
71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"
7272
73    def __init__(self, *notes):73    def __init__(self, *notes):
74        """Leave only unique notes and sort relative to the root."""74        """Leave only unique notes and sort relative to the root."""
75        root = notes[0]75        root = notes[0]
76        unique_and_sorted = sorted(list(set(notes)))76        unique_and_sorted = sorted(list(set(notes)))
77        root_index = unique_and_sorted.index(root)77        root_index = unique_and_sorted.index(root)
78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]
79        if len(unique_and_sorted) <= 1:79        if len(unique_and_sorted) <= 1:
80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)
81        self.notes = unique_and_sorted81        self.notes = unique_and_sorted
8282
83    def __str__(self):83    def __str__(self):
84        return "-".join(self.notes)84        return "-".join(self.notes)
8585
86    def __add__(self, other):86    def __add__(self, other):
87        """Add a tone to a chord."""87        """Add a tone to a chord."""
88        if isinstance(other, Tone):88        if isinstance(other, Tone):
89            return Chord(*self.notes, other)89            return Chord(*self.notes, other)
90        if isinstance(other, Chord):90        if isinstance(other, Chord):
t91            return Chord(*self.notes,  *other.notes)t91            return Chord(*self.notes, *other.notes)
9292
93    def __sub__(self, other):93    def __sub__(self, other):
94        """Remove a tone from a chord if possible."""94        """Remove a tone from a chord if possible."""
95        if isinstance(other, Tone):95        if isinstance(other, Tone):
96            if other not in self.notes:96            if other not in self.notes:
97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))
98            return Chord(*[note for note in self.notes if note != other])98            return Chord(*[note for note in self.notes if note != other])
9999
100    def is_minor(self):100    def is_minor(self):
101        """Determine the age of the chord."""101        """Determine the age of the chord."""
102        return (Tone(self.notes[0]) + Interval(3)) in self.notes102        return (Tone(self.notes[0]) + Interval(3)) in self.notes
103103
104    def is_major(self):104    def is_major(self):
105        """Determine the military rank of the chord."""105        """Determine the military rank of the chord."""
106        return (Tone(self.notes[0]) + Interval(4)) in self.notes106        return (Tone(self.notes[0]) + Interval(4)) in self.notes
107107
108    def is_power_chord(self):108    def is_power_chord(self):
109        """Determine the strenght of the chord."""109        """Determine the strenght of the chord."""
110        return not (self.is_minor() or self.is_major())110        return not (self.is_minor() or self.is_major())
111111
112    def transposed(self, interval):112    def transposed(self, interval):
113        """Return a new chord with different tones, I'm tired of docstrings."""113        """Return a new chord with different tones, I'm tired of docstrings."""
114        new_notes = [note + interval for note in self.notes]114        new_notes = [note + interval for note in self.notes]
115        return Chord(*new_notes)115        return Chord(*new_notes)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1INVALID_OPERATION_MESSAGE = "Invalid operation"f1INVALID_OPERATION_MESSAGE = "Invalid operation"
22
33
4class Tone(str):4class Tone(str):
5    """Class that represents a musical tone."""5    """Class that represents a musical tone."""
6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
77
8    def __add__(self, other):8    def __add__(self, other):
9        """Add two tones or an interval to a tone."""9        """Add two tones or an interval to a tone."""
10        if isinstance(other, Tone):10        if isinstance(other, Tone):
11            return Chord(self, other)11            return Chord(self, other)
12        if isinstance(other, Interval):12        if isinstance(other, Interval):
13            current = self.TONES.index(self)13            current = self.TONES.index(self)
14            new = self.TONES[(current + int(other)) % len(self.TONES)]14            new = self.TONES[(current + int(other)) % len(self.TONES)]
15            return Tone(new)15            return Tone(new)
1616
17    def __sub__(self, other):17    def __sub__(self, other):
18        """Subtract two tones or an interval from a tone."""18        """Subtract two tones or an interval from a tone."""
19        if isinstance(other, Tone):19        if isinstance(other, Tone):
t20            return Interval(self.TONES.index(self)-self.TONES.index(other))t20            return Interval(self.TONES.index(self) - self.TONES.index(other))
21        if isinstance(other, Interval):21        if isinstance(other, Interval):
22            return self.__add__(-other)22            return self.__add__(-other)
2323
24    def __radd__(self, other):24    def __radd__(self, other):
25        """Raise an exception attempting right-hand addition."""25        """Raise an exception attempting right-hand addition."""
26        raise TypeError(INVALID_OPERATION_MESSAGE)26        raise TypeError(INVALID_OPERATION_MESSAGE)
2727
28    __rsub__ = __radd__28    __rsub__ = __radd__
2929
3030
31class Interval:31class Interval:
32    """Class that represents a musical interval."""32    """Class that represents a musical interval."""
33    INTERVAL_NAMES = (33    INTERVAL_NAMES = (
34        "unison",34        "unison",
35        "minor 2nd",35        "minor 2nd",
36        "major 2nd",36        "major 2nd",
37        "minor 3rd",37        "minor 3rd",
38        "major 3rd",38        "major 3rd",
39        "perfect 4th",39        "perfect 4th",
40        "diminished 5th",40        "diminished 5th",
41        "perfect 5th",41        "perfect 5th",
42        "minor 6th",42        "minor 6th",
43        "major 6th",43        "major 6th",
44        "minor 7th",44        "minor 7th",
45        "major 7th"45        "major 7th"
46    )46    )
4747
48    def __init__(self, value):48    def __init__(self, value):
49        """Save the normalized initialization value for the interval."""49        """Save the normalized initialization value for the interval."""
50        self._value = value % len(self.INTERVAL_NAMES)50        self._value = value % len(self.INTERVAL_NAMES)
5151
52    def __str__(self):52    def __str__(self):
53        return self.INTERVAL_NAMES[self._value]53        return self.INTERVAL_NAMES[self._value]
5454
55    def __add__(self, other):55    def __add__(self, other):
56        """Add two intervals or raise an error if adding anything else to an interval."""56        """Add two intervals or raise an error if adding anything else to an interval."""
57        if isinstance(other, Interval):57        if isinstance(other, Interval):
58            return Interval(self._value + other._value)58            return Interval(self._value + other._value)
59        raise TypeError(INVALID_OPERATION_MESSAGE)59        raise TypeError(INVALID_OPERATION_MESSAGE)
6060
61    def __neg__(self):61    def __neg__(self):
62        return Interval(-self._value)62        return Interval(-self._value)
6363
64    def __int__(self):64    def __int__(self):
65        return self._value65        return self._value
6666
6767
68class Chord:68class Chord:
69    """Class that represents a musical chord."""69    """Class that represents a musical chord."""
70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"
71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"
7272
73    def __init__(self, *notes):73    def __init__(self, *notes):
74        """Leave only unique notes and sort relative to the root."""74        """Leave only unique notes and sort relative to the root."""
75        root = notes[0]75        root = notes[0]
76        unique_and_sorted = sorted(list(set(notes)))76        unique_and_sorted = sorted(list(set(notes)))
77        root_index = unique_and_sorted.index(root)77        root_index = unique_and_sorted.index(root)
78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]
79        if len(unique_and_sorted) <= 1:79        if len(unique_and_sorted) <= 1:
80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)
81        self.notes = unique_and_sorted81        self.notes = unique_and_sorted
8282
83    def __str__(self):83    def __str__(self):
84        return "-".join(self.notes)84        return "-".join(self.notes)
8585
86    def __add__(self, other):86    def __add__(self, other):
87        """Add a tone to a chord."""87        """Add a tone to a chord."""
88        if isinstance(other, Tone):88        if isinstance(other, Tone):
89            return Chord(*self.notes, other)89            return Chord(*self.notes, other)
90        if isinstance(other, Chord):90        if isinstance(other, Chord):
91            return Chord(*self.notes,  *other.notes)91            return Chord(*self.notes,  *other.notes)
9292
93    def __sub__(self, other):93    def __sub__(self, other):
94        """Remove a tone from a chord if possible."""94        """Remove a tone from a chord if possible."""
95        if isinstance(other, Tone):95        if isinstance(other, Tone):
96            if other not in self.notes:96            if other not in self.notes:
97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))
98            return Chord(*[note for note in self.notes if note != other])98            return Chord(*[note for note in self.notes if note != other])
9999
100    def is_minor(self):100    def is_minor(self):
101        """Determine the age of the chord."""101        """Determine the age of the chord."""
102        return (Tone(self.notes[0]) + Interval(3)) in self.notes102        return (Tone(self.notes[0]) + Interval(3)) in self.notes
103103
104    def is_major(self):104    def is_major(self):
105        """Determine the military rank of the chord."""105        """Determine the military rank of the chord."""
106        return (Tone(self.notes[0]) + Interval(4)) in self.notes106        return (Tone(self.notes[0]) + Interval(4)) in self.notes
107107
108    def is_power_chord(self):108    def is_power_chord(self):
109        """Determine the strenght of the chord."""109        """Determine the strenght of the chord."""
110        return not (self.is_minor() or self.is_major())110        return not (self.is_minor() or self.is_major())
111111
112    def transposed(self, interval):112    def transposed(self, interval):
113        """Return a new chord with different tones, I'm tired of docstrings."""113        """Return a new chord with different tones, I'm tired of docstrings."""
114        new_notes = [note + interval for note in self.notes]114        new_notes = [note + interval for note in self.notes]
115        return Chord(*new_notes)115        return Chord(*new_notes)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

n1INVALID_OPERATION = "Invalid operation"n1INVALID_OPERATION_MESSAGE = "Invalid operation"
22
33
4class Tone(str):4class Tone(str):
5    """Class that represents a musical tone."""5    """Class that represents a musical tone."""
6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
77
8    def __add__(self, other):8    def __add__(self, other):
9        """Add two tones or an interval to a tone."""9        """Add two tones or an interval to a tone."""
10        if isinstance(other, Tone):10        if isinstance(other, Tone):
11            return Chord(self, other)11            return Chord(self, other)
12        if isinstance(other, Interval):12        if isinstance(other, Interval):
13            current = self.TONES.index(self)13            current = self.TONES.index(self)
14            new = self.TONES[(current + int(other)) % len(self.TONES)]14            new = self.TONES[(current + int(other)) % len(self.TONES)]
15            return Tone(new)15            return Tone(new)
1616
17    def __sub__(self, other):17    def __sub__(self, other):
18        """Subtract two tones or an interval from a tone."""18        """Subtract two tones or an interval from a tone."""
19        if isinstance(other, Tone):19        if isinstance(other, Tone):
20            return Interval(self.TONES.index(self)-self.TONES.index(other))20            return Interval(self.TONES.index(self)-self.TONES.index(other))
21        if isinstance(other, Interval):21        if isinstance(other, Interval):
22            return self.__add__(-other)22            return self.__add__(-other)
2323
24    def __radd__(self, other):24    def __radd__(self, other):
25        """Raise an exception attempting right-hand addition."""25        """Raise an exception attempting right-hand addition."""
n26        raise TypeError(INVALID_OPERATION)n26        raise TypeError(INVALID_OPERATION_MESSAGE)
2727
28    __rsub__ = __radd__28    __rsub__ = __radd__
2929
3030
31class Interval:31class Interval:
32    """Class that represents a musical interval."""32    """Class that represents a musical interval."""
33    INTERVAL_NAMES = (33    INTERVAL_NAMES = (
34        "unison",34        "unison",
35        "minor 2nd",35        "minor 2nd",
36        "major 2nd",36        "major 2nd",
37        "minor 3rd",37        "minor 3rd",
38        "major 3rd",38        "major 3rd",
39        "perfect 4th",39        "perfect 4th",
40        "diminished 5th",40        "diminished 5th",
41        "perfect 5th",41        "perfect 5th",
42        "minor 6th",42        "minor 6th",
43        "major 6th",43        "major 6th",
44        "minor 7th",44        "minor 7th",
45        "major 7th"45        "major 7th"
46    )46    )
4747
48    def __init__(self, value):48    def __init__(self, value):
49        """Save the normalized initialization value for the interval."""49        """Save the normalized initialization value for the interval."""
50        self._value = value % len(self.INTERVAL_NAMES)50        self._value = value % len(self.INTERVAL_NAMES)
5151
52    def __str__(self):52    def __str__(self):
53        return self.INTERVAL_NAMES[self._value]53        return self.INTERVAL_NAMES[self._value]
5454
55    def __add__(self, other):55    def __add__(self, other):
56        """Add two intervals or raise an error if adding anything else to an interval."""56        """Add two intervals or raise an error if adding anything else to an interval."""
57        if isinstance(other, Interval):57        if isinstance(other, Interval):
58            return Interval(self._value + other._value)58            return Interval(self._value + other._value)
t59        raise TypeError(INVALID_OPERATION)t59        raise TypeError(INVALID_OPERATION_MESSAGE)
6060
61    def __neg__(self):61    def __neg__(self):
62        return Interval(-self._value)62        return Interval(-self._value)
6363
64    def __int__(self):64    def __int__(self):
65        return self._value65        return self._value
6666
6767
68class Chord:68class Chord:
69    """Class that represents a musical chord."""69    """Class that represents a musical chord."""
70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"
71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"
7272
73    def __init__(self, *notes):73    def __init__(self, *notes):
74        """Leave only unique notes and sort relative to the root."""74        """Leave only unique notes and sort relative to the root."""
75        root = notes[0]75        root = notes[0]
76        unique_and_sorted = sorted(list(set(notes)))76        unique_and_sorted = sorted(list(set(notes)))
77        root_index = unique_and_sorted.index(root)77        root_index = unique_and_sorted.index(root)
78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]
79        if len(unique_and_sorted) <= 1:79        if len(unique_and_sorted) <= 1:
80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)
81        self.notes = unique_and_sorted81        self.notes = unique_and_sorted
8282
83    def __str__(self):83    def __str__(self):
84        return "-".join(self.notes)84        return "-".join(self.notes)
8585
86    def __add__(self, other):86    def __add__(self, other):
87        """Add a tone to a chord."""87        """Add a tone to a chord."""
88        if isinstance(other, Tone):88        if isinstance(other, Tone):
89            return Chord(*self.notes, other)89            return Chord(*self.notes, other)
90        if isinstance(other, Chord):90        if isinstance(other, Chord):
91            return Chord(*self.notes,  *other.notes)91            return Chord(*self.notes,  *other.notes)
9292
93    def __sub__(self, other):93    def __sub__(self, other):
94        """Remove a tone from a chord if possible."""94        """Remove a tone from a chord if possible."""
95        if isinstance(other, Tone):95        if isinstance(other, Tone):
96            if other not in self.notes:96            if other not in self.notes:
97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))
98            return Chord(*[note for note in self.notes if note != other])98            return Chord(*[note for note in self.notes if note != other])
9999
100    def is_minor(self):100    def is_minor(self):
101        """Determine the age of the chord."""101        """Determine the age of the chord."""
102        return (Tone(self.notes[0]) + Interval(3)) in self.notes102        return (Tone(self.notes[0]) + Interval(3)) in self.notes
103103
104    def is_major(self):104    def is_major(self):
105        """Determine the military rank of the chord."""105        """Determine the military rank of the chord."""
106        return (Tone(self.notes[0]) + Interval(4)) in self.notes106        return (Tone(self.notes[0]) + Interval(4)) in self.notes
107107
108    def is_power_chord(self):108    def is_power_chord(self):
109        """Determine the strenght of the chord."""109        """Determine the strenght of the chord."""
110        return not (self.is_minor() or self.is_major())110        return not (self.is_minor() or self.is_major())
111111
112    def transposed(self, interval):112    def transposed(self, interval):
113        """Return a new chord with different tones, I'm tired of docstrings."""113        """Return a new chord with different tones, I'm tired of docstrings."""
114        new_notes = [note + interval for note in self.notes]114        new_notes = [note + interval for note in self.notes]
115        return Chord(*new_notes)115        return Chord(*new_notes)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1INVALID_OPERATION = "Invalid operation"f1INVALID_OPERATION = "Invalid operation"
22
33
4class Tone(str):4class Tone(str):
5    """Class that represents a musical tone."""5    """Class that represents a musical tone."""
6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
77
8    def __add__(self, other):8    def __add__(self, other):
9        """Add two tones or an interval to a tone."""9        """Add two tones or an interval to a tone."""
10        if isinstance(other, Tone):10        if isinstance(other, Tone):
11            return Chord(self, other)11            return Chord(self, other)
12        if isinstance(other, Interval):12        if isinstance(other, Interval):
13            current = self.TONES.index(self)13            current = self.TONES.index(self)
14            new = self.TONES[(current + int(other)) % len(self.TONES)]14            new = self.TONES[(current + int(other)) % len(self.TONES)]
15            return Tone(new)15            return Tone(new)
1616
17    def __sub__(self, other):17    def __sub__(self, other):
n18        """Subtract an interval from a tone."""n18        """Subtract two tones or an interval from a tone."""
19        if isinstance(other, Tone):19        if isinstance(other, Tone):
20            return Interval(self.TONES.index(self)-self.TONES.index(other))20            return Interval(self.TONES.index(self)-self.TONES.index(other))
21        if isinstance(other, Interval):21        if isinstance(other, Interval):
22            return self.__add__(-other)22            return self.__add__(-other)
2323
24    def __radd__(self, other):24    def __radd__(self, other):
25        """Raise an exception attempting right-hand addition."""25        """Raise an exception attempting right-hand addition."""
26        raise TypeError(INVALID_OPERATION)26        raise TypeError(INVALID_OPERATION)
2727
28    __rsub__ = __radd__28    __rsub__ = __radd__
2929
3030
31class Interval:31class Interval:
32    """Class that represents a musical interval."""32    """Class that represents a musical interval."""
33    INTERVAL_NAMES = (33    INTERVAL_NAMES = (
34        "unison",34        "unison",
35        "minor 2nd",35        "minor 2nd",
36        "major 2nd",36        "major 2nd",
37        "minor 3rd",37        "minor 3rd",
38        "major 3rd",38        "major 3rd",
39        "perfect 4th",39        "perfect 4th",
40        "diminished 5th",40        "diminished 5th",
41        "perfect 5th",41        "perfect 5th",
42        "minor 6th",42        "minor 6th",
43        "major 6th",43        "major 6th",
44        "minor 7th",44        "minor 7th",
45        "major 7th"45        "major 7th"
46    )46    )
4747
48    def __init__(self, value):48    def __init__(self, value):
49        """Save the normalized initialization value for the interval."""49        """Save the normalized initialization value for the interval."""
50        self._value = value % len(self.INTERVAL_NAMES)50        self._value = value % len(self.INTERVAL_NAMES)
5151
52    def __str__(self):52    def __str__(self):
53        return self.INTERVAL_NAMES[self._value]53        return self.INTERVAL_NAMES[self._value]
5454
55    def __add__(self, other):55    def __add__(self, other):
56        """Add two intervals or raise an error if adding anything else to an interval."""56        """Add two intervals or raise an error if adding anything else to an interval."""
57        if isinstance(other, Interval):57        if isinstance(other, Interval):
58            return Interval(self._value + other._value)58            return Interval(self._value + other._value)
59        raise TypeError(INVALID_OPERATION)59        raise TypeError(INVALID_OPERATION)
6060
61    def __neg__(self):61    def __neg__(self):
62        return Interval(-self._value)62        return Interval(-self._value)
6363
64    def __int__(self):64    def __int__(self):
65        return self._value65        return self._value
6666
6767
68class Chord:68class Chord:
69    """Class that represents a musical chord."""69    """Class that represents a musical chord."""
70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"
71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"
7272
73    def __init__(self, *notes):73    def __init__(self, *notes):
74        """Leave only unique notes and sort relative to the root."""74        """Leave only unique notes and sort relative to the root."""
75        root = notes[0]75        root = notes[0]
76        unique_and_sorted = sorted(list(set(notes)))76        unique_and_sorted = sorted(list(set(notes)))
77        root_index = unique_and_sorted.index(root)77        root_index = unique_and_sorted.index(root)
78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]
79        if len(unique_and_sorted) <= 1:79        if len(unique_and_sorted) <= 1:
80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)
81        self.notes = unique_and_sorted81        self.notes = unique_and_sorted
8282
83    def __str__(self):83    def __str__(self):
84        return "-".join(self.notes)84        return "-".join(self.notes)
8585
86    def __add__(self, other):86    def __add__(self, other):
87        """Add a tone to a chord."""87        """Add a tone to a chord."""
88        if isinstance(other, Tone):88        if isinstance(other, Tone):
89            return Chord(*self.notes, other)89            return Chord(*self.notes, other)
90        if isinstance(other, Chord):90        if isinstance(other, Chord):
91            return Chord(*self.notes,  *other.notes)91            return Chord(*self.notes,  *other.notes)
9292
93    def __sub__(self, other):93    def __sub__(self, other):
94        """Remove a tone from a chord if possible."""94        """Remove a tone from a chord if possible."""
95        if isinstance(other, Tone):95        if isinstance(other, Tone):
96            if other not in self.notes:96            if other not in self.notes:
97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))
98            return Chord(*[note for note in self.notes if note != other])98            return Chord(*[note for note in self.notes if note != other])
9999
100    def is_minor(self):100    def is_minor(self):
101        """Determine the age of the chord."""101        """Determine the age of the chord."""
102        return (Tone(self.notes[0]) + Interval(3)) in self.notes102        return (Tone(self.notes[0]) + Interval(3)) in self.notes
103103
104    def is_major(self):104    def is_major(self):
105        """Determine the military rank of the chord."""105        """Determine the military rank of the chord."""
106        return (Tone(self.notes[0]) + Interval(4)) in self.notes106        return (Tone(self.notes[0]) + Interval(4)) in self.notes
107107
108    def is_power_chord(self):108    def is_power_chord(self):
109        """Determine the strenght of the chord."""109        """Determine the strenght of the chord."""
110        return not (self.is_minor() or self.is_major())110        return not (self.is_minor() or self.is_major())
111111
112    def transposed(self, interval):112    def transposed(self, interval):
113        """Return a new chord with different tones, I'm tired of docstrings."""113        """Return a new chord with different tones, I'm tired of docstrings."""
t114        new_notes = [note+interval for note in self.notes]t114        new_notes = [note + interval for note in self.notes]
115        return Chord(*new_notes)115        return Chord(*new_notes)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1INVALID_OPERATION = "Invalid operation"f1INVALID_OPERATION = "Invalid operation"
22
33
4class Tone(str):4class Tone(str):
5    """Class that represents a musical tone."""5    """Class that represents a musical tone."""
6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
77
8    def __add__(self, other):8    def __add__(self, other):
9        """Add two tones or an interval to a tone."""9        """Add two tones or an interval to a tone."""
10        if isinstance(other, Tone):10        if isinstance(other, Tone):
11            return Chord(self, other)11            return Chord(self, other)
12        if isinstance(other, Interval):12        if isinstance(other, Interval):
13            current = self.TONES.index(self)13            current = self.TONES.index(self)
14            new = self.TONES[(current + int(other)) % len(self.TONES)]14            new = self.TONES[(current + int(other)) % len(self.TONES)]
15            return Tone(new)15            return Tone(new)
1616
17    def __sub__(self, other):17    def __sub__(self, other):
18        """Subtract an interval from a tone."""18        """Subtract an interval from a tone."""
19        if isinstance(other, Tone):19        if isinstance(other, Tone):
n20            raise TypeError(INVALID_OPERATION)n20            return Interval(self.TONES.index(self)-self.TONES.index(other))
21        if isinstance(other, Interval):
21        return self.__add__(-other)22            return self.__add__(-other)
2223
23    def __radd__(self, other):24    def __radd__(self, other):
24        """Raise an exception attempting right-hand addition."""25        """Raise an exception attempting right-hand addition."""
25        raise TypeError(INVALID_OPERATION)26        raise TypeError(INVALID_OPERATION)
2627
27    __rsub__ = __radd__28    __rsub__ = __radd__
2829
2930
30class Interval:31class Interval:
31    """Class that represents a musical interval."""32    """Class that represents a musical interval."""
32    INTERVAL_NAMES = (33    INTERVAL_NAMES = (
33        "unison",34        "unison",
34        "minor 2nd",35        "minor 2nd",
35        "major 2nd",36        "major 2nd",
36        "minor 3rd",37        "minor 3rd",
37        "major 3rd",38        "major 3rd",
38        "perfect 4th",39        "perfect 4th",
39        "diminished 5th",40        "diminished 5th",
40        "perfect 5th",41        "perfect 5th",
41        "minor 6th",42        "minor 6th",
42        "major 6th",43        "major 6th",
43        "minor 7th",44        "minor 7th",
44        "major 7th"45        "major 7th"
45    )46    )
4647
47    def __init__(self, value):48    def __init__(self, value):
48        """Save the normalized initialization value for the interval."""49        """Save the normalized initialization value for the interval."""
49        self._value = value % len(self.INTERVAL_NAMES)50        self._value = value % len(self.INTERVAL_NAMES)
5051
51    def __str__(self):52    def __str__(self):
52        return self.INTERVAL_NAMES[self._value]53        return self.INTERVAL_NAMES[self._value]
5354
54    def __add__(self, other):55    def __add__(self, other):
55        """Add two intervals or raise an error if adding anything else to an interval."""56        """Add two intervals or raise an error if adding anything else to an interval."""
56        if isinstance(other, Interval):57        if isinstance(other, Interval):
57            return Interval(self._value + other._value)58            return Interval(self._value + other._value)
58        raise TypeError(INVALID_OPERATION)59        raise TypeError(INVALID_OPERATION)
5960
60    def __neg__(self):61    def __neg__(self):
61        return Interval(-self._value)62        return Interval(-self._value)
6263
63    def __int__(self):64    def __int__(self):
64        return self._value65        return self._value
6566
6667
67class Chord:68class Chord:
68    """Class that represents a musical chord."""69    """Class that represents a musical chord."""
69    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"
70    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"
7172
72    def __init__(self, *notes):73    def __init__(self, *notes):
73        """Leave only unique notes and sort relative to the root."""74        """Leave only unique notes and sort relative to the root."""
74        root = notes[0]75        root = notes[0]
75        unique_and_sorted = sorted(list(set(notes)))76        unique_and_sorted = sorted(list(set(notes)))
76        root_index = unique_and_sorted.index(root)77        root_index = unique_and_sorted.index(root)
77        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]
78        if len(unique_and_sorted) <= 1:79        if len(unique_and_sorted) <= 1:
79            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)
80        self.notes = unique_and_sorted81        self.notes = unique_and_sorted
8182
82    def __str__(self):83    def __str__(self):
83        return "-".join(self.notes)84        return "-".join(self.notes)
8485
85    def __add__(self, other):86    def __add__(self, other):
86        """Add a tone to a chord."""87        """Add a tone to a chord."""
87        if isinstance(other, Tone):88        if isinstance(other, Tone):
88            return Chord(*self.notes, other)89            return Chord(*self.notes, other)
tt90        if isinstance(other, Chord):
91            return Chord(*self.notes,  *other.notes)
8992
90    def __sub__(self, other):93    def __sub__(self, other):
91        """Remove a tone from a chord if possible."""94        """Remove a tone from a chord if possible."""
92        if isinstance(other, Tone):95        if isinstance(other, Tone):
93            if other not in self.notes:96            if other not in self.notes:
94                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))97                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))
95            return Chord(*[note for note in self.notes if note != other])98            return Chord(*[note for note in self.notes if note != other])
9699
97    def is_minor(self):100    def is_minor(self):
98        """Determine the age of the chord."""101        """Determine the age of the chord."""
99        return (Tone(self.notes[0]) + Interval(3)) in self.notes102        return (Tone(self.notes[0]) + Interval(3)) in self.notes
100103
101    def is_major(self):104    def is_major(self):
102        """Determine the military rank of the chord."""105        """Determine the military rank of the chord."""
103        return (Tone(self.notes[0]) + Interval(4)) in self.notes106        return (Tone(self.notes[0]) + Interval(4)) in self.notes
104107
105    def is_power_chord(self):108    def is_power_chord(self):
106        """Determine the strenght of the chord."""109        """Determine the strenght of the chord."""
107        return not (self.is_minor() or self.is_major())110        return not (self.is_minor() or self.is_major())
108111
109    def transposed(self, interval):112    def transposed(self, interval):
110        """Return a new chord with different tones, I'm tired of docstrings."""113        """Return a new chord with different tones, I'm tired of docstrings."""
111        new_notes = [note+interval for note in self.notes]114        new_notes = [note+interval for note in self.notes]
112        return Chord(*new_notes)115        return Chord(*new_notes)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1INVALID_OPERATION = "Invalid operation"f1INVALID_OPERATION = "Invalid operation"
22
33
4class Tone(str):4class Tone(str):
5    """Class that represents a musical tone."""5    """Class that represents a musical tone."""
6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')6    TONES = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
77
8    def __add__(self, other):8    def __add__(self, other):
9        """Add two tones or an interval to a tone."""9        """Add two tones or an interval to a tone."""
10        if isinstance(other, Tone):10        if isinstance(other, Tone):
11            return Chord(self, other)11            return Chord(self, other)
12        if isinstance(other, Interval):12        if isinstance(other, Interval):
13            current = self.TONES.index(self)13            current = self.TONES.index(self)
14            new = self.TONES[(current + int(other)) % len(self.TONES)]14            new = self.TONES[(current + int(other)) % len(self.TONES)]
15            return Tone(new)15            return Tone(new)
1616
17    def __sub__(self, other):17    def __sub__(self, other):
18        """Subtract an interval from a tone."""18        """Subtract an interval from a tone."""
19        if isinstance(other, Tone):19        if isinstance(other, Tone):
20            raise TypeError(INVALID_OPERATION)20            raise TypeError(INVALID_OPERATION)
21        return self.__add__(-other)21        return self.__add__(-other)
2222
23    def __radd__(self, other):23    def __radd__(self, other):
24        """Raise an exception attempting right-hand addition."""24        """Raise an exception attempting right-hand addition."""
25        raise TypeError(INVALID_OPERATION)25        raise TypeError(INVALID_OPERATION)
2626
27    __rsub__ = __radd__27    __rsub__ = __radd__
2828
2929
30class Interval:30class Interval:
31    """Class that represents a musical interval."""31    """Class that represents a musical interval."""
n32    INTERVAL_NAMES = [n32    INTERVAL_NAMES = (
33        "unison",33        "unison",
34        "minor 2nd",34        "minor 2nd",
35        "major 2nd",35        "major 2nd",
36        "minor 3rd",36        "minor 3rd",
37        "major 3rd",37        "major 3rd",
38        "perfect 4th",38        "perfect 4th",
39        "diminished 5th",39        "diminished 5th",
40        "perfect 5th",40        "perfect 5th",
41        "minor 6th",41        "minor 6th",
42        "major 6th",42        "major 6th",
43        "minor 7th",43        "minor 7th",
44        "major 7th"44        "major 7th"
n45    ]n45    )
46    TOTAL_INTERVALS = len(INTERVAL_NAMES)
4746
48    def __init__(self, value):47    def __init__(self, value):
49        """Save the normalized initialization value for the interval."""48        """Save the normalized initialization value for the interval."""
t50        self._value = value % self.TOTAL_INTERVALSt49        self._value = value % len(self.INTERVAL_NAMES)
5150
52    def __str__(self):51    def __str__(self):
53        return self.INTERVAL_NAMES[self._value]52        return self.INTERVAL_NAMES[self._value]
5453
55    def __add__(self, other):54    def __add__(self, other):
56        """Add two intervals or raise an error if adding anything else to an interval."""55        """Add two intervals or raise an error if adding anything else to an interval."""
57        if isinstance(other, Interval):56        if isinstance(other, Interval):
58            return Interval(self._value + other._value)57            return Interval(self._value + other._value)
59        raise TypeError(INVALID_OPERATION)58        raise TypeError(INVALID_OPERATION)
6059
61    def __neg__(self):60    def __neg__(self):
62        return Interval(-self._value)61        return Interval(-self._value)
6362
64    def __int__(self):63    def __int__(self):
65        return self._value64        return self._value
6665
6766
68class Chord:67class Chord:
69    """Class that represents a musical chord."""68    """Class that represents a musical chord."""
70    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"69    CANNOT_CHORD_CHORD_MESSAGE = "Cannot have a chord made of only 1 unique tone"
71    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"70    CANNOT_REMOVE_TONE_MESSAGE = "Cannot remove tone {0} from chord {1}"
7271
73    def __init__(self, *notes):72    def __init__(self, *notes):
74        """Leave only unique notes and sort relative to the root."""73        """Leave only unique notes and sort relative to the root."""
75        root = notes[0]74        root = notes[0]
76        unique_and_sorted = sorted(list(set(notes)))75        unique_and_sorted = sorted(list(set(notes)))
77        root_index = unique_and_sorted.index(root)76        root_index = unique_and_sorted.index(root)
78        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]77        unique_and_sorted = unique_and_sorted[root_index:] + unique_and_sorted[:root_index]
79        if len(unique_and_sorted) <= 1:78        if len(unique_and_sorted) <= 1:
80            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)79            raise TypeError(self.CANNOT_CHORD_CHORD_MESSAGE)
81        self.notes = unique_and_sorted80        self.notes = unique_and_sorted
8281
83    def __str__(self):82    def __str__(self):
84        return "-".join(self.notes)83        return "-".join(self.notes)
8584
86    def __add__(self, other):85    def __add__(self, other):
87        """Add a tone to a chord."""86        """Add a tone to a chord."""
88        if isinstance(other, Tone):87        if isinstance(other, Tone):
89            return Chord(*self.notes, other)88            return Chord(*self.notes, other)
9089
91    def __sub__(self, other):90    def __sub__(self, other):
92        """Remove a tone from a chord if possible."""91        """Remove a tone from a chord if possible."""
93        if isinstance(other, Tone):92        if isinstance(other, Tone):
94            if other not in self.notes:93            if other not in self.notes:
95                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))94                raise TypeError(self.CANNOT_REMOVE_TONE_MESSAGE.format(other, self))
96            return Chord(*[note for note in self.notes if note != other])95            return Chord(*[note for note in self.notes if note != other])
9796
98    def is_minor(self):97    def is_minor(self):
99        """Determine the age of the chord."""98        """Determine the age of the chord."""
100        return (Tone(self.notes[0]) + Interval(3)) in self.notes99        return (Tone(self.notes[0]) + Interval(3)) in self.notes
101100
102    def is_major(self):101    def is_major(self):
103        """Determine the military rank of the chord."""102        """Determine the military rank of the chord."""
104        return (Tone(self.notes[0]) + Interval(4)) in self.notes103        return (Tone(self.notes[0]) + Interval(4)) in self.notes
105104
106    def is_power_chord(self):105    def is_power_chord(self):
107        """Determine the strenght of the chord."""106        """Determine the strenght of the chord."""
108        return not (self.is_minor() or self.is_major())107        return not (self.is_minor() or self.is_major())
109108
110    def transposed(self, interval):109    def transposed(self, interval):
111        """Return a new chord with different tones, I'm tired of docstrings."""110        """Return a new chord with different tones, I'm tired of docstrings."""
112        new_notes = [note+interval for note in self.notes]111        new_notes = [note+interval for note in self.notes]
113        return Chord(*new_notes)112        return Chord(*new_notes)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op