1+ #python3
2+ import sys
3+ from tkinter import *
4+ from collections import OrderedDict
5+
6+
7+ # This program creates a guitar scale gui from grid elements, and fills them in color-coded appropriately.
8+
9+ # Get Note name from a 0-11 INT
10+ def getnotename (tonename ):
11+ notedict = ['E ' , 'F ' , 'F#' , 'G ' , 'Ab' ,
12+ 'A ' , 'Bb' , 'B ' , 'C ' , 'Db' , 'D ' , 'Eb' ]
13+ return notedict [tonename % 12 ]
14+
15+
16+ # Contains int offsets, based on note string, added for convenience, which
17+ # is simply offset relative to C.
18+ def getoffset_tonename (tonename ):
19+ scaleref = {
20+ 'E ' : 0 , 'F ' : 1 , 'F#' : 2 , 'G ' : 3 , 'Ab' : 4 , 'A ' : 5 , 'Bb' : 6 , 'B ' : 7 , 'C ' : 8 , 'Db' : 9 , 'D ' : 10 ,
21+ 'Eb' : 11 }
22+
23+
24+ return scaleref [tonename ]
25+
26+
27+ # Return array that is rotated circular
28+ def rotate (l , n ):
29+ return l [- n :] + l [:- n ]
30+
31+
32+ scales = OrderedDict ([
33+ ('Major' , [0 , 2 , 2 , 1 , 2 , 2 , 2 , 1 ]),
34+ ('Natural minor' , [0 , 2 , 1 , 2 , 2 , 1 , 2 , 2 ]),
35+ ('Harmonic minor' , [0 , 2 , 1 , 2 , 2 , 1 , 3 , 1 ]),
36+ ('Melodic minor' , [0 , 2 , 1 , 2 , 2 , 2 , 2 , 2 ]),
37+ ('Dorian mode' , [0 , 2 , 1 , 2 , 2 , 2 , 1 , 2 ]),
38+ ('Phrygian mode' , [0 , 1 , 2 , 2 , 2 , 1 , 2 , 2 ]),
39+ ('Lydian mode' , [0 , 2 , 2 , 2 , 1 , 2 , 2 , 1 ]),
40+ ('Mixolydian mode' , [0 , 2 , 2 , 1 , 2 , 2 , 1 , 2 ]),
41+ ('Locrian mode' , [0 , 1 , 2 , 2 , 1 , 2 , 2 , 2 ]),
42+ ('Ahava raba mode' , [0 , 1 , 3 , 1 , 2 , 1 , 2 , 2 ]),
43+ ('Minor pentatonic' , [0 , 3 , 2 , 2 , 3 , 2 ]),
44+ ('Pentatonic' , [0 , 2 , 2 , 3 , 2 , 3 ]),
45+ ('Blues' , [0 , 3 , 2 , 1 , 1 , 3 ]),
46+ ('5 chord' , [0 , 7 ]),
47+ ('Major chord' , [0 , 4 , 3 ]),
48+ ('Minor chord' , [0 , 3 , 4 ]),
49+ ('Diminished chord' , [0 , 3 , 3 ]),
50+ ('Augmented chord' , [0 , 4 , 4 ]),
51+ ('Sus2 chord' , [0 , 2 , 5 ]),
52+ ('Sus4 chord' , [0 , 5 , 2 ]),
53+ ('Maj7 chord' , [0 , 4 , 3 , 4 ]),
54+ ('min7 chord' , [0 , 3 , 4 , 3 ]),
55+ ('7 chord' , [0 , 4 , 3 , 3 ]),
56+ ('min7b5 chord' , [0 , 3 , 3 , 4 ]),
57+ ('dim7 chord' , [0 , 3 , 3 , 3 ]),
58+ ('9 chord' , [0 , 4 , 3 , 3 , 4 ]),
59+ ('Maj9 chord' , [0 , 4 , 3 , 4 , 3 ]),
60+ ('m9 chord' , [0 , 3 , 4 , 3 , 4 ]),
61+ ('11 chord' , [0 , 4 , 3 , 3 , 4 , 3 ]),
62+ ('Maj11 chord' , [0 , 4 , 3 , 4 , 3 , 3 ]),
63+ ('min11 chord' , [0 , 3 , 4 , 3 , 4 , 3 ]),
64+ ])
65+
66+ # returns a scale of 16 notes, from the key tonic + 24
67+
68+
69+ def makescale (keyroot , keyopt ):
70+ keywheel = []
71+ keywheel .extend (scales [keyopt ])
72+ filler = 0
73+ # fill array with 16 notes relevant to key and option.
74+ ourscale = []
75+ lenvar = len (keywheel ) # of notes we use (2 octaves of key notes)
76+ for inte in range (lenvar ):
77+ filler += keywheel [inte % len (keywheel )]
78+ ourscale .append (int (filler + getoffset_tonename (keyroot )))
79+ return ourscale
80+
81+
82+ # fetches a default scale
83+ ourscale = makescale ('E ' , 'Major' )
84+
85+ # Used for note offsets
86+ e = 0
87+
88+ # high e = (e+4), b = (e-1), g = (e+7), d = (e+2),a = (e+9), low e = (e+4)
89+ # added to each string to offset and identify the notes.
90+ offsetArray = [e , e + 7 , e + 3 , e + 10 , e + 5 , e ]
91+
92+ # default e Major
93+ chartgui = Tk ()
94+
95+ # our callback variables that change when menu options are selected
96+ variable = StringVar (chartgui )
97+ variable .set ('E ' )
98+ variable2 = StringVar (chartgui )
99+ variable2 .set ('Major' )
100+
101+
102+ # variable3 = StringVar(chartgui)
103+ # variable3.set('View 1')
104+
105+
106+ # for clearing all our values, used for the "Reset" button.
107+ def resettable ():
108+ print ("Tried to reset!" )
109+ for i in range (0 , 25 ):
110+ for gss in range (0 , 6 ):
111+ Label (chartgui , text = getnotename (i + offsetArray [gss ]), bg = 'tan' ).grid (
112+ row = gss + 2 , column = i + 1 , padx = 0 , pady = 0 )
113+
114+
115+ # redraw our whole scale, the action for the "Apply" button
116+ def applyit (val ):
117+ print ("Trying to apply!" )
118+ # print("var1 = %s"%variable.get())
119+ # print("var2 = %s"%variable2.get())
120+ # print("var3 = %s"%variable3.get())
121+ ourtonic = str (variable .get ())
122+ ourkey = str (variable2 .get ())
123+ print (ourtonic )
124+ print (ourkey )
125+
126+ ourscale = makescale (ourtonic , ourkey )
127+ print (ourscale )
128+ ournotes = []
129+
130+ for notes in ourscale :
131+ ournotes .append (getnotename (notes ))
132+
133+ print (ournotes )
134+
135+ # draw our whole scale
136+ for i in range (0 , 25 ):
137+ for gss in range (0 , 6 ):
138+ start = offsetArray [gss ]
139+
140+ # draw lawngreen for roots
141+ if ourtonic == getnotename (i + start % 12 ):
142+ Label (
143+ chartgui , text = getnotename (i + start ), bg = 'lawngreen' ).grid (row = gss + 2 , column = i + 1 ,
144+ padx = 0 , pady = 0 )
145+ # draw cyan for notes in the scale
146+ elif getnotename (i + start ) in ournotes :
147+ Label (
148+ chartgui , text = getnotename (i + start ), bg = 'cyan' ).grid (row = gss + 2 , column = i + 1 ,
149+ padx = 0 , pady = 0 )
150+ # only write notename
151+ else :
152+ Label (chartgui , text = getnotename (i + start ), bg = 'tan' ).grid (
153+ row = gss + 2 , column = i + 1 , padx = 0 , pady = 0 )
154+
155+
156+ if __name__ == "__main__" :
157+
158+ chartgui .geometry ('700x300+400+300' )
159+ chartgui .title ('Guitarex- Playing Made Easier ' )
160+ chartgui .configure (bg = 'tan' )
161+ ourx = 40
162+ oury = 20
163+ chartgui .iconbitmap (r'C:\Users\Aryan\Downloads\IMG_20200108_094316_201.jpg' )
164+
165+ # For our fret (column) labels on top and bottom
166+ for i in range (0 , 25 ):
167+ Label (chartgui , text = i , font = 'boulder' , bg = 'tan' ).grid (
168+ row = 0 , column = i + 1 , padx = 0 , pady = 10 )
169+ Label (chartgui , text = i , font = 'boulder' , bg = 'tan' ).grid (
170+ row = 9 , column = i + 1 , padx = 0 , pady = 10 )
171+
172+ # For our string (row) labels
173+ stringarray = ['E' , 'B' , 'G' , 'D' , 'A' , 'E' ]
174+ for gss in range (0 , 6 ):
175+ Label (chartgui , text = stringarray [gss ], font = "comicsans" , bg = 'tan' ).grid (
176+ row = gss + 2 , column = 0 , padx = 10 , pady = 0 )
177+
178+ print (ourscale )
179+
180+ # draw our whole scale
181+ applyit ("" )
182+
183+ keymenu = OptionMenu (
184+ chartgui , variable , 'E ' , 'F ' , 'F#' , 'G ' , 'Ab' , 'A ' , 'Bb' , 'B ' , 'C ' , 'Db' , 'D ' ,
185+ 'Eb' , command = applyit ).place (x = ourx * 4 , y = oury * 13 )
186+ scalemenu = OptionMenu (chartgui , variable2 , * scales .keys (), command = applyit ).place (
187+ x = ourx * 6 , y = oury * 13 )
188+ resetbutton = Button (chartgui , text = ' Reset ' , command = resettable ).place (
189+ x = ourx * 10 , y = oury * 13 )
190+
191+ chartgui .mainloop ()
0 commit comments