Домашни > Pitches love the D > Решения > Решението на Дейвид Барух

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

9 точки общо

32 успешни теста
5 неуспешни теста
Код (Последна версия XD наистина)

  1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
  2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
  3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]
  4MAX_INDEX = 12
  5
  6class Tone:
  7    def __init__(self, name):
  8        self.name = name
  9    
 10    def __str__(self):
 11        return self.name
 12    
 13    def __add__(self, other):
 14        if isinstance(other, Tone):
 15            return Chord(self, other)
 16        if isinstance(other, Interval):
 17            total_len = other.lenght + self.index
 18            correct_index = int(total_len / MAX_INDEX)
 19            correct_len = total_len - correct_index*MAX_INDEX
 20            return Tone(TONE_VALUE_LIST[correct_len])
 21    
 22    def __sub__(self, other):
 23        if isinstance(other, Tone):
 24            len = self.index - other.index
 25            if self.index < other.index:
 26                len = self.index + MAX_INDEX - other.index
 27            return Interval(len)
 28        if isinstance(other, Interval):
 29            wanted_index = self.index - other.lenght
 30            if self.index < other.lenght:
 31                wanted_index = self.index - other.lenght + MAX_INDEX
 32            return TONE_VALUE_LIST[wanted_index]
 33    
 34    @property
 35    def index(self):
 36        return TONE_INDEX_DICT[self.name]
 37    
 38class Interval:
 39    def __init__(self, lenght):
 40        correct_index = int(lenght / MAX_INDEX)
 41        self.lenght = lenght - correct_index*MAX_INDEX
 42
 43    def __str__(self):
 44        return INTERVAL_VALUE_LIST[self.lenght]
 45    
 46    def __add__(self,other):
 47        if isinstance(other,Tone):
 48            raise TypeError("Invalid operation")
 49        if isinstance(other,Interval):
 50            total_len = self.lenght + other.lenght
 51            correct_index = int(total_len / MAX_INDEX)
 52            correct_len = total_len - correct_index*MAX_INDEX
 53            return INTERVAL_VALUE_LIST[correct_len]
 54        
 55    def __sub__(self,other):
 56        if isinstance(other,Tone):
 57            raise TypeError("Invalid operation")
 58        
 59    def __neg__(self):
 60        return Interval(MAX_INDEX - self.lenght)
 61
 62class Chord:
 63    def __init_sorted_tones(self):
 64        main_index = self.main_tone.index
 65        tones_dict = {self.main_tone.name : main_index}
 66        self.all_tones_list_objs = [self.main_tone]
 67        for tone_name in self.unique_tones:
 68            tone_index = Tone(tone_name).index
 69            self.without_main_tones_list_objs.append(Tone(tone_name))
 70            self.all_tones_list_objs.append(Tone(tone_name))
 71            if main_index > tone_index:
 72                tones_dict[tone_name] = tone_index + MAX_INDEX
 73            else:
 74                tones_dict[tone_name] = tone_index
 75        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
 76
 77    def __init__(self, main_tone, *tones):
 78        self.main_tone = main_tone
 79        self.unique_tones= set()
 80        self.sorted_tones = []
 81        self.all_tones_list_objs = []
 82        self.without_main_tones_list_objs = []
 83        self.unique_tones.add(main_tone.name)
 84        for tone in tones:
 85            self.unique_tones.add(tone.name)            
 86        valid_len = len(self.unique_tones)
 87        if valid_len <= 1:
 88            raise TypeError("Cannot have a chord made of only 1 unique tone")
 89        self.unique_tones.discard(main_tone.name)
 90        self.__init_sorted_tones()
 91        
 92    def __add__(self, other):
 93        new_tones = self.without_main_tones_list_objs
 94        if isinstance(other, Tone):
 95            new_tones.append(other)
 96        if isinstance(other,Chord):
 97            for tone in other.all_tones_list_objs:
 98                new_tones.append(tone)
 99        return Chord(self.main_tone, *new_tones)
100
101    def __sub__(self, other):
102        if other.name not in self.sorted_tones:
103            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
104        if len(self.unique_tones) < 2:
105            raise TypeError("Cannot have a chord made of only 1 unique tone")
106        new_tones = self.without_main_tones_list_objs
107        main_tone = self.main_tone
108        if isinstance(other, Tone):
109            if main_tone.name == other.name:
110                main_tone = self.without_main_tones_list_objs[0]
111                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)
112            else:
113                new_tones = filter(lambda tone: tone.name != other.name, new_tones)
114        return Chord(main_tone, *new_tones)      
115
116    def __str__(self):    
117        return "-".join(self.sorted_tones)
118    
119    def is_minor(self):
120        for tone in self.without_main_tones_list_objs:
121            interval = tone - self.main_tone
122            if str(interval) == "minor 3rd":
123                return True
124        return False
125    
126    def is_major(self):
127        for tone in self.without_main_tones_list_objs:
128            interval = tone - self.main_tone
129            if str(interval) == "major 3rd":
130                return True
131        return False
132    
133    def is_power_chord(self):
134        return not self.is_major() and not self.is_minor() 
135    
136    def transposed(self, interval):
137        transposed_tones = [tone + interval for tone in self.all_tones_list_objs]
138        return Chord(transposed_tones[0], *transposed_tones[1:])

........................FFF.FF.......
======================================================================
FAIL: test_interval_addition (test.TestOperations.test_interval_addition)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 240, in test_interval_addition
self.assertIsInstance(major_3rd, Interval)
AssertionError: 'major 3rd' is not an instance of <class 'solution.Interval'>

======================================================================
FAIL: test_interval_addition_overflow (test.TestOperations.test_interval_addition_overflow)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 246, in test_interval_addition_overflow
self.assertIsInstance(unison, Interval)
AssertionError: 'unison' is not an instance of <class 'solution.Interval'>

======================================================================
FAIL: test_subtract_interval_from_tone (test.TestOperations.test_subtract_interval_from_tone)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 216, in test_subtract_interval_from_tone
self.assertIsInstance(f_sharp, Tone)
AssertionError: 'F#' is not an instance of <class 'solution.Tone'>

======================================================================
FAIL: test_subtract_interval_from_tone_oveflow (test.TestOperations.test_subtract_interval_from_tone_oveflow)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 228, in test_subtract_interval_from_tone_oveflow
self.assertIsInstance(g, Tone)
AssertionError: 'G' is not an instance of <class 'solution.Tone'>

======================================================================
FAIL: test_subtract_interval_from_tone_same_tone (test.TestOperations.test_subtract_interval_from_tone_same_tone)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 222, in test_subtract_interval_from_tone_same_tone
self.assertIsInstance(still_g, Tone)
AssertionError: 'G' is not an instance of <class 'solution.Tone'>

----------------------------------------------------------------------
Ran 37 tests in 0.002s

FAILED (failures=5)

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

Търсим интервалът между двата, релативен спрямо основния тон. Как ще го имплементираш зависи от теб, но `tone - main_tone` ми звучи правилно.
Дейвид Барух
05.11.2024 22:28

Един последен дразнещ въпрос, при мажорите вадим от тона roota нали, за да намерим разстоянитето между тях . Демек (tone - main_tone)
Дейвид Барух
05.11.2024 16:08

Да разбрах на обратно от мойте разбирания е. Разстоянието примерно А-С е разстоянието между С и А
Виктор Бечев
05.11.2024 15:24

Добре, разбирам от къде идва объркването. Все пак - спазвай примера от по-долу, където съм ти дал за `A-C` и `C-A`. Приеми го за аксиома, ако го смяташ за неинтуитивно.
Дейвид Барух
05.11.2024 11:06

Не сър на примера не е C -G 😂😂 a e G -C демек от G до C e g#,a,a#,b,c, поне аз схващам че G-C e разстоянието от G до C освен ако не визирате обратното
Виктор Бечев
05.11.2024 10:32

![](https://py-fmi.org/media/resources/chromatic-scale_edited.png) - 0 - unison - 1 - minor 2nd - 2 - major 2nd - 3 - minor 3rd - 4 - major 3rd - 5 - perfect 4th - 6 - diminished 5th - **7 - perfect 5th** - 8 - minor 6th - 9 - major 6th - 10 - minor 7th - 11 - major 7th
Дейвид Барух
05.11.2024 00:06

е то на примера е G-C сър, c, g = Tone("C"), Tone("G"); interval = g - c, трябва да е perfect 4th
Виктор Бечев
04.11.2024 23:00

Полутоновете между G и C са 5. Между C и G са 7. Ако си представиш, че всеки тон си има индекс, ако C е с индекс 0, то G би било с индекс 7. `g - c` -> 7. 7 полутона разстояние е `"perfect 5th"`.
Дейвид Барух
04.11.2024 18:14

тук не е ли perfect 4th защото полутоновете между C и G са 5 : c, g = Tone("C"), Tone("G") result_interval = g - c # result_interval е обект от тип Interval print(result_interval) "perfect 5th"
Виктор Бечев
04.11.2024 18:11

Да. Но с посока, а не абсолютна стойност. Затова между A и C имаме 3 полутона, а между C и A - 9. Ако говорим за операция изваждане - `A-C=9`, `C-A=3`.
Дейвид Барух
04.11.2024 17:12

Извинявай, но се обърках малко. Разстоянието(боря полутонове) между два тона е разликата им нали?
Виктор Бечев
04.11.2024 16:14

Имаме цикличност, но имаме и релативност спрямо основния тон. Разстоянието между A и C е 3 полутона _(A#, B, C)_, но между C и А _(в случай, когато root е C)_ - 9 полутона. С други думи за F#-D-E имаме 8 полутона между F# и D.
Дейвид Барух
04.11.2024 15:45

демек така както го правя сега е грешно?
Дейвид Барух
04.11.2024 15:43

и за разлика на тонове приерно А-C ще се даде 2 не 9 , защото си поддържаме цикличност?
Дейвид Барух
04.11.2024 15:38

за ismajor и isminor ако имаме нещо от сорта F#-D-E , то тогава за разстоянието между F# и D примерно приемаме че имаме 4 или 9 демек да се продължваме по цикъла един вид ?
Виктор Бечев
03.11.2024 21:19

Да, интервалите са циклични.
Дейвид Барух
03.11.2024 14:21

За интервалите имали също цикличност примерно за последния пример да дадем : d_minor_chord = c_minor_chord.transposed(Interval(20)) то да се приеме като Interval(8)?
История

f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]
4MAX_INDEX = 124MAX_INDEX = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self.name = name8        self.name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return self.name11        return self.name
12    12    
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other, Tone):14        if isinstance(other, Tone):
15            return Chord(self, other)15            return Chord(self, other)
16        if isinstance(other, Interval):16        if isinstance(other, Interval):
17            total_len = other.lenght + self.index17            total_len = other.lenght + self.index
18            correct_index = int(total_len / MAX_INDEX)18            correct_index = int(total_len / MAX_INDEX)
19            correct_len = total_len - correct_index*MAX_INDEX19            correct_len = total_len - correct_index*MAX_INDEX
20            return Tone(TONE_VALUE_LIST[correct_len])20            return Tone(TONE_VALUE_LIST[correct_len])
21    21    
22    def __sub__(self, other):22    def __sub__(self, other):
23        if isinstance(other, Tone):23        if isinstance(other, Tone):
n24            # len = other.index - self.indexn
25            # if self.index > other.index:
26            #     len = other.index + MAX_INDEX - self.index
27            # return Interval(len)
28            len = self.index - other.index24            len = self.index - other.index
29            if self.index < other.index:25            if self.index < other.index:
30                len = self.index + MAX_INDEX - other.index26                len = self.index + MAX_INDEX - other.index
31            return Interval(len)27            return Interval(len)
32        if isinstance(other, Interval):28        if isinstance(other, Interval):
33            wanted_index = self.index - other.lenght29            wanted_index = self.index - other.lenght
34            if self.index < other.lenght:30            if self.index < other.lenght:
35                wanted_index = self.index - other.lenght + MAX_INDEX31                wanted_index = self.index - other.lenght + MAX_INDEX
36            return TONE_VALUE_LIST[wanted_index]32            return TONE_VALUE_LIST[wanted_index]
37    33    
38    @property34    @property
39    def index(self):35    def index(self):
40        return TONE_INDEX_DICT[self.name]36        return TONE_INDEX_DICT[self.name]
41    37    
42class Interval:38class Interval:
43    def __init__(self, lenght):39    def __init__(self, lenght):
44        correct_index = int(lenght / MAX_INDEX)40        correct_index = int(lenght / MAX_INDEX)
45        self.lenght = lenght - correct_index*MAX_INDEX41        self.lenght = lenght - correct_index*MAX_INDEX
4642
47    def __str__(self):43    def __str__(self):
t48        print(f"len is {self.lenght}")t
49        return INTERVAL_VALUE_LIST[self.lenght]44        return INTERVAL_VALUE_LIST[self.lenght]
50    45    
51    def __add__(self,other):46    def __add__(self,other):
52        if isinstance(other,Tone):47        if isinstance(other,Tone):
53            raise TypeError("Invalid operation")48            raise TypeError("Invalid operation")
54        if isinstance(other,Interval):49        if isinstance(other,Interval):
55            total_len = self.lenght + other.lenght50            total_len = self.lenght + other.lenght
56            correct_index = int(total_len / MAX_INDEX)51            correct_index = int(total_len / MAX_INDEX)
57            correct_len = total_len - correct_index*MAX_INDEX52            correct_len = total_len - correct_index*MAX_INDEX
58            return INTERVAL_VALUE_LIST[correct_len]53            return INTERVAL_VALUE_LIST[correct_len]
59        54        
60    def __sub__(self,other):55    def __sub__(self,other):
61        if isinstance(other,Tone):56        if isinstance(other,Tone):
62            raise TypeError("Invalid operation")57            raise TypeError("Invalid operation")
63        58        
64    def __neg__(self):59    def __neg__(self):
65        return Interval(MAX_INDEX - self.lenght)60        return Interval(MAX_INDEX - self.lenght)
6661
67class Chord:62class Chord:
68    def __init_sorted_tones(self):63    def __init_sorted_tones(self):
69        main_index = self.main_tone.index64        main_index = self.main_tone.index
70        tones_dict = {self.main_tone.name : main_index}65        tones_dict = {self.main_tone.name : main_index}
71        self.all_tones_list_objs = [self.main_tone]66        self.all_tones_list_objs = [self.main_tone]
72        for tone_name in self.unique_tones:67        for tone_name in self.unique_tones:
73            tone_index = Tone(tone_name).index68            tone_index = Tone(tone_name).index
74            self.without_main_tones_list_objs.append(Tone(tone_name))69            self.without_main_tones_list_objs.append(Tone(tone_name))
75            self.all_tones_list_objs.append(Tone(tone_name))70            self.all_tones_list_objs.append(Tone(tone_name))
76            if main_index > tone_index:71            if main_index > tone_index:
77                tones_dict[tone_name] = tone_index + MAX_INDEX72                tones_dict[tone_name] = tone_index + MAX_INDEX
78            else:73            else:
79                tones_dict[tone_name] = tone_index74                tones_dict[tone_name] = tone_index
80        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]75        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
8176
82    def __init__(self, main_tone, *tones):77    def __init__(self, main_tone, *tones):
83        self.main_tone = main_tone78        self.main_tone = main_tone
84        self.unique_tones= set()79        self.unique_tones= set()
85        self.sorted_tones = []80        self.sorted_tones = []
86        self.all_tones_list_objs = []81        self.all_tones_list_objs = []
87        self.without_main_tones_list_objs = []82        self.without_main_tones_list_objs = []
88        self.unique_tones.add(main_tone.name)83        self.unique_tones.add(main_tone.name)
89        for tone in tones:84        for tone in tones:
90            self.unique_tones.add(tone.name)            85            self.unique_tones.add(tone.name)            
91        valid_len = len(self.unique_tones)86        valid_len = len(self.unique_tones)
92        if valid_len <= 1:87        if valid_len <= 1:
93            raise TypeError("Cannot have a chord made of only 1 unique tone")88            raise TypeError("Cannot have a chord made of only 1 unique tone")
94        self.unique_tones.discard(main_tone.name)89        self.unique_tones.discard(main_tone.name)
95        self.__init_sorted_tones()90        self.__init_sorted_tones()
96        91        
97    def __add__(self, other):92    def __add__(self, other):
98        new_tones = self.without_main_tones_list_objs93        new_tones = self.without_main_tones_list_objs
99        if isinstance(other, Tone):94        if isinstance(other, Tone):
100            new_tones.append(other)95            new_tones.append(other)
101        if isinstance(other,Chord):96        if isinstance(other,Chord):
102            for tone in other.all_tones_list_objs:97            for tone in other.all_tones_list_objs:
103                new_tones.append(tone)98                new_tones.append(tone)
104        return Chord(self.main_tone, *new_tones)99        return Chord(self.main_tone, *new_tones)
105100
106    def __sub__(self, other):101    def __sub__(self, other):
107        if other.name not in self.sorted_tones:102        if other.name not in self.sorted_tones:
108            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")103            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
109        if len(self.unique_tones) < 2:104        if len(self.unique_tones) < 2:
110            raise TypeError("Cannot have a chord made of only 1 unique tone")105            raise TypeError("Cannot have a chord made of only 1 unique tone")
111        new_tones = self.without_main_tones_list_objs106        new_tones = self.without_main_tones_list_objs
112        main_tone = self.main_tone107        main_tone = self.main_tone
113        if isinstance(other, Tone):108        if isinstance(other, Tone):
114            if main_tone.name == other.name:109            if main_tone.name == other.name:
115                main_tone = self.without_main_tones_list_objs[0]110                main_tone = self.without_main_tones_list_objs[0]
116                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)111                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)
117            else:112            else:
118                new_tones = filter(lambda tone: tone.name != other.name, new_tones)113                new_tones = filter(lambda tone: tone.name != other.name, new_tones)
119        return Chord(main_tone, *new_tones)      114        return Chord(main_tone, *new_tones)      
120115
121    def __str__(self):    116    def __str__(self):    
122        return "-".join(self.sorted_tones)117        return "-".join(self.sorted_tones)
123    118    
124    def is_minor(self):119    def is_minor(self):
125        for tone in self.without_main_tones_list_objs:120        for tone in self.without_main_tones_list_objs:
126            interval = tone - self.main_tone121            interval = tone - self.main_tone
127            if str(interval) == "minor 3rd":122            if str(interval) == "minor 3rd":
128                return True123                return True
129        return False124        return False
130    125    
131    def is_major(self):126    def is_major(self):
132        for tone in self.without_main_tones_list_objs:127        for tone in self.without_main_tones_list_objs:
133            interval = tone - self.main_tone128            interval = tone - self.main_tone
134            if str(interval) == "major 3rd":129            if str(interval) == "major 3rd":
135                return True130                return True
136        return False131        return False
137    132    
138    def is_power_chord(self):133    def is_power_chord(self):
139        return not self.is_major() and not self.is_minor() 134        return not self.is_major() and not self.is_minor() 
140    135    
141    def transposed(self, interval):136    def transposed(self, interval):
142        transposed_tones = [tone + interval for tone in self.all_tones_list_objs]137        transposed_tones = [tone + interval for tone in self.all_tones_list_objs]
143        return Chord(transposed_tones[0], *transposed_tones[1:])138        return Chord(transposed_tones[0], *transposed_tones[1:])
144139
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]
4MAX_INDEX = 124MAX_INDEX = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self.name = name8        self.name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return self.name11        return self.name
12    12    
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other, Tone):14        if isinstance(other, Tone):
15            return Chord(self, other)15            return Chord(self, other)
16        if isinstance(other, Interval):16        if isinstance(other, Interval):
17            total_len = other.lenght + self.index17            total_len = other.lenght + self.index
18            correct_index = int(total_len / MAX_INDEX)18            correct_index = int(total_len / MAX_INDEX)
19            correct_len = total_len - correct_index*MAX_INDEX19            correct_len = total_len - correct_index*MAX_INDEX
20            return Tone(TONE_VALUE_LIST[correct_len])20            return Tone(TONE_VALUE_LIST[correct_len])
21    21    
22    def __sub__(self, other):22    def __sub__(self, other):
23        if isinstance(other, Tone):23        if isinstance(other, Tone):
n24            len = other.index - self.indexn24            # len = other.index - self.index
25            if self.index > other.index:25            # if self.index > other.index:
26                print("here")
27                len = other.index + MAX_INDEX - self.index26            #     len = other.index + MAX_INDEX - self.index
27            # return Interval(len)
28            len = self.index - other.index
29            if self.index < other.index:
30                len = self.index + MAX_INDEX - other.index
28            return Interval(len)31            return Interval(len)
29        if isinstance(other, Interval):32        if isinstance(other, Interval):
30            wanted_index = self.index - other.lenght33            wanted_index = self.index - other.lenght
31            if self.index < other.lenght:34            if self.index < other.lenght:
32                wanted_index = self.index - other.lenght + MAX_INDEX35                wanted_index = self.index - other.lenght + MAX_INDEX
33            return TONE_VALUE_LIST[wanted_index]36            return TONE_VALUE_LIST[wanted_index]
34    37    
35    @property38    @property
36    def index(self):39    def index(self):
37        return TONE_INDEX_DICT[self.name]40        return TONE_INDEX_DICT[self.name]
38    41    
39class Interval:42class Interval:
40    def __init__(self, lenght):43    def __init__(self, lenght):
41        correct_index = int(lenght / MAX_INDEX)44        correct_index = int(lenght / MAX_INDEX)
42        self.lenght = lenght - correct_index*MAX_INDEX45        self.lenght = lenght - correct_index*MAX_INDEX
4346
44    def __str__(self):47    def __str__(self):
nn48        print(f"len is {self.lenght}")
45        return INTERVAL_VALUE_LIST[self.lenght]49        return INTERVAL_VALUE_LIST[self.lenght]
46    50    
47    def __add__(self,other):51    def __add__(self,other):
48        if isinstance(other,Tone):52        if isinstance(other,Tone):
49            raise TypeError("Invalid operation")53            raise TypeError("Invalid operation")
50        if isinstance(other,Interval):54        if isinstance(other,Interval):
51            total_len = self.lenght + other.lenght55            total_len = self.lenght + other.lenght
52            correct_index = int(total_len / MAX_INDEX)56            correct_index = int(total_len / MAX_INDEX)
53            correct_len = total_len - correct_index*MAX_INDEX57            correct_len = total_len - correct_index*MAX_INDEX
54            return INTERVAL_VALUE_LIST[correct_len]58            return INTERVAL_VALUE_LIST[correct_len]
55        59        
56    def __sub__(self,other):60    def __sub__(self,other):
57        if isinstance(other,Tone):61        if isinstance(other,Tone):
58            raise TypeError("Invalid operation")62            raise TypeError("Invalid operation")
59        63        
60    def __neg__(self):64    def __neg__(self):
61        return Interval(MAX_INDEX - self.lenght)65        return Interval(MAX_INDEX - self.lenght)
6266
63class Chord:67class Chord:
64    def __init_sorted_tones(self):68    def __init_sorted_tones(self):
65        main_index = self.main_tone.index69        main_index = self.main_tone.index
66        tones_dict = {self.main_tone.name : main_index}70        tones_dict = {self.main_tone.name : main_index}
67        self.all_tones_list_objs = [self.main_tone]71        self.all_tones_list_objs = [self.main_tone]
68        for tone_name in self.unique_tones:72        for tone_name in self.unique_tones:
69            tone_index = Tone(tone_name).index73            tone_index = Tone(tone_name).index
70            self.without_main_tones_list_objs.append(Tone(tone_name))74            self.without_main_tones_list_objs.append(Tone(tone_name))
71            self.all_tones_list_objs.append(Tone(tone_name))75            self.all_tones_list_objs.append(Tone(tone_name))
72            if main_index > tone_index:76            if main_index > tone_index:
73                tones_dict[tone_name] = tone_index + MAX_INDEX77                tones_dict[tone_name] = tone_index + MAX_INDEX
74            else:78            else:
75                tones_dict[tone_name] = tone_index79                tones_dict[tone_name] = tone_index
76        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]80        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
7781
78    def __init__(self, main_tone, *tones):82    def __init__(self, main_tone, *tones):
79        self.main_tone = main_tone83        self.main_tone = main_tone
80        self.unique_tones= set()84        self.unique_tones= set()
81        self.sorted_tones = []85        self.sorted_tones = []
82        self.all_tones_list_objs = []86        self.all_tones_list_objs = []
83        self.without_main_tones_list_objs = []87        self.without_main_tones_list_objs = []
84        self.unique_tones.add(main_tone.name)88        self.unique_tones.add(main_tone.name)
85        for tone in tones:89        for tone in tones:
86            self.unique_tones.add(tone.name)            90            self.unique_tones.add(tone.name)            
87        valid_len = len(self.unique_tones)91        valid_len = len(self.unique_tones)
88        if valid_len <= 1:92        if valid_len <= 1:
89            raise TypeError("Cannot have a chord made of only 1 unique tone")93            raise TypeError("Cannot have a chord made of only 1 unique tone")
90        self.unique_tones.discard(main_tone.name)94        self.unique_tones.discard(main_tone.name)
91        self.__init_sorted_tones()95        self.__init_sorted_tones()
92        96        
93    def __add__(self, other):97    def __add__(self, other):
94        new_tones = self.without_main_tones_list_objs98        new_tones = self.without_main_tones_list_objs
95        if isinstance(other, Tone):99        if isinstance(other, Tone):
96            new_tones.append(other)100            new_tones.append(other)
97        if isinstance(other,Chord):101        if isinstance(other,Chord):
98            for tone in other.all_tones_list_objs:102            for tone in other.all_tones_list_objs:
99                new_tones.append(tone)103                new_tones.append(tone)
100        return Chord(self.main_tone, *new_tones)104        return Chord(self.main_tone, *new_tones)
101105
102    def __sub__(self, other):106    def __sub__(self, other):
103        if other.name not in self.sorted_tones:107        if other.name not in self.sorted_tones:
104            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")108            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
105        if len(self.unique_tones) < 2:109        if len(self.unique_tones) < 2:
106            raise TypeError("Cannot have a chord made of only 1 unique tone")110            raise TypeError("Cannot have a chord made of only 1 unique tone")
107        new_tones = self.without_main_tones_list_objs111        new_tones = self.without_main_tones_list_objs
108        main_tone = self.main_tone112        main_tone = self.main_tone
109        if isinstance(other, Tone):113        if isinstance(other, Tone):
110            if main_tone.name == other.name:114            if main_tone.name == other.name:
111                main_tone = self.without_main_tones_list_objs[0]115                main_tone = self.without_main_tones_list_objs[0]
112                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)116                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)
113            else:117            else:
114                new_tones = filter(lambda tone: tone.name != other.name, new_tones)118                new_tones = filter(lambda tone: tone.name != other.name, new_tones)
115        return Chord(main_tone, *new_tones)      119        return Chord(main_tone, *new_tones)      
116120
117    def __str__(self):    121    def __str__(self):    
118        return "-".join(self.sorted_tones)122        return "-".join(self.sorted_tones)
119    123    
120    def is_minor(self):124    def is_minor(self):
121        for tone in self.without_main_tones_list_objs:125        for tone in self.without_main_tones_list_objs:
n122            interval = self.main_tone - tonen126            interval = tone - self.main_tone
123            if str(interval) == "minor 3rd":127            if str(interval) == "minor 3rd":
124                return True128                return True
125        return False129        return False
126    130    
127    def is_major(self):131    def is_major(self):
128        for tone in self.without_main_tones_list_objs:132        for tone in self.without_main_tones_list_objs:
t129            interval = self.main_tone - tonet133            interval = tone - self.main_tone
130            if str(interval) == "major 3rd":134            if str(interval) == "major 3rd":
131                return True135                return True
132        return False136        return False
133    137    
134    def is_power_chord(self):138    def is_power_chord(self):
135        return not self.is_major() and not self.is_minor() 139        return not self.is_major() and not self.is_minor() 
136    140    
137    def transposed(self, interval):141    def transposed(self, interval):
138        transposed_tones = [tone + interval for tone in self.all_tones_list_objs]142        transposed_tones = [tone + interval for tone in self.all_tones_list_objs]
139        return Chord(transposed_tones[0], *transposed_tones[1:])143        return Chord(transposed_tones[0], *transposed_tones[1:])
140144
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]
4MAX_INDEX = 124MAX_INDEX = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self.name = name8        self.name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return self.name11        return self.name
12    12    
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other, Tone):14        if isinstance(other, Tone):
15            return Chord(self, other)15            return Chord(self, other)
16        if isinstance(other, Interval):16        if isinstance(other, Interval):
n17            total_len = other.lenght + TONE_INDEX_DICT[self.name]n17            total_len = other.lenght + self.index
18            correct_index = int(total_len / MAX_INDEX)18            correct_index = int(total_len / MAX_INDEX)
19            correct_len = total_len - correct_index*MAX_INDEX19            correct_len = total_len - correct_index*MAX_INDEX
20            return Tone(TONE_VALUE_LIST[correct_len])20            return Tone(TONE_VALUE_LIST[correct_len])
21    21    
22    def __sub__(self, other):22    def __sub__(self, other):
23        if isinstance(other, Tone):23        if isinstance(other, Tone):
n24            return Interval(abs(self.index - other.index))n24            len = other.index - self.index
25            if self.index > other.index:
26                print("here")
27                len = other.index + MAX_INDEX - self.index
28            return Interval(len)
25        if isinstance(other, Interval):29        if isinstance(other, Interval):
n26            cur_index = TONE_INDEX_DICT[self.name]n30            wanted_index = self.index - other.lenght
31            if self.index < other.lenght:
27            wanted_index = cur_index - other.lenght + MAX_INDEX32                wanted_index = self.index - other.lenght + MAX_INDEX
28            return TONE_VALUE_LIST[wanted_index]33            return TONE_VALUE_LIST[wanted_index]
29    34    
30    @property35    @property
31    def index(self):36    def index(self):
32        return TONE_INDEX_DICT[self.name]37        return TONE_INDEX_DICT[self.name]
33    38    
34class Interval:39class Interval:
35    def __init__(self, lenght):40    def __init__(self, lenght):
36        correct_index = int(lenght / MAX_INDEX)41        correct_index = int(lenght / MAX_INDEX)
37        self.lenght = lenght - correct_index*MAX_INDEX42        self.lenght = lenght - correct_index*MAX_INDEX
3843
39    def __str__(self):44    def __str__(self):
40        return INTERVAL_VALUE_LIST[self.lenght]45        return INTERVAL_VALUE_LIST[self.lenght]
41    46    
42    def __add__(self,other):47    def __add__(self,other):
43        if isinstance(other,Tone):48        if isinstance(other,Tone):
44            raise TypeError("Invalid operation")49            raise TypeError("Invalid operation")
45        if isinstance(other,Interval):50        if isinstance(other,Interval):
46            total_len = self.lenght + other.lenght51            total_len = self.lenght + other.lenght
47            correct_index = int(total_len / MAX_INDEX)52            correct_index = int(total_len / MAX_INDEX)
48            correct_len = total_len - correct_index*MAX_INDEX53            correct_len = total_len - correct_index*MAX_INDEX
49            return INTERVAL_VALUE_LIST[correct_len]54            return INTERVAL_VALUE_LIST[correct_len]
50        55        
51    def __sub__(self,other):56    def __sub__(self,other):
52        if isinstance(other,Tone):57        if isinstance(other,Tone):
53            raise TypeError("Invalid operation")58            raise TypeError("Invalid operation")
54        59        
55    def __neg__(self):60    def __neg__(self):
56        return Interval(MAX_INDEX - self.lenght)61        return Interval(MAX_INDEX - self.lenght)
5762
58class Chord:63class Chord:
59    def __init_sorted_tones(self):64    def __init_sorted_tones(self):
60        main_index = self.main_tone.index65        main_index = self.main_tone.index
61        tones_dict = {self.main_tone.name : main_index}66        tones_dict = {self.main_tone.name : main_index}
62        self.all_tones_list_objs = [self.main_tone]67        self.all_tones_list_objs = [self.main_tone]
63        for tone_name in self.unique_tones:68        for tone_name in self.unique_tones:
64            tone_index = Tone(tone_name).index69            tone_index = Tone(tone_name).index
65            self.without_main_tones_list_objs.append(Tone(tone_name))70            self.without_main_tones_list_objs.append(Tone(tone_name))
66            self.all_tones_list_objs.append(Tone(tone_name))71            self.all_tones_list_objs.append(Tone(tone_name))
67            if main_index > tone_index:72            if main_index > tone_index:
68                tones_dict[tone_name] = tone_index + MAX_INDEX73                tones_dict[tone_name] = tone_index + MAX_INDEX
69            else:74            else:
70                tones_dict[tone_name] = tone_index75                tones_dict[tone_name] = tone_index
71        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]76        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
7277
73    def __init__(self, main_tone, *tones):78    def __init__(self, main_tone, *tones):
74        self.main_tone = main_tone79        self.main_tone = main_tone
75        self.unique_tones= set()80        self.unique_tones= set()
76        self.sorted_tones = []81        self.sorted_tones = []
77        self.all_tones_list_objs = []82        self.all_tones_list_objs = []
78        self.without_main_tones_list_objs = []83        self.without_main_tones_list_objs = []
79        self.unique_tones.add(main_tone.name)84        self.unique_tones.add(main_tone.name)
80        for tone in tones:85        for tone in tones:
81            self.unique_tones.add(tone.name)            86            self.unique_tones.add(tone.name)            
82        valid_len = len(self.unique_tones)87        valid_len = len(self.unique_tones)
83        if valid_len <= 1:88        if valid_len <= 1:
84            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")
85        self.unique_tones.discard(main_tone.name)90        self.unique_tones.discard(main_tone.name)
86        self.__init_sorted_tones()91        self.__init_sorted_tones()
87        92        
88    def __add__(self, other):93    def __add__(self, other):
89        new_tones = self.without_main_tones_list_objs94        new_tones = self.without_main_tones_list_objs
90        if isinstance(other, Tone):95        if isinstance(other, Tone):
91            new_tones.append(other)96            new_tones.append(other)
92        if isinstance(other,Chord):97        if isinstance(other,Chord):
93            for tone in other.all_tones_list_objs:98            for tone in other.all_tones_list_objs:
94                new_tones.append(tone)99                new_tones.append(tone)
95        return Chord(self.main_tone, *new_tones)100        return Chord(self.main_tone, *new_tones)
96101
97    def __sub__(self, other):102    def __sub__(self, other):
98        if other.name not in self.sorted_tones:103        if other.name not in self.sorted_tones:
99            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")104            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
100        if len(self.unique_tones) < 2:105        if len(self.unique_tones) < 2:
101            raise TypeError("Cannot have a chord made of only 1 unique tone")106            raise TypeError("Cannot have a chord made of only 1 unique tone")
n102        new_tones = self.all_tones_list_objsn107        new_tones = self.without_main_tones_list_objs
103        main_tone = self.main_tone108        main_tone = self.main_tone
104        if isinstance(other, Tone):109        if isinstance(other, Tone):
105            if main_tone.name == other.name:110            if main_tone.name == other.name:
n106                main_tone = Tone(self.sorted_tones[0])n111                main_tone = self.without_main_tones_list_objs[0]
107                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)112                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)
108            else:113            else:
109                new_tones = filter(lambda tone: tone.name != other.name, new_tones)114                new_tones = filter(lambda tone: tone.name != other.name, new_tones)
110        return Chord(main_tone, *new_tones)      115        return Chord(main_tone, *new_tones)      
111116
112    def __str__(self):    117    def __str__(self):    
113        return "-".join(self.sorted_tones)118        return "-".join(self.sorted_tones)
114    119    
115    def is_minor(self):120    def is_minor(self):
n116        main_index = self.main_tone.indexn
117        for tone in self.without_main_tones_list_objs:121        for tone in self.without_main_tones_list_objs:
n118            interval = Interval(abs(main_index - tone.index))n122            interval = self.main_tone - tone
119            if str(interval) == "minor 3rd":123            if str(interval) == "minor 3rd":
120                return True124                return True
121        return False125        return False
122    126    
123    def is_major(self):127    def is_major(self):
n124        main_index = self.main_tone.indexn
125        for tone in self.without_main_tones_list_objs:128        for tone in self.without_main_tones_list_objs:
n126            interval = Interval(abs(main_index - tone.index))n129            interval = self.main_tone - tone
127            if str(interval) == "major 3rd":130            if str(interval) == "major 3rd":
128                return True131                return True
129        return False132        return False
130    133    
131    def is_power_chord(self):134    def is_power_chord(self):
132        return not self.is_major() and not self.is_minor() 135        return not self.is_major() and not self.is_minor() 
133    136    
134    def transposed(self, interval):137    def transposed(self, interval):
135        transposed_tones = [tone + interval for tone in self.all_tones_list_objs]138        transposed_tones = [tone + interval for tone in self.all_tones_list_objs]
136        return Chord(transposed_tones[0], *transposed_tones[1:])139        return Chord(transposed_tones[0], *transposed_tones[1:])
137140
t138 t
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]
4MAX_INDEX = 124MAX_INDEX = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self.name = name8        self.name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return self.name11        return self.name
12    12    
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other, Tone):14        if isinstance(other, Tone):
15            return Chord(self, other)15            return Chord(self, other)
16        if isinstance(other, Interval):16        if isinstance(other, Interval):
17            total_len = other.lenght + TONE_INDEX_DICT[self.name]17            total_len = other.lenght + TONE_INDEX_DICT[self.name]
18            correct_index = int(total_len / MAX_INDEX)18            correct_index = int(total_len / MAX_INDEX)
19            correct_len = total_len - correct_index*MAX_INDEX19            correct_len = total_len - correct_index*MAX_INDEX
20            return Tone(TONE_VALUE_LIST[correct_len])20            return Tone(TONE_VALUE_LIST[correct_len])
21    21    
22    def __sub__(self, other):22    def __sub__(self, other):
23        if isinstance(other, Tone):23        if isinstance(other, Tone):
24            return Interval(abs(self.index - other.index))24            return Interval(abs(self.index - other.index))
25        if isinstance(other, Interval):25        if isinstance(other, Interval):
26            cur_index = TONE_INDEX_DICT[self.name]26            cur_index = TONE_INDEX_DICT[self.name]
27            wanted_index = cur_index - other.lenght + MAX_INDEX27            wanted_index = cur_index - other.lenght + MAX_INDEX
28            return TONE_VALUE_LIST[wanted_index]28            return TONE_VALUE_LIST[wanted_index]
29    29    
30    @property30    @property
31    def index(self):31    def index(self):
32        return TONE_INDEX_DICT[self.name]32        return TONE_INDEX_DICT[self.name]
33    33    
34class Interval:34class Interval:
35    def __init__(self, lenght):35    def __init__(self, lenght):
36        correct_index = int(lenght / MAX_INDEX)36        correct_index = int(lenght / MAX_INDEX)
37        self.lenght = lenght - correct_index*MAX_INDEX37        self.lenght = lenght - correct_index*MAX_INDEX
3838
39    def __str__(self):39    def __str__(self):
40        return INTERVAL_VALUE_LIST[self.lenght]40        return INTERVAL_VALUE_LIST[self.lenght]
41    41    
42    def __add__(self,other):42    def __add__(self,other):
43        if isinstance(other,Tone):43        if isinstance(other,Tone):
44            raise TypeError("Invalid operation")44            raise TypeError("Invalid operation")
45        if isinstance(other,Interval):45        if isinstance(other,Interval):
46            total_len = self.lenght + other.lenght46            total_len = self.lenght + other.lenght
47            correct_index = int(total_len / MAX_INDEX)47            correct_index = int(total_len / MAX_INDEX)
48            correct_len = total_len - correct_index*MAX_INDEX48            correct_len = total_len - correct_index*MAX_INDEX
49            return INTERVAL_VALUE_LIST[correct_len]49            return INTERVAL_VALUE_LIST[correct_len]
50        50        
51    def __sub__(self,other):51    def __sub__(self,other):
52        if isinstance(other,Tone):52        if isinstance(other,Tone):
53            raise TypeError("Invalid operation")53            raise TypeError("Invalid operation")
54        54        
55    def __neg__(self):55    def __neg__(self):
56        return Interval(MAX_INDEX - self.lenght)56        return Interval(MAX_INDEX - self.lenght)
5757
58class Chord:58class Chord:
59    def __init_sorted_tones(self):59    def __init_sorted_tones(self):
60        main_index = self.main_tone.index60        main_index = self.main_tone.index
61        tones_dict = {self.main_tone.name : main_index}61        tones_dict = {self.main_tone.name : main_index}
nn62        self.all_tones_list_objs = [self.main_tone]
62        for tone in self.uniques_to_list_objs_tones:63        for tone_name in self.unique_tones:
63            tone_index = tone.index64            tone_index = Tone(tone_name).index
65            self.without_main_tones_list_objs.append(Tone(tone_name))
66            self.all_tones_list_objs.append(Tone(tone_name))
64            if main_index > tone_index:67            if main_index > tone_index:
n65                tones_dict[tone.name] = tone_index + MAX_INDEXn68                tones_dict[tone_name] = tone_index + MAX_INDEX
66            else:69            else:
n67                tones_dict[tone.name] = tone_indexn70                tones_dict[tone_name] = tone_index
68        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]71        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
n69    n
70    @property
71    def sorted_to_list_objs_tones(self):
72        tones_objs_list = []
73        for tone in self.sorted_tones:
74            tones_objs_list.append(Tone(tone))
75        return tones_objs_list
76 
77    @property
78    def uniques_to_list_objs_tones(self):
79        tones_objs_list = []
80        for tone in self.unique_tones:
81            tones_objs_list.append(Tone(tone))
82        return tones_objs_list
8372
84    def __init__(self, main_tone, *tones):73    def __init__(self, main_tone, *tones):
85        self.main_tone = main_tone74        self.main_tone = main_tone
86        self.unique_tones= set()75        self.unique_tones= set()
87        self.sorted_tones = []76        self.sorted_tones = []
nn77        self.all_tones_list_objs = []
78        self.without_main_tones_list_objs = []
88        self.unique_tones.add(main_tone.name)79        self.unique_tones.add(main_tone.name)
89        for tone in tones:80        for tone in tones:
90            self.unique_tones.add(tone.name)            81            self.unique_tones.add(tone.name)            
91        valid_len = len(self.unique_tones)82        valid_len = len(self.unique_tones)
92        if valid_len <= 1:83        if valid_len <= 1:
93            raise TypeError("Cannot have a chord made of only 1 unique tone")84            raise TypeError("Cannot have a chord made of only 1 unique tone")
94        self.unique_tones.discard(main_tone.name)85        self.unique_tones.discard(main_tone.name)
95        self.__init_sorted_tones()86        self.__init_sorted_tones()
96        87        
97    def __add__(self, other):88    def __add__(self, other):
n98        new_tones = self.uniques_to_list_objs_tonesn89        new_tones = self.without_main_tones_list_objs
99        if isinstance(other, Tone):90        if isinstance(other, Tone):
100            new_tones.append(other)91            new_tones.append(other)
101        if isinstance(other,Chord):92        if isinstance(other,Chord):
n102            for tone in other.sorted_to_list_objs_tones:n93            for tone in other.all_tones_list_objs:
103                new_tones.append(tone)94                new_tones.append(tone)
104        return Chord(self.main_tone, *new_tones)95        return Chord(self.main_tone, *new_tones)
10596
106    def __sub__(self, other):97    def __sub__(self, other):
107        if other.name not in self.sorted_tones:98        if other.name not in self.sorted_tones:
108            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")99            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
109        if len(self.unique_tones) < 2:100        if len(self.unique_tones) < 2:
110            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")
n111        new_tones = self.sorted_to_list_objs_tonesn102        new_tones = self.all_tones_list_objs
112        main_tone = self.main_tone103        main_tone = self.main_tone
113        if isinstance(other, Tone):104        if isinstance(other, Tone):
114            if main_tone.name == other.name:105            if main_tone.name == other.name:
115                main_tone = Tone(self.sorted_tones[0])106                main_tone = Tone(self.sorted_tones[0])
116                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)107                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)
117            else:108            else:
118                new_tones = filter(lambda tone: tone.name != other.name, new_tones)109                new_tones = filter(lambda tone: tone.name != other.name, new_tones)
119        return Chord(main_tone, *new_tones)      110        return Chord(main_tone, *new_tones)      
120111
121    def __str__(self):    112    def __str__(self):    
122        return "-".join(self.sorted_tones)113        return "-".join(self.sorted_tones)
123    114    
124    def is_minor(self):115    def is_minor(self):
125        main_index = self.main_tone.index116        main_index = self.main_tone.index
n126        for tone in self.uniques_to_list_objs_tones:n117        for tone in self.without_main_tones_list_objs:
127            interval = Interval(abs(main_index - tone.index))118            interval = Interval(abs(main_index - tone.index))
128            if str(interval) == "minor 3rd":119            if str(interval) == "minor 3rd":
129                return True120                return True
130        return False121        return False
131    122    
132    def is_major(self):123    def is_major(self):
133        main_index = self.main_tone.index124        main_index = self.main_tone.index
n134        for tone in self.uniques_to_list_objs_tones:n125        for tone in self.without_main_tones_list_objs:
135            interval = Interval(abs(main_index - tone.index))126            interval = Interval(abs(main_index - tone.index))
136            if str(interval) == "major 3rd":127            if str(interval) == "major 3rd":
137                return True128                return True
138        return False129        return False
139    130    
140    def is_power_chord(self):131    def is_power_chord(self):
141        return not self.is_major() and not self.is_minor() 132        return not self.is_major() and not self.is_minor() 
142    133    
143    def transposed(self, interval):134    def transposed(self, interval):
t144        transposed_tones = [tone + interval for tone in self.sorted_to_list_objs_tones]t135        transposed_tones = [tone + interval for tone in self.all_tones_list_objs]
145        return Chord(transposed_tones[0], *transposed_tones[1:])136        return Chord(transposed_tones[0], *transposed_tones[1:])
146137
147138
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]
4MAX_INDEX = 124MAX_INDEX = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self.name = name8        self.name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return self.name11        return self.name
12    12    
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other, Tone):14        if isinstance(other, Tone):
15            return Chord(self, other)15            return Chord(self, other)
16        if isinstance(other, Interval):16        if isinstance(other, Interval):
17            total_len = other.lenght + TONE_INDEX_DICT[self.name]17            total_len = other.lenght + TONE_INDEX_DICT[self.name]
18            correct_index = int(total_len / MAX_INDEX)18            correct_index = int(total_len / MAX_INDEX)
19            correct_len = total_len - correct_index*MAX_INDEX19            correct_len = total_len - correct_index*MAX_INDEX
20            return Tone(TONE_VALUE_LIST[correct_len])20            return Tone(TONE_VALUE_LIST[correct_len])
21    21    
22    def __sub__(self, other):22    def __sub__(self, other):
23        if isinstance(other, Tone):23        if isinstance(other, Tone):
24            return Interval(abs(self.index - other.index))24            return Interval(abs(self.index - other.index))
25        if isinstance(other, Interval):25        if isinstance(other, Interval):
26            cur_index = TONE_INDEX_DICT[self.name]26            cur_index = TONE_INDEX_DICT[self.name]
27            wanted_index = cur_index - other.lenght + MAX_INDEX27            wanted_index = cur_index - other.lenght + MAX_INDEX
28            return TONE_VALUE_LIST[wanted_index]28            return TONE_VALUE_LIST[wanted_index]
29    29    
30    @property30    @property
31    def index(self):31    def index(self):
32        return TONE_INDEX_DICT[self.name]32        return TONE_INDEX_DICT[self.name]
33    33    
34class Interval:34class Interval:
35    def __init__(self, lenght):35    def __init__(self, lenght):
36        correct_index = int(lenght / MAX_INDEX)36        correct_index = int(lenght / MAX_INDEX)
37        self.lenght = lenght - correct_index*MAX_INDEX37        self.lenght = lenght - correct_index*MAX_INDEX
3838
39    def __str__(self):39    def __str__(self):
40        return INTERVAL_VALUE_LIST[self.lenght]40        return INTERVAL_VALUE_LIST[self.lenght]
41    41    
42    def __add__(self,other):42    def __add__(self,other):
43        if isinstance(other,Tone):43        if isinstance(other,Tone):
44            raise TypeError("Invalid operation")44            raise TypeError("Invalid operation")
45        if isinstance(other,Interval):45        if isinstance(other,Interval):
46            total_len = self.lenght + other.lenght46            total_len = self.lenght + other.lenght
47            correct_index = int(total_len / MAX_INDEX)47            correct_index = int(total_len / MAX_INDEX)
48            correct_len = total_len - correct_index*MAX_INDEX48            correct_len = total_len - correct_index*MAX_INDEX
49            return INTERVAL_VALUE_LIST[correct_len]49            return INTERVAL_VALUE_LIST[correct_len]
50        50        
51    def __sub__(self,other):51    def __sub__(self,other):
52        if isinstance(other,Tone):52        if isinstance(other,Tone):
53            raise TypeError("Invalid operation")53            raise TypeError("Invalid operation")
54        54        
55    def __neg__(self):55    def __neg__(self):
t56        correct_index = int(self.lenght / MAX_INDEX)t
57        self.lenght  = self.lenght - correct_index*MAX_INDEX
58        return Interval(MAX_INDEX-self.lenght)56        return Interval(MAX_INDEX - self.lenght)
5957
60class Chord:58class Chord:
61    def __init_sorted_tones(self):59    def __init_sorted_tones(self):
62        main_index = self.main_tone.index60        main_index = self.main_tone.index
63        tones_dict = {self.main_tone.name : main_index}61        tones_dict = {self.main_tone.name : main_index}
64        for tone in self.uniques_to_list_objs_tones:62        for tone in self.uniques_to_list_objs_tones:
65            tone_index = tone.index63            tone_index = tone.index
66            if main_index > tone_index:64            if main_index > tone_index:
67                tones_dict[tone.name] = tone_index + MAX_INDEX65                tones_dict[tone.name] = tone_index + MAX_INDEX
68            else:66            else:
69                tones_dict[tone.name] = tone_index67                tones_dict[tone.name] = tone_index
70        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]68        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
71    69    
72    @property70    @property
73    def sorted_to_list_objs_tones(self):71    def sorted_to_list_objs_tones(self):
74        tones_objs_list = []72        tones_objs_list = []
75        for tone in self.sorted_tones:73        for tone in self.sorted_tones:
76            tones_objs_list.append(Tone(tone))74            tones_objs_list.append(Tone(tone))
77        return tones_objs_list75        return tones_objs_list
7876
79    @property77    @property
80    def uniques_to_list_objs_tones(self):78    def uniques_to_list_objs_tones(self):
81        tones_objs_list = []79        tones_objs_list = []
82        for tone in self.unique_tones:80        for tone in self.unique_tones:
83            tones_objs_list.append(Tone(tone))81            tones_objs_list.append(Tone(tone))
84        return tones_objs_list82        return tones_objs_list
8583
86    def __init__(self, main_tone, *tones):84    def __init__(self, main_tone, *tones):
87        self.main_tone = main_tone85        self.main_tone = main_tone
88        self.unique_tones= set()86        self.unique_tones= set()
89        self.sorted_tones = []87        self.sorted_tones = []
90        self.unique_tones.add(main_tone.name)88        self.unique_tones.add(main_tone.name)
91        for tone in tones:89        for tone in tones:
92            self.unique_tones.add(tone.name)            90            self.unique_tones.add(tone.name)            
93        valid_len = len(self.unique_tones)91        valid_len = len(self.unique_tones)
94        if valid_len <= 1:92        if valid_len <= 1:
95            raise TypeError("Cannot have a chord made of only 1 unique tone")93            raise TypeError("Cannot have a chord made of only 1 unique tone")
96        self.unique_tones.discard(main_tone.name)94        self.unique_tones.discard(main_tone.name)
97        self.__init_sorted_tones()95        self.__init_sorted_tones()
98        96        
99    def __add__(self, other):97    def __add__(self, other):
100        new_tones = self.uniques_to_list_objs_tones98        new_tones = self.uniques_to_list_objs_tones
101        if isinstance(other, Tone):99        if isinstance(other, Tone):
102            new_tones.append(other)100            new_tones.append(other)
103        if isinstance(other,Chord):101        if isinstance(other,Chord):
104            for tone in other.sorted_to_list_objs_tones:102            for tone in other.sorted_to_list_objs_tones:
105                new_tones.append(tone)103                new_tones.append(tone)
106        return Chord(self.main_tone, *new_tones)104        return Chord(self.main_tone, *new_tones)
107105
108    def __sub__(self, other):106    def __sub__(self, other):
109        if other.name not in self.sorted_tones:107        if other.name not in self.sorted_tones:
110            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")108            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
111        if len(self.unique_tones) < 2:109        if len(self.unique_tones) < 2:
112            raise TypeError("Cannot have a chord made of only 1 unique tone")110            raise TypeError("Cannot have a chord made of only 1 unique tone")
113        new_tones = self.sorted_to_list_objs_tones111        new_tones = self.sorted_to_list_objs_tones
114        main_tone = self.main_tone112        main_tone = self.main_tone
115        if isinstance(other, Tone):113        if isinstance(other, Tone):
116            if main_tone.name == other.name:114            if main_tone.name == other.name:
117                main_tone = Tone(self.sorted_tones[0])115                main_tone = Tone(self.sorted_tones[0])
118                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)116                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)
119            else:117            else:
120                new_tones = filter(lambda tone: tone.name != other.name, new_tones)118                new_tones = filter(lambda tone: tone.name != other.name, new_tones)
121        return Chord(main_tone, *new_tones)      119        return Chord(main_tone, *new_tones)      
122120
123    def __str__(self):    121    def __str__(self):    
124        return "-".join(self.sorted_tones)122        return "-".join(self.sorted_tones)
125    123    
126    def is_minor(self):124    def is_minor(self):
127        main_index = self.main_tone.index125        main_index = self.main_tone.index
128        for tone in self.uniques_to_list_objs_tones:126        for tone in self.uniques_to_list_objs_tones:
129            interval = Interval(abs(main_index - tone.index))127            interval = Interval(abs(main_index - tone.index))
130            if str(interval) == "minor 3rd":128            if str(interval) == "minor 3rd":
131                return True129                return True
132        return False130        return False
133    131    
134    def is_major(self):132    def is_major(self):
135        main_index = self.main_tone.index133        main_index = self.main_tone.index
136        for tone in self.uniques_to_list_objs_tones:134        for tone in self.uniques_to_list_objs_tones:
137            interval = Interval(abs(main_index - tone.index))135            interval = Interval(abs(main_index - tone.index))
138            if str(interval) == "major 3rd":136            if str(interval) == "major 3rd":
139                return True137                return True
140        return False138        return False
141    139    
142    def is_power_chord(self):140    def is_power_chord(self):
143        return not self.is_major() and not self.is_minor() 141        return not self.is_major() and not self.is_minor() 
144    142    
145    def transposed(self, interval):143    def transposed(self, interval):
146        transposed_tones = [tone + interval for tone in self.sorted_to_list_objs_tones]144        transposed_tones = [tone + interval for tone in self.sorted_to_list_objs_tones]
147        return Chord(transposed_tones[0], *transposed_tones[1:])145        return Chord(transposed_tones[0], *transposed_tones[1:])
148146
149147
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]
4MAX_INDEX = 124MAX_INDEX = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self.name = name8        self.name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return self.name11        return self.name
12    12    
13    def __add__(self, other):13    def __add__(self, other):
n14        if isinstance(other,Tone):n14        if isinstance(other, Tone):
15            return Chord(self,other)15            return Chord(self, other)
16        if isinstance(other,Interval):16        if isinstance(other, Interval):
17            total_len = other.lenght + TONE_INDEX_DICT[self.name]17            total_len = other.lenght + TONE_INDEX_DICT[self.name]
18            correct_index = int(total_len / MAX_INDEX)18            correct_index = int(total_len / MAX_INDEX)
19            correct_len = total_len - correct_index*MAX_INDEX19            correct_len = total_len - correct_index*MAX_INDEX
20            return Tone(TONE_VALUE_LIST[correct_len])20            return Tone(TONE_VALUE_LIST[correct_len])
21    21    
22    def __sub__(self, other):22    def __sub__(self, other):
n23        if isinstance(other,Tone):n23        if isinstance(other, Tone):
24            return Interval(abs(self.index - other.index))24            return Interval(abs(self.index - other.index))
n25        if isinstance(other,Interval):n25        if isinstance(other, Interval):
26            cur_index = TONE_INDEX_DICT[self.name]26            cur_index = TONE_INDEX_DICT[self.name]
27            wanted_index = cur_index - other.lenght + MAX_INDEX27            wanted_index = cur_index - other.lenght + MAX_INDEX
28            return TONE_VALUE_LIST[wanted_index]28            return TONE_VALUE_LIST[wanted_index]
29    29    
30    @property30    @property
31    def index(self):31    def index(self):
32        return TONE_INDEX_DICT[self.name]32        return TONE_INDEX_DICT[self.name]
33    33    
34class Interval:34class Interval:
35    def __init__(self, lenght):35    def __init__(self, lenght):
36        correct_index = int(lenght / MAX_INDEX)36        correct_index = int(lenght / MAX_INDEX)
n37        self.lenght  = lenght - correct_index*MAX_INDEXn37        self.lenght = lenght - correct_index*MAX_INDEX
3838
39    def __str__(self):39    def __str__(self):
n40     n
41        return INTERVAL_VALUE_LIST[self.lenght]40        return INTERVAL_VALUE_LIST[self.lenght]
42    41    
43    def __add__(self,other):42    def __add__(self,other):
44        if isinstance(other,Tone):43        if isinstance(other,Tone):
45            raise TypeError("Invalid operation")44            raise TypeError("Invalid operation")
46        if isinstance(other,Interval):45        if isinstance(other,Interval):
47            total_len = self.lenght + other.lenght46            total_len = self.lenght + other.lenght
48            correct_index = int(total_len / MAX_INDEX)47            correct_index = int(total_len / MAX_INDEX)
49            correct_len = total_len - correct_index*MAX_INDEX48            correct_len = total_len - correct_index*MAX_INDEX
50            return INTERVAL_VALUE_LIST[correct_len]49            return INTERVAL_VALUE_LIST[correct_len]
51        50        
52    def __sub__(self,other):51    def __sub__(self,other):
53        if isinstance(other,Tone):52        if isinstance(other,Tone):
54            raise TypeError("Invalid operation")53            raise TypeError("Invalid operation")
55        54        
56    def __neg__(self):55    def __neg__(self):
57        correct_index = int(self.lenght / MAX_INDEX)56        correct_index = int(self.lenght / MAX_INDEX)
58        self.lenght  = self.lenght - correct_index*MAX_INDEX57        self.lenght  = self.lenght - correct_index*MAX_INDEX
59        return Interval(MAX_INDEX-self.lenght)58        return Interval(MAX_INDEX-self.lenght)
6059
61class Chord:60class Chord:
62    def __init_sorted_tones(self):61    def __init_sorted_tones(self):
63        main_index = self.main_tone.index62        main_index = self.main_tone.index
64        tones_dict = {self.main_tone.name : main_index}63        tones_dict = {self.main_tone.name : main_index}
65        for tone in self.uniques_to_list_objs_tones:64        for tone in self.uniques_to_list_objs_tones:
66            tone_index = tone.index65            tone_index = tone.index
67            if main_index > tone_index:66            if main_index > tone_index:
68                tones_dict[tone.name] = tone_index + MAX_INDEX67                tones_dict[tone.name] = tone_index + MAX_INDEX
69            else:68            else:
70                tones_dict[tone.name] = tone_index69                tones_dict[tone.name] = tone_index
71        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]70        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
72    71    
73    @property72    @property
74    def sorted_to_list_objs_tones(self):73    def sorted_to_list_objs_tones(self):
75        tones_objs_list = []74        tones_objs_list = []
76        for tone in self.sorted_tones:75        for tone in self.sorted_tones:
77            tones_objs_list.append(Tone(tone))76            tones_objs_list.append(Tone(tone))
78        return tones_objs_list77        return tones_objs_list
7978
80    @property79    @property
81    def uniques_to_list_objs_tones(self):80    def uniques_to_list_objs_tones(self):
82        tones_objs_list = []81        tones_objs_list = []
83        for tone in self.unique_tones:82        for tone in self.unique_tones:
84            tones_objs_list.append(Tone(tone))83            tones_objs_list.append(Tone(tone))
85        return tones_objs_list84        return tones_objs_list
8685
87    def __init__(self, main_tone, *tones):86    def __init__(self, main_tone, *tones):
88        self.main_tone = main_tone87        self.main_tone = main_tone
89        self.unique_tones= set()88        self.unique_tones= set()
90        self.sorted_tones = []89        self.sorted_tones = []
91        self.unique_tones.add(main_tone.name)90        self.unique_tones.add(main_tone.name)
92        for tone in tones:91        for tone in tones:
n93                self.unique_tones.add(tone.name)            n92            self.unique_tones.add(tone.name)            
94 
95        valid_len = len(self.unique_tones)93        valid_len = len(self.unique_tones)
96        if valid_len <= 1:94        if valid_len <= 1:
97            raise TypeError("Cannot have a chord made of only 1 unique tone")95            raise TypeError("Cannot have a chord made of only 1 unique tone")
98        self.unique_tones.discard(main_tone.name)96        self.unique_tones.discard(main_tone.name)
99        self.__init_sorted_tones()97        self.__init_sorted_tones()
100        98        
101    def __add__(self, other):99    def __add__(self, other):
102        new_tones = self.uniques_to_list_objs_tones100        new_tones = self.uniques_to_list_objs_tones
103        if isinstance(other, Tone):101        if isinstance(other, Tone):
104            new_tones.append(other)102            new_tones.append(other)
105        if isinstance(other,Chord):103        if isinstance(other,Chord):
106            for tone in other.sorted_to_list_objs_tones:104            for tone in other.sorted_to_list_objs_tones:
107                new_tones.append(tone)105                new_tones.append(tone)
108        return Chord(self.main_tone, *new_tones)106        return Chord(self.main_tone, *new_tones)
109107
n110    n
111    def __sub__(self, other):108    def __sub__(self, other):
112        if other.name not in self.sorted_tones:109        if other.name not in self.sorted_tones:
113            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")110            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
114        if len(self.unique_tones) < 2:111        if len(self.unique_tones) < 2:
115            raise TypeError("Cannot have a chord made of only 1 unique tone")112            raise TypeError("Cannot have a chord made of only 1 unique tone")
116        new_tones = self.sorted_to_list_objs_tones113        new_tones = self.sorted_to_list_objs_tones
117        main_tone = self.main_tone114        main_tone = self.main_tone
118        if isinstance(other, Tone):115        if isinstance(other, Tone):
119            if main_tone.name == other.name:116            if main_tone.name == other.name:
120                main_tone = Tone(self.sorted_tones[0])117                main_tone = Tone(self.sorted_tones[0])
121                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)118                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)
122            else:119            else:
123                new_tones = filter(lambda tone: tone.name != other.name, new_tones)120                new_tones = filter(lambda tone: tone.name != other.name, new_tones)
124        return Chord(main_tone, *new_tones)      121        return Chord(main_tone, *new_tones)      
125122
126    def __str__(self):    123    def __str__(self):    
127        return "-".join(self.sorted_tones)124        return "-".join(self.sorted_tones)
128    125    
129    def is_minor(self):126    def is_minor(self):
130        main_index = self.main_tone.index127        main_index = self.main_tone.index
131        for tone in self.uniques_to_list_objs_tones:128        for tone in self.uniques_to_list_objs_tones:
132            interval = Interval(abs(main_index - tone.index))129            interval = Interval(abs(main_index - tone.index))
133            if str(interval) == "minor 3rd":130            if str(interval) == "minor 3rd":
134                return True131                return True
135        return False132        return False
136    133    
137    def is_major(self):134    def is_major(self):
138        main_index = self.main_tone.index135        main_index = self.main_tone.index
139        for tone in self.uniques_to_list_objs_tones:136        for tone in self.uniques_to_list_objs_tones:
140            interval = Interval(abs(main_index - tone.index))137            interval = Interval(abs(main_index - tone.index))
141            if str(interval) == "major 3rd":138            if str(interval) == "major 3rd":
142                return True139                return True
143        return False140        return False
144    141    
145    def is_power_chord(self):142    def is_power_chord(self):
146        return not self.is_major() and not self.is_minor() 143        return not self.is_major() and not self.is_minor() 
147    144    
148    def transposed(self, interval):145    def transposed(self, interval):
149        transposed_tones = [tone + interval for tone in self.sorted_to_list_objs_tones]146        transposed_tones = [tone + interval for tone in self.sorted_to_list_objs_tones]
t150    t
151        return Chord(transposed_tones[0], *transposed_tones[1:])147        return Chord(transposed_tones[0], *transposed_tones[1:])
152148
153149
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
n2TONE_VALUE_DICT = {0 : "C", 1: "C#" , 2 : "D" , 3 : "D#" , 4 : "E" , 5 : "F" , 6 : "F#" , 7 : "G" , 8 : "G#" , 9 : "A" , 10 : "A#" , 11 : "B" }n2TONE_VALUE_LIST = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
3INTERVAL_VALUE_DICT = {0 : "unison", 1 : "minor 2nd", 2 : "major 2nd", 3 : "minor 3rd", 4 : "major 3rd", 5 : "perfect 4th", 6 : "diminished 5th", 7 : "perfect 5th", 8 : "minor 6th", 9 : "major 6th", 10 : "minor 7th", 11 : "major 7th"}3INTERVAL_VALUE_LIST = ["unison", "minor 2nd", "major 2nd", "minor 3rd", "major 3rd", "perfect 4th", "diminished 5th", "perfect 5th", "minor 6th", "major 6th", "minor 7th", "major 7th"]
4MAX_INDEX = 124MAX_INDEX = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self.name = name8        self.name = name
9    9    
10    def __str__(self):10    def __str__(self):
n11        return f"{self.name}"n11        return self.name
12    12    
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other,Tone):14        if isinstance(other,Tone):
15            return Chord(self,other)15            return Chord(self,other)
16        if isinstance(other,Interval):16        if isinstance(other,Interval):
17            total_len = other.lenght + TONE_INDEX_DICT[self.name]17            total_len = other.lenght + TONE_INDEX_DICT[self.name]
18            correct_index = int(total_len / MAX_INDEX)18            correct_index = int(total_len / MAX_INDEX)
19            correct_len = total_len - correct_index*MAX_INDEX19            correct_len = total_len - correct_index*MAX_INDEX
n20            return Tone(TONE_VALUE_DICT[correct_len])n20            return Tone(TONE_VALUE_LIST[correct_len])
21    21    
22    def __sub__(self, other):22    def __sub__(self, other):
23        if isinstance(other,Tone):23        if isinstance(other,Tone):
n24            return Interval(abs(self.get_index()-other.get_index()))n24            return Interval(abs(self.index - other.index))
25        if isinstance(other,Interval):25        if isinstance(other,Interval):
n26            correct_index = int(other.lenght / MAX_INDEX)n
27            correct_len = other.lenght - correct_index*MAX_INDEX
28            cur_index = TONE_INDEX_DICT[self.name]26            cur_index = TONE_INDEX_DICT[self.name]
n29            wanted_index = cur_index - correct_len + MAX_INDEXn27            wanted_index = cur_index - other.lenght + MAX_INDEX
30            return TONE_VALUE_DICT[wanted_index]28            return TONE_VALUE_LIST[wanted_index]
31 29    
30    @property
32    def get_index(self):31    def index(self):
33       return TONE_INDEX_DICT[self.name]32        return TONE_INDEX_DICT[self.name]
34        33    
35    @staticmethod
36    def get_index_for_name(name):
37        return TONE_INDEX_DICT[name]
38 
39          
40 
41class Interval:34class Interval:
42    def __init__(self, lenght):35    def __init__(self, lenght):
n43        self.lenght = lenghtn36        correct_index = int(lenght / MAX_INDEX)
44   37        self.lenght  = lenght - correct_index*MAX_INDEX
38 
45    def __str__(self):39    def __str__(self):
n46        correct_index = int(self.lenght / MAX_INDEX)n40     
47        correct_len = self.lenght - correct_index*MAX_INDEX
48        return INTERVAL_VALUE_DICT[correct_len]41        return INTERVAL_VALUE_LIST[self.lenght]
49    42    
50    def __add__(self,other):43    def __add__(self,other):
51        if isinstance(other,Tone):44        if isinstance(other,Tone):
52            raise TypeError("Invalid operation")45            raise TypeError("Invalid operation")
53        if isinstance(other,Interval):46        if isinstance(other,Interval):
54            total_len = self.lenght + other.lenght47            total_len = self.lenght + other.lenght
55            correct_index = int(total_len / MAX_INDEX)48            correct_index = int(total_len / MAX_INDEX)
56            correct_len = total_len - correct_index*MAX_INDEX49            correct_len = total_len - correct_index*MAX_INDEX
n57            return INTERVAL_VALUE_DICT[correct_len]n50            return INTERVAL_VALUE_LIST[correct_len]
58        51        
59    def __sub__(self,other):52    def __sub__(self,other):
60        if isinstance(other,Tone):53        if isinstance(other,Tone):
61            raise TypeError("Invalid operation")54            raise TypeError("Invalid operation")
62        55        
63    def __neg__(self):56    def __neg__(self):
nn57        correct_index = int(self.lenght / MAX_INDEX)
58        self.lenght  = self.lenght - correct_index*MAX_INDEX
64        return Interval(-self.lenght)59        return Interval(MAX_INDEX-self.lenght)
6560
66class Chord:61class Chord:
67    def __init_sorted_tones(self):62    def __init_sorted_tones(self):
n68        main_index = self.main_tone.get_index()n63        main_index = self.main_tone.index
69        tones_dict = {self.main_tone.name : main_index}64        tones_dict = {self.main_tone.name : main_index}
n70        for tone_name in self.unique_tones:n65        for tone in self.uniques_to_list_objs_tones:
71            tone_index = Tone.get_index_for_name(tone_name)66            tone_index = tone.index
72            if main_index > tone_index:67            if main_index > tone_index:
n73                tones_dict[tone_name] = tone_index + 10n68                tones_dict[tone.name] = tone_index + MAX_INDEX
74            else:69            else:
n75                tones_dict[tone_name] = tone_indexn70                tones_dict[tone.name] = tone_index
76        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]71        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
nn72    
73    @property
74    def sorted_to_list_objs_tones(self):
75        tones_objs_list = []
76        for tone in self.sorted_tones:
77            tones_objs_list.append(Tone(tone))
78        return tones_objs_list
79 
80    @property
81    def uniques_to_list_objs_tones(self):
82        tones_objs_list = []
83        for tone in self.unique_tones:
84            tones_objs_list.append(Tone(tone))
85        return tones_objs_list
7786
78    def __init__(self, main_tone, *tones):87    def __init__(self, main_tone, *tones):
79        self.main_tone = main_tone88        self.main_tone = main_tone
80        self.unique_tones= set()89        self.unique_tones= set()
81        self.sorted_tones = []90        self.sorted_tones = []
82        self.unique_tones.add(main_tone.name)91        self.unique_tones.add(main_tone.name)
83        for tone in tones:92        for tone in tones:
84                self.unique_tones.add(tone.name)            93                self.unique_tones.add(tone.name)            
8594
86        valid_len = len(self.unique_tones)95        valid_len = len(self.unique_tones)
87        if valid_len <= 1:96        if valid_len <= 1:
n88            raise TypeError(f"Cannot have a chord made of only {valid_len} unique tone")n97            raise TypeError("Cannot have a chord made of only 1 unique tone")
89        self.unique_tones.discard(main_tone.name)98        self.unique_tones.discard(main_tone.name)
90        self.__init_sorted_tones()99        self.__init_sorted_tones()
91        100        
92    def __add__(self, other):101    def __add__(self, other):
nn102        new_tones = self.uniques_to_list_objs_tones
93        if isinstance(other, Tone):103        if isinstance(other, Tone):
n94            self.unique_tones.add(other.name)n104            new_tones.append(other)
95        if isinstance(other,Chord):105        if isinstance(other,Chord):
n96            for tone_name in other.sorted_tones:n106            for tone in other.sorted_to_list_objs_tones:
97                self.unique_tones.add(tone_name)107                new_tones.append(tone)
98        return self108        return Chord(self.main_tone, *new_tones)
99109
100    110    
101    def __sub__(self, other):111    def __sub__(self, other):
n102        if not other.name in self.sorted_tones:n112        if other.name not in self.sorted_tones:
103            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")113            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
104        if len(self.unique_tones) < 2:114        if len(self.unique_tones) < 2:
105            raise TypeError("Cannot have a chord made of only 1 unique tone")115            raise TypeError("Cannot have a chord made of only 1 unique tone")
nn116        new_tones = self.sorted_to_list_objs_tones
117        main_tone = self.main_tone
106        if isinstance(other, Tone):118        if isinstance(other, Tone):
n107            if self.main_tone.name == other.name:n119            if main_tone.name == other.name:
108                self.main_tone = Tone(self.sorted_tones[0])120                main_tone = Tone(self.sorted_tones[0])
109                self.unique_tones.discard(self.main_tone.name)121                new_tones = filter(lambda tone: tone.name != main_tone.name, new_tones)
110            else:122            else:
n111                self.unique_tones.discard(other.name)n123                new_tones = filter(lambda tone: tone.name != other.name, new_tones)
112        return self            124        return Chord(main_tone, *new_tones)      
113125
114    def __str__(self):    126    def __str__(self):    
n115        self.__init_sorted_tones()n
116        return "-".join(self.sorted_tones)127        return "-".join(self.sorted_tones)
117    128    
118    def is_minor(self):129    def is_minor(self):
n119        main_index = self.main_tone.get_index()n130        main_index = self.main_tone.index
120        for tone_name in self.unique_tones:131        for tone in self.uniques_to_list_objs_tones:
121            tone_index = Tone.get_index_for_name(tone_name)
122            interval = Interval(abs(main_index - tone_index))132            interval = Interval(abs(main_index - tone.index))
123            if str(interval) == "minor 3rd":133            if str(interval) == "minor 3rd":
124                return True134                return True
125        return False135        return False
126    136    
127    def is_major(self):137    def is_major(self):
n128        main_index = self.main_tone.get_index()n138        main_index = self.main_tone.index
129        for tone_name in self.unique_tones:139        for tone in self.uniques_to_list_objs_tones:
130            tone_index = Tone.get_index_for_name(tone_name)
131            interval = Interval(abs(main_index - tone_index))140            interval = Interval(abs(main_index - tone.index))
132            if str(interval) == "major 3rd":141            if str(interval) == "major 3rd":
133                return True142                return True
134        return False143        return False
135    144    
136    def is_power_chord(self):145    def is_power_chord(self):
137        return not self.is_major() and not self.is_minor() 146        return not self.is_major() and not self.is_minor() 
138    147    
139    def transposed(self, interval):148    def transposed(self, interval):
n140        transposing = interval.lenghtn149        transposed_tones = [tone + interval for tone in self.sorted_to_list_objs_tones]
141        transposed_tones = []150    
142        tone_name_transposed = ""151        return Chord(transposed_tones[0], *transposed_tones[1:])
143        for tone_name in self.sorted_tones:
144            index = Tone.get_index_for_name(tone_name)
145            if(transposing >= 0):
146                tone_name_transposed = (TONE_VALUE_DICT[index + transposing])
147            else:
148                if(index + transposing < 0):
149                    tone_name_transposed = (TONE_VALUE_DICT[index + transposing + MAX_INDEX])
150                else:
151                    tone_name_transposed = (TONE_VALUE_DICT[index + transposing])
152152
153153
t154            transposed_tones.append(Tone(tone_name_transposed))t
155 
156        return Chord(transposed_tones[0], *transposed_tones[1:])
157 
158 
159 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}f1TONE_INDEX_DICT = {"C" : 0, "C#" : 1, "D" : 2, "D#" : 3, "E" : 4, "F" : 5, "F#" : 6, "G" : 7, "G#" : 8, "A" : 9, "A#" : 10, "B" : 11}
2TONE_VALUE_DICT = {0 : "C", 1: "C#" , 2 : "D" , 3 : "D#" , 4 : "E" , 5 : "F" , 6 : "F#" , 7 : "G" , 8 : "G#" , 9 : "A" , 10 : "A#" , 11 : "B" }2TONE_VALUE_DICT = {0 : "C", 1: "C#" , 2 : "D" , 3 : "D#" , 4 : "E" , 5 : "F" , 6 : "F#" , 7 : "G" , 8 : "G#" , 9 : "A" , 10 : "A#" , 11 : "B" }
3INTERVAL_VALUE_DICT = {0 : "unison", 1 : "minor 2nd", 2 : "major 2nd", 3 : "minor 3rd", 4 : "major 3rd", 5 : "perfect 4th", 6 : "diminished 5th", 7 : "perfect 5th", 8 : "minor 6th", 9 : "major 6th", 10 : "minor 7th", 11 : "major 7th"}3INTERVAL_VALUE_DICT = {0 : "unison", 1 : "minor 2nd", 2 : "major 2nd", 3 : "minor 3rd", 4 : "major 3rd", 5 : "perfect 4th", 6 : "diminished 5th", 7 : "perfect 5th", 8 : "minor 6th", 9 : "major 6th", 10 : "minor 7th", 11 : "major 7th"}
4MAX_INDEX = 124MAX_INDEX = 12
55
6class Tone:6class Tone:
7    def __init__(self, name):7    def __init__(self, name):
8        self.name = name8        self.name = name
9    9    
10    def __str__(self):10    def __str__(self):
11        return f"{self.name}"11        return f"{self.name}"
12    12    
13    def __add__(self, other):13    def __add__(self, other):
14        if isinstance(other,Tone):14        if isinstance(other,Tone):
15            return Chord(self,other)15            return Chord(self,other)
16        if isinstance(other,Interval):16        if isinstance(other,Interval):
17            total_len = other.lenght + TONE_INDEX_DICT[self.name]17            total_len = other.lenght + TONE_INDEX_DICT[self.name]
18            correct_index = int(total_len / MAX_INDEX)18            correct_index = int(total_len / MAX_INDEX)
19            correct_len = total_len - correct_index*MAX_INDEX19            correct_len = total_len - correct_index*MAX_INDEX
20            return Tone(TONE_VALUE_DICT[correct_len])20            return Tone(TONE_VALUE_DICT[correct_len])
21    21    
22    def __sub__(self, other):22    def __sub__(self, other):
23        if isinstance(other,Tone):23        if isinstance(other,Tone):
24            return Interval(abs(self.get_index()-other.get_index()))24            return Interval(abs(self.get_index()-other.get_index()))
25        if isinstance(other,Interval):25        if isinstance(other,Interval):
26            correct_index = int(other.lenght / MAX_INDEX)26            correct_index = int(other.lenght / MAX_INDEX)
27            correct_len = other.lenght - correct_index*MAX_INDEX27            correct_len = other.lenght - correct_index*MAX_INDEX
28            cur_index = TONE_INDEX_DICT[self.name]28            cur_index = TONE_INDEX_DICT[self.name]
29            wanted_index = cur_index - correct_len + MAX_INDEX29            wanted_index = cur_index - correct_len + MAX_INDEX
30            return TONE_VALUE_DICT[wanted_index]30            return TONE_VALUE_DICT[wanted_index]
3131
32    def get_index(self):32    def get_index(self):
33       return TONE_INDEX_DICT[self.name]33       return TONE_INDEX_DICT[self.name]
34        34        
35    @staticmethod35    @staticmethod
36    def get_index_for_name(name):36    def get_index_for_name(name):
37        return TONE_INDEX_DICT[name]37        return TONE_INDEX_DICT[name]
3838
39          39          
4040
41class Interval:41class Interval:
42    def __init__(self, lenght):42    def __init__(self, lenght):
43        self.lenght = lenght43        self.lenght = lenght
44   44   
45    def __str__(self):45    def __str__(self):
46        correct_index = int(self.lenght / MAX_INDEX)46        correct_index = int(self.lenght / MAX_INDEX)
47        correct_len = self.lenght - correct_index*MAX_INDEX47        correct_len = self.lenght - correct_index*MAX_INDEX
48        return INTERVAL_VALUE_DICT[correct_len]48        return INTERVAL_VALUE_DICT[correct_len]
49    49    
50    def __add__(self,other):50    def __add__(self,other):
51        if isinstance(other,Tone):51        if isinstance(other,Tone):
52            raise TypeError("Invalid operation")52            raise TypeError("Invalid operation")
53        if isinstance(other,Interval):53        if isinstance(other,Interval):
54            total_len = self.lenght + other.lenght54            total_len = self.lenght + other.lenght
55            correct_index = int(total_len / MAX_INDEX)55            correct_index = int(total_len / MAX_INDEX)
56            correct_len = total_len - correct_index*MAX_INDEX56            correct_len = total_len - correct_index*MAX_INDEX
57            return INTERVAL_VALUE_DICT[correct_len]57            return INTERVAL_VALUE_DICT[correct_len]
58        58        
59    def __sub__(self,other):59    def __sub__(self,other):
60        if isinstance(other,Tone):60        if isinstance(other,Tone):
61            raise TypeError("Invalid operation")61            raise TypeError("Invalid operation")
62        62        
63    def __neg__(self):63    def __neg__(self):
64        return Interval(-self.lenght)64        return Interval(-self.lenght)
6565
66class Chord:66class Chord:
67    def __init_sorted_tones(self):67    def __init_sorted_tones(self):
68        main_index = self.main_tone.get_index()68        main_index = self.main_tone.get_index()
69        tones_dict = {self.main_tone.name : main_index}69        tones_dict = {self.main_tone.name : main_index}
70        for tone_name in self.unique_tones:70        for tone_name in self.unique_tones:
71            tone_index = Tone.get_index_for_name(tone_name)71            tone_index = Tone.get_index_for_name(tone_name)
72            if main_index > tone_index:72            if main_index > tone_index:
73                tones_dict[tone_name] = tone_index + 1073                tones_dict[tone_name] = tone_index + 10
74            else:74            else:
75                tones_dict[tone_name] = tone_index75                tones_dict[tone_name] = tone_index
76        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]76        self.sorted_tones = [key for key, value in sorted(tones_dict.items(), key=lambda item: item[1])]
7777
78    def __init__(self, main_tone, *tones):78    def __init__(self, main_tone, *tones):
79        self.main_tone = main_tone79        self.main_tone = main_tone
80        self.unique_tones= set()80        self.unique_tones= set()
81        self.sorted_tones = []81        self.sorted_tones = []
82        self.unique_tones.add(main_tone.name)82        self.unique_tones.add(main_tone.name)
83        for tone in tones:83        for tone in tones:
84                self.unique_tones.add(tone.name)            84                self.unique_tones.add(tone.name)            
8585
86        valid_len = len(self.unique_tones)86        valid_len = len(self.unique_tones)
87        if valid_len <= 1:87        if valid_len <= 1:
88            raise TypeError(f"Cannot have a chord made of only {valid_len} unique tone")88            raise TypeError(f"Cannot have a chord made of only {valid_len} unique tone")
89        self.unique_tones.discard(main_tone.name)89        self.unique_tones.discard(main_tone.name)
90        self.__init_sorted_tones()90        self.__init_sorted_tones()
91        91        
92    def __add__(self, other):92    def __add__(self, other):
93        if isinstance(other, Tone):93        if isinstance(other, Tone):
94            self.unique_tones.add(other.name)94            self.unique_tones.add(other.name)
95        if isinstance(other,Chord):95        if isinstance(other,Chord):
96            for tone_name in other.sorted_tones:96            for tone_name in other.sorted_tones:
97                self.unique_tones.add(tone_name)97                self.unique_tones.add(tone_name)
98        return self98        return self
9999
100    100    
101    def __sub__(self, other):101    def __sub__(self, other):
102        if not other.name in self.sorted_tones:102        if not other.name in self.sorted_tones:
103            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")103            raise TypeError(f"Cannot remove tone {other.name} from chord {self}")
104        if len(self.unique_tones) < 2:104        if len(self.unique_tones) < 2:
105            raise TypeError("Cannot have a chord made of only 1 unique tone")105            raise TypeError("Cannot have a chord made of only 1 unique tone")
106        if isinstance(other, Tone):106        if isinstance(other, Tone):
107            if self.main_tone.name == other.name:107            if self.main_tone.name == other.name:
108                self.main_tone = Tone(self.sorted_tones[0])108                self.main_tone = Tone(self.sorted_tones[0])
109                self.unique_tones.discard(self.main_tone.name)109                self.unique_tones.discard(self.main_tone.name)
110            else:110            else:
111                self.unique_tones.discard(other.name)111                self.unique_tones.discard(other.name)
112        return self            112        return self            
113113
114    def __str__(self):    114    def __str__(self):    
115        self.__init_sorted_tones()115        self.__init_sorted_tones()
116        return "-".join(self.sorted_tones)116        return "-".join(self.sorted_tones)
117    117    
118    def is_minor(self):118    def is_minor(self):
119        main_index = self.main_tone.get_index()119        main_index = self.main_tone.get_index()
120        for tone_name in self.unique_tones:120        for tone_name in self.unique_tones:
121            tone_index = Tone.get_index_for_name(tone_name)121            tone_index = Tone.get_index_for_name(tone_name)
122            interval = Interval(abs(main_index - tone_index))122            interval = Interval(abs(main_index - tone_index))
123            if str(interval) == "minor 3rd":123            if str(interval) == "minor 3rd":
124                return True124                return True
125        return False125        return False
126    126    
127    def is_major(self):127    def is_major(self):
128        main_index = self.main_tone.get_index()128        main_index = self.main_tone.get_index()
129        for tone_name in self.unique_tones:129        for tone_name in self.unique_tones:
130            tone_index = Tone.get_index_for_name(tone_name)130            tone_index = Tone.get_index_for_name(tone_name)
131            interval = Interval(abs(main_index - tone_index))131            interval = Interval(abs(main_index - tone_index))
132            if str(interval) == "major 3rd":132            if str(interval) == "major 3rd":
133                return True133                return True
134        return False134        return False
135    135    
136    def is_power_chord(self):136    def is_power_chord(self):
137        return not self.is_major() and not self.is_minor() 137        return not self.is_major() and not self.is_minor() 
138    138    
t139    def transposed(self,interval):t139    def transposed(self, interval):
140        transposing = interval.lenght140        transposing = interval.lenght
141        transposed_tones = []141        transposed_tones = []
142        tone_name_transposed = ""142        tone_name_transposed = ""
143        for tone_name in self.sorted_tones:143        for tone_name in self.sorted_tones:
144            index = Tone.get_index_for_name(tone_name)144            index = Tone.get_index_for_name(tone_name)
145            if(transposing >= 0):145            if(transposing >= 0):
146                tone_name_transposed = (TONE_VALUE_DICT[index + transposing])146                tone_name_transposed = (TONE_VALUE_DICT[index + transposing])
147            else:147            else:
148                if(index + transposing < 0):148                if(index + transposing < 0):
149                    tone_name_transposed = (TONE_VALUE_DICT[index + transposing + MAX_INDEX])149                    tone_name_transposed = (TONE_VALUE_DICT[index + transposing + MAX_INDEX])
150                else:150                else:
151                    tone_name_transposed = (TONE_VALUE_DICT[index + transposing])151                    tone_name_transposed = (TONE_VALUE_DICT[index + transposing])
152152
153153
154            transposed_tones.append(Tone(tone_name_transposed))154            transposed_tones.append(Tone(tone_name_transposed))
155155
156        return Chord(transposed_tones[0], *transposed_tones[1:])156        return Chord(transposed_tones[0], *transposed_tones[1:])
157 157 
158158
159159
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op