-
Notifications
You must be signed in to change notification settings - Fork 0
/
scale.py
104 lines (85 loc) · 3.66 KB
/
scale.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from .note import Note
from .scale_types import types_of_scales
class Scale:
def __init__(self, scale_type="custom", start_note="", list_of_notes=None):
if scale_type != "custom":
self.start_note = Note(start_note) if isinstance(start_note, str) else start_note
try:
self.scale_type = scale_type
self.scale_intervals = types_of_scales[scale_type]
except KeyError:
raise Exception("Scale \"{}\" does not exist. Here is a list of all the possible chords:\n{}"
.format(scale_type, types_of_scales.keys())) from None
self.scale = [self.start_note + interval for interval in self.scale_intervals]
else:
if list_of_notes is None:
list_of_notes = []
self.scale = []
for note in list_of_notes:
if isinstance(note, str):
self.scale.append(Note(note))
elif isinstance(note, Note):
self.scale.append(note)
else:
raise Exception("{} is of incorrect type. Must be a Note/str object.".format(note))
self.scale_type = scale_type
self.start_note = self.scale[0]
self.last_note = self.scale[-1]
def __contains__(self, item):
if isinstance(item, Note):
return item in self.scale
elif isinstance(item, str):
return Note(item) in self.scale
else:
raise Exception("{} is of incorrect type. Must be str or Note, not {}".format(item, type(item)))
def __iter__(self):
return iter(self.scale)
def __getitem__(self, i):
return self.scale[i]
def __delitem__(self, i):
del self.scale[i]
def __setitem__(self, i, val):
# optional: self._acl_check(val)
self.scale[i] = val
def insert(self, i, val):
# optional: self._acl_check(val)
self.scale.insert(i, val)
def append(self, val):
self.insert(len(self.scale), val)
def __eq__(self, other):
if isinstance(other, Scale):
return self.scale == other.scale
else:
raise Exception("{} is of incorrect type. Must be a Scale object.".format(other))
def __ne__(self, other):
if isinstance(other, Scale):
return self.scale != other.scale
else:
raise Exception("{} is of incorrect type. Must be a Scale object.".format(other))
def __gt__(self, other):
if isinstance(other, Scale):
return self.last_note.number > other.last_note.number
else:
raise Exception("{} is of incorrect type. Must be a Scale object.".format(other))
def __lt__(self, other):
if isinstance(other, Scale):
return self.last_note.number < other.last_note.number
else:
raise Exception("{} is of incorrect type. Must be a Scale object.".format(other))
def __ge__(self, other):
if isinstance(other, Scale):
return self.last_note.number >= other.last_note.number
else:
raise Exception("{} is of incorrect type. Must be a Scale object.".format(other))
def __le__(self, other):
if isinstance(other, Scale):
return self.last_note.number <= other.last_note.number
else:
raise Exception("{} is of incorrect type. Must be a Scale object.".format(other))
def __len__(self):
return len(self.scale)
def __str__(self):
return "Scale(" + str(self.scale) + ")"
def __repr__(self):
# return "<{} {}>".format(self.__class__.__name__, self.scale)
return self.__str__()