Advertisement
Guest User

app

a guest
Nov 10th, 2022
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.51 KB | None | 0 0
  1. from random import choice
  2. import PySimpleGUI as sg
  3. from copy import copy
  4. # go into venv to run
  5.  
  6. sg.theme('DarkTeal3')
  7.  
  8. keys = {
  9. "C":["C","D","E","F","G","A","B"], # key of C
  10. "F":["F","G","A","Bb","C","D","E"], # key of F
  11. "G":["G","A","B","C","D","E","F#"], # key of G
  12. "Bb":["Bb","C","D","Eb","F","G","A"], # key of Bb
  13. "D":["D","E","F#","G","A","B","C#"], # key of D
  14. "Eb":["Eb","F","G","Ab","Bb","C","D"], # key of Eb
  15. "A":["A","B","C#","D","E","F#","G#"], # key of A
  16. }
  17.  
  18. # chord inversion practice
  19. inversions_1 = ["no 7", "first inversion no 7", "second inversion no 7"]
  20. inversions_2 = ["no 5", "first inversion no 5", "third inversion no 5"]
  21. inversions_3 = ["no 7", "no 5", "first inversion no 5", "first inversion no 7", "second inversion no 7", "third inversion no 5"]
  22.  
  23. # layout for chord inversion page
  24. chord_inversion_practice = [
  25. [sg.Text("Choose a key:")],
  26. [sg.Radio("Key of C", "radio_1",default=False)],
  27. [sg.Radio("Key of F", "radio_1",default=False)],
  28. [sg.Radio("Key of G", "radio_1",default=False)],
  29. [sg.Radio("Key of Bb", "radio_1",default=False)],
  30. [sg.Radio("Key of D", "radio_1",default=False)],
  31. [sg.Radio("Key of Eb", "radio_1",default=False)],
  32. [sg.Radio("Key of A", "radio_1",default=False)],
  33. [sg.Radio("Random", "radio_1",default=False, key="random_key")],
  34. [sg.Text("Select which inversions you want included:")],
  35. [sg.Radio("No inversion, first, second", "radio_2",default=False, key="no7")],
  36. [sg.Radio("No inversion, first, third", "radio_2",default=False, key="no5")],
  37. [sg.Radio("No inversion, first, second, third", "radio_2",default=False, key="all_invs")],
  38. [sg.Button("Generate Chord"), sg.Button("Easy Mode"), sg.Button("Back")],
  39. [
  40. sg.Text(key="display_key",font=("Courier", 25)),
  41. sg.Text(key="first_half",font=("Courier", 25)),
  42. sg.Text(key="note",font=("Courier", 25)),
  43. sg.Text(key="second_half", font=("Courier",25))
  44. ],
  45. [sg.Text(key='chord',font=("Courier", 25))]
  46. ]
  47.  
  48. # def generate_chord(values):
  49. # # get our key
  50. # if values[0] == True:
  51. # key, scale = "C",keys["C"] #C
  52. # elif values[1] == True:
  53. # key, scale = "F",keys["F"] #F
  54. # elif values[2] == True:
  55. # key, scale = "G",keys["G"] #G
  56. # elif values[3] == True:
  57. # key, scale = "Bb",keys["Bb"] #Bb
  58. # elif values[4] == True:
  59. # key, scale = "D",keys["D"] #D
  60. # elif values[5] == True:
  61. # key, scale = "Eb",keys["Eb"] #Eb
  62. # elif values[6] == True:
  63. # key, scale = "A",keys["A"] #A
  64. # elif values[7] == True: # gets a key/value pair in the form of a tupe (key,value)
  65. # key, scale = choice(list(keys.items()))
  66.  
  67. # # get which inversions to choose from
  68. # if values[8] == True:
  69. # inversion = inversions_1
  70. # elif values[9] == True:
  71. # inversion = inversions_2
  72. # elif values[10] == True:
  73. # inversion = inversions_3
  74. # note = choice(scale)
  75. # return f"{note} {choice(inversion)}", key, ' '.join(scale), note # choose a random note from the key and which inversion
  76.  
  77. # work on this over time to condense and improve everything
  78. def generate_chord(values):
  79. if values["random_key"]:
  80. key, scale = choice(list(keys.items()))
  81. else:
  82. l_keys = ['C','F','G','Bb','D','Eb','A']
  83. for k, s in enumerate(values[:-6]):
  84. if s:
  85. key, scale = l_keys[k], keys[l_keys[k]]
  86. if values["no7"]:
  87. inversion = inversions_1
  88. elif values["no5"]:
  89. inversion = inversions_2
  90. elif values["all_invs"]:
  91. inversion = inversions_3
  92. note = choice(scale)
  93. return f"{note} {choice(inversion)}", key, ' '.join(scale), note # choose a random note from the key and which inversion
  94.  
  95.  
  96.  
  97. # scale practice
  98. scale_mode_practice = [
  99. [sg.Text("Choose a key:")],
  100. [sg.Radio("Key of C", "radio_1",default=False)],
  101. [sg.Radio("Key of F", "radio_1",default=False)],
  102. [sg.Radio("Key of G", "radio_1",default=False)],
  103. [sg.Radio("Key of Bb", "radio_1",default=False)],
  104. [sg.Radio("Key of D", "radio_1",default=False)],
  105. [sg.Radio("Key of Eb", "radio_1",default=False)],
  106. [sg.Radio("Key of A", "radio_1",default=False)],
  107. [sg.Radio("Random", "radio_1",default=False)],
  108. [sg.Text("Choose Diatonic or Pentatonic:")],
  109. [sg.Radio("Diatonic ", "radio_3"),sg.Radio("Pentatonic", "radio_3")],
  110. [sg.Radio("ionnian ", "diatonic_mode"), sg.Radio("major pentatonic", "pentatonic_mode")],
  111. [sg.Radio("dorianc ", "diatonic_mode"), sg.Radio("egyptian", "pentatonic_mode")],
  112. [sg.Radio("phrygian ", "diatonic_mode"), sg.Radio("blues minor", "pentatonic_mode")],
  113. [sg.Radio("lydian ", "diatonic_mode"), sg.Radio("blues major", "pentatonic_mode")],
  114. [sg.Radio("mixolydian", "diatonic_mode"), sg.Radio("minor pentatonic", "pentatonic_mode")],
  115. [sg.Radio("aeolian ", "diatonic_mode"), sg.Radio("Random", "pentatonic_mode")],
  116. [sg.Radio("locrian ", "diatonic_mode")],
  117. [sg.Radio("Random ", "diatonic_mode")],
  118. [sg.Button("Generate Scale"), sg.Button("Hint pls"), sg.Button("Return")],
  119. [sg.Text(key="scale_to_show", font=("Courier",25))],
  120. [sg.Text(key="scale_hint", font=("Courier",25))],
  121. [sg.Text(key="factoid", font=("Courier",18))]
  122. ]
  123.  
  124. diatonics = ["ionian", "dorian", "phrygian", "lydian", "mixolydian", "aeolian", "locrian"]
  125. pentatonics = ["major pentatonic", "egyptian", "blues minor", "blues major", "minor pentatonic"]
  126.  
  127. def generate_scale(values):
  128. if values[11] == True:
  129. key, temp_scale = "C",copy(keys["C"]) #C
  130. elif values[12] == True:
  131. key, temp_scale = "F",copy(keys["F"]) #F
  132. elif values[13] == True:
  133. key, temp_scale = "G",copy(keys["G"]) #G
  134. elif values[14] == True:
  135. key, temp_scale = "Bb",copy(keys["Bb"]) #Bb
  136. elif values[15] == True:
  137. key, temp_scale = "D",copy(keys["D"]) #D
  138. elif values[16] == True:
  139. key, temp_scale = "Eb",copy(keys["Eb"]) #Eb
  140. elif values[17] == True:
  141. key, temp_scale = "A",copy(keys["A"]) #A
  142. elif values[18] == True:
  143. key, temp_scale = copy(choice(list(keys.items())))
  144.  
  145. # if you ever decide to condense this stuff just make a while loop and after choosing random loop back up and go through the modes and combine everything, too lazy to rn. also when you do it itll be if value[x] == true or mode == mode_name
  146. if values[19] == True: # if diatonic was chosen, we will have the rest in this if statement to ignore anything from pentatonic if anything in that column was chosen as an easy workaround
  147. if values[21] == True:
  148. mode = "ionian"
  149. elif values[23] == True:
  150. mode = "dorian"
  151. elif values[25] == True:
  152. mode = "phrygian"
  153. elif values[27] == True:
  154. mode = "lydian"
  155. elif values[29] == True:
  156. mode = "mixolydian"
  157. elif values[31] == True:
  158. mode = "aeolian"
  159. elif values[33] == True:
  160. mode = "locrian"
  161. elif values[34] == True:
  162. mode = choice(diatonics)
  163. # reorder the scale
  164. if mode == "ionian":
  165. scale = temp_scale
  166. note = "original scale"
  167. elif mode == "dorian":
  168. scale = temp_scale[1:]
  169. scale.append(temp_scale[0])
  170. note = "flat 3, flat 7"
  171. elif mode == "phrygian":
  172. scale = temp_scale[2:]
  173. scale.append(temp_scale[0])
  174. scale.append(temp_scale[1])
  175. note = "flat 2, flat 3, flat 6, flat 7"
  176. elif mode == "lydian":
  177. scale = temp_scale[3:]
  178. scale.append(temp_scale[0])
  179. scale.append(temp_scale[1])
  180. scale.append(temp_scale[2])
  181. note = "sharp 4"
  182. elif mode == "mixolydian":
  183. scale = temp_scale[4:]
  184. scale.append(temp_scale[0])
  185. scale.append(temp_scale[1])
  186. scale.append(temp_scale[2])
  187. scale.append(temp_scale[3])
  188. note = "flat 7"
  189. elif mode == "aeolian":
  190. scale = temp_scale[5:]
  191. scale.append(temp_scale[0])
  192. scale.append(temp_scale[1])
  193. scale.append(temp_scale[2])
  194. scale.append(temp_scale[3])
  195. scale.append(temp_scale[4])
  196. note = "flat 3, flat 6, flat 7"
  197. elif mode == "locrian":
  198. scale = temp_scale[6:]
  199. scale.append(temp_scale[0])
  200. scale.append(temp_scale[1])
  201. scale.append(temp_scale[2])
  202. scale.append(temp_scale[3])
  203. scale.append(temp_scale[4])
  204. scale.append(temp_scale[5])
  205. note = "flat 2, flat 3, flat 5, flat 6, flat 7"
  206. scale = ' '.join(scale)
  207.  
  208. elif values[20] == True: # if this is true then we also need to remove specific values from our scale before we do anything with it, take out the 4 and 7
  209. temp_scale.pop(3) # remove the 4
  210. temp_scale.pop() # remove the 7
  211. if values[22] == True:
  212. mode = "major pentatonic"
  213. elif values[24] == True:
  214. mode = "egyptian"
  215. elif values[26] == True:
  216. mode = "blues minor"
  217. elif values[28] == True:
  218. mode = "blues major"
  219. elif values[30] == True:
  220. mode = "minor pentatonic"
  221. elif values[32] == True:
  222. mode = choice(pentatonics)
  223. print(mode)
  224. # reorder the scale
  225. if mode == "major pentatonic":
  226. scale = temp_scale # unchanged
  227. elif mode == "egyptian":
  228. scale = temp_scale[1:]
  229. scale.append(temp_scale[0])
  230. elif mode == "blues minor":
  231. scale = temp_scale[2:]
  232. scale.append(temp_scale[0])
  233. scale.append(temp_scale[1])
  234. elif mode == "blues major":
  235. scale = temp_scale[3:]
  236. scale.append(temp_scale[0])
  237. scale.append(temp_scale[1])
  238. scale.append(temp_scale[2])
  239. elif mode == "minor pentatonic":
  240. scale = temp_scale[4:]
  241. scale.append(temp_scale[0])
  242. scale.append(temp_scale[1])
  243. scale.append(temp_scale[2])
  244. scale.append(temp_scale[3])
  245. scale = ' '.join(scale)
  246. note = ''
  247. return key, scale, mode, note
  248.  
  249.  
  250. # we will use key in the hint, scale is what will be used for cycling
  251. # the keys are values 11 through 18
  252. # diatonic/pent are 19 and 20
  253. # diatonic modes: 21, 23, 25, 27, 29, 31, 33, 34
  254. # pentatonic modes: 22, 24, 26, 28, 30, 32
  255.  
  256. # menu
  257. main_menu = [
  258. [sg.Text('Select a practice tool:')],
  259. [sg.Button('Chord Inversion Practice')],
  260. [sg.Button('Scale Practice')],
  261. [sg.Button('Exit')]
  262. ]
  263.  
  264. layout = [
  265. [sg.Column(main_menu, key="screen_0"),
  266. sg.Column(chord_inversion_practice, key="screen_1",visible=False),
  267. sg.Column(scale_mode_practice, key="screen_2",visible=False)]
  268. ]
  269.  
  270. window = sg.Window("Guitar Inversion Practice Tool", layout,size=(625, 650), font="Courier")
  271.  
  272.  
  273. while True:
  274. event, values = window.read()
  275. if event == "Chord Inversion Practice":
  276. window["screen_0"].update(visible=False)
  277. window["screen_1"].update(visible=True)
  278. if event == "Scale Practice":
  279. window["screen_0"].update(visible=False)
  280. window["screen_2"].update(visible=True)
  281.  
  282.  
  283. if event == "Generate Chord":
  284. # try:
  285. chord_to_play, key_name, scale, note = generate_chord(values)
  286. window['display_key'].update(f'key: {key_name}') # default show on harder mode
  287. window['chord'].update(f'chord: {chord_to_play}')
  288. window['first_half'].update("")
  289. window['note'].update("")
  290. window['second_half'].update("")
  291. # except:
  292. # sg.popup_error("make sure two parameters are selected")
  293. # continue
  294.  
  295. if event == "Generate Scale":
  296. try:
  297. key, scale, mode, note = generate_scale(values)
  298. window["scale_to_show"].update(f"scale: {scale[0:2]} {mode}") # want to show scale: first note mode, hint
  299. window['scale_hint'].update('')
  300. window['factoid'].update('')
  301. except:
  302. sg.popup_error('make sure all necessary parameters are selected')
  303.  
  304. if event == "Hint pls":
  305. try:
  306. window["scale_hint"].update(f"key: {key}\nscale: {scale}")
  307. window['factoid'].update(note)
  308. except:
  309. sg.popup_error("must have a scale already chosen")
  310.  
  311. if event == "Easy Mode":
  312. try:
  313. note_index = scale.index(note) # index of the note
  314. if note_index > 0:
  315. window['display_key'].update("key: ")
  316. window['first_half'].update(scale[:note_index-1])
  317. if note_index == 0:
  318. window['display_key'].update("key:")
  319. window['note'].update(value=scale[note_index:note_index+2], text_color="yellow")
  320. window['second_half'].update(scale[note_index+3:])
  321. except:
  322. sg.popup_error("generate a chord first")
  323. continue
  324.  
  325. # returning back to the menu, idk why i can't use the same word for everything so this is a bit sloppy here but it works
  326. if event == "Back":
  327. window['screen_1'].update(visible=False)
  328. window['screen_0'].update(visible=True)
  329. if event == "Return":
  330. window['screen_2'].update(visible=False)
  331. window['screen_0'].update(visible=True)
  332.  
  333. elif event == sg.WIN_CLOSED or event == "Exit":
  334. break
  335.  
  336. window.close()
  337.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement