Skip to content

Instantly share code, notes, and snippets.

@riordant
Last active October 10, 2025 12:27
Show Gist options
  • Select an option

  • Save riordant/8f581c14b3488be7ce5eb4ca5b6a0557 to your computer and use it in GitHub Desktop.

Select an option

Save riordant/8f581c14b3488be7ce5eb4ca5b6a0557 to your computer and use it in GitHub Desktop.
Guitar Fretboard Trainer - GuitarNutrition
# Implementation of the method described in https://guitarnutrition.com/blog/the-most-effective-way-to-memorise-notes-on-the-guitar-fretboard
# That is:
# - On Day 1, start with three notes on the Low E string (E, F, F#)
# - The program randomly selects one of the three notes, where you must play it as quickly as you can
# - Do this for 10 minutes
# - On Day 2, check that you know the first three notes with NO HESITATION (if there is ANY hesitation spend another day on the first three notes)
# - If there is no hesitation, add the note G on the Low E string
# - The program randomly selects one of the four notes, where you must play it as quickly as you can
# - Do this for 10 minutes
# - Repeat this process adding ONE new note every day if you can play the previous notes with NO HESITATION
# - Do this for all strings
#
# Code:
# - Choose time - start time of 3 is advised, reduce if it feels too easy, increase if too difficult
# - day: when you become comfortable with the current notes, move to the next day
# - run with: python3 guitar-fretboard-trainer.py
import time
import random
# Notes on each string (open -> 12th fret)
STRING_NOTES = {
" Low E": ["E", "F", "F#", "G", "G#", "A", "A#", "B", "C", "C#", "D", "D#"],
" A": ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"],
" D": ["D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C", "C#"],
" G": ["G", "G#", "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#"],
" B": ["B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#"],
"High E": ["E", "F", "F#", "G", "G#", "A", "A#", "B", "C", "C#", "D", "D#"],
}
STRINGS_ORDER = [" Low E", " A", " D", " G", " B", "High E"]
#### Vars ####
TIME_PER_NOTE = 3 # lower to increase difficulty
LAST_DAY = 1 # write this back after
#### Vars ####
TOTAL_ROUNDS = int(600 / TIME_PER_NOTE) # rounds divided into 10 minutes
def get_notes_for_day(day: int):
"""
Given a day number, return the unlocked (string, note) pairs.
Day 1 starts with 3 notes on Low E. Each day adds one more note,
until 12 notes per string are learned, then the next string starts.
"""
notes_per_string = 12
starting_notes = 3
# Day 1 = 3 notes
total_unlocked_notes = starting_notes + (day - 1)
unlocked_pairs = []
notes_used = 0
for string in STRINGS_ORDER:
if notes_used >= total_unlocked_notes:
break
remaining = total_unlocked_notes - notes_used
notes_here = min(remaining, notes_per_string)
unlocked_pairs.extend([(string, note) for note in STRING_NOTES[string][:notes_here]])
notes_used += notes_here
return unlocked_pairs
def main():
day = int(input(f"Enter the day number (last day: {LAST_DAY}): "))
unlocked = get_notes_for_day(day)
print(f"\nDay {day}: You have unlocked {len(unlocked)} notes")
print("Press Ctrl+C to stop.\n")
rounds = 0
try:
while True:
string, note = random.choice(unlocked)
if len(note) == 1:
print(f"{string}: {note} (round: {rounds}/{TOTAL_ROUNDS})")
else:
print(f"{string}: {note} (round: {rounds}/{TOTAL_ROUNDS})")
time.sleep(TIME_PER_NOTE)
if rounds == TOTAL_ROUNDS:
break
rounds += 1
except KeyboardInterrupt:
print("\nSession ended.")
print(f"Complete.")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment