Python script to test music sight reading
Warning for other reviewers : input and input are different depending on the version of Python you are using. This is about Python 3.



Instead of defining the notes of a clef as a dictionnary mapping consecutive integers from 0 to n to names, you could use a list.

You'll have the much more natural :

TREBLE_CLEF_NOTES = [ 'F', 'E', 'D', 'C', 'B', 'A', 'G', 'F', 'E' ]
BASS_CLEF_NOTES = [ 'A', 'G', 'F', 'E', 'D', 'C', 'B', 'A', 'G' ]


and you just need to change :

def random_note(self):
    return random.choice(range(len(self.notes)))




add_note = i == note_index does not seem useful : get rid of it.



The way you are playing with string slicing to display a note or a line doesn't need to be that complicated. Also, defining values as class members was a nice touch but the fact that you hardcode indices in the logic with the string slicing kind of removes the all point. As for me, I'll keep things simple and not so well organised for the time being as these values are unlikely to be useful for anything else than displaying.

Here's my suggestion :

def display(note_index):
    for i in range(9):
        line_element = '-' if i%2 else ' '
        print(line_element * 4 + ('O' if i == note_index else line_element) + line_element*5)




I have to go, I'll try to add more details later. In the meantime, if you are interested in Python and music theory, you might be interested by this github project.