Last active
October 10, 2025 12:27
-
-
Save riordant/8f581c14b3488be7ce5eb4ca5b6a0557 to your computer and use it in GitHub Desktop.
Guitar Fretboard Trainer - GuitarNutrition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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