I’m looking for some code improvement, or a pre-built version of what I’ve implemented myself as I think there might be, or should be, a cleaner way to achieve what I want.
I’m writing a piece of software to convert guitar tabs into classical notation, I need to convert the number on a tab to it’s corresponding note and it would be useful for building a list of each strings note from the starting string.
I have a list of notes, (a – g#) and a list of frets (0, 21).
Notes[fret] works fine for the first eleven notes but after that I obviously get an out of index error.
The code I have to get around this is here:
notes = ["a", "a#", "b", "c", "c#", "d", "e", "f", "f#", "g", "g#"]
note = 21
while note >= len(notes):
note -= 11
try:
print notes<div class="su-note" style="border-color:#e5e54c;border-radius:3px"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#FFFF66;border-color:#ffffff;color:#333333;border-radius:3px"></div></div>
except:
continue
It works but it seems a little long, is there a better way to do this?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Use the % operator to produce a modulus:
notes<div class="su-note" style="border-color:#e5e54c;border-radius:3px"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#FFFF66;border-color:#ffffff;color:#333333;border-radius:3px"></div></div>
Demo:
>>> notes = ["a", "a#", "b", "c", "c#", "d", "e", "f", "f#", "g", "g#"] >>> note = 21 >>> notes<div class="su-note" style="border-color:#e5e54c;border-radius:3px"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#FFFF66;border-color:#ffffff;color:#333333;border-radius:3px"></div></div> 'g#'
or in a loop:
>>> for note in range(22): ... print notes<div class="su-note" style="border-color:#e5e54c;border-radius:3px"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#FFFF66;border-color:#ffffff;color:#333333;border-radius:3px"></div></div>, ... a a# b c c# d e f f# g g# a a# b c c# d e f f# g g#
Method 2
Another options is to use itertools.cycle
>>> import itertools
>>> notes = ["a", "a#", "b", "c", "c#", "d", "e", "f", "f#", "g", "g#"]
>>> frets = range(21)
>>> for note, fret in itertools.izip(itertools.cycle(notes), frets):
print ("[%s, %d]" %(note, fret))
[a, 0]
[a#, 1]
[b, 2]
[c, 3]
[c#, 4]
[d, 5]
[e, 6]
[f, 7]
[f#, 8]
[g, 9]
[g#, 10]
[a, 11]
[a#, 12]
[b, 13]
[c, 14]
[c#, 15]
[d, 16]
[e, 17]
[f, 18]
[f#, 19]
[g, 20]
Method 3
Use the modulo operator:
In [3]: notes = ["a", "a#", "b", "c", "c#", "d", "e", "f", "f#", "g", "g#"] In [4]: len(notes) Out[4]: 11 In [5]: note = 11 In [6]: notes<div class="su-note" style="border-color:#e5e54c;border-radius:3px"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#FFFF66;border-color:#ffffff;color:#333333;border-radius:3px"></div></div> --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-6-707e7e351463> in <module>() ----> 1 notes<div class="su-note" style="border-color:#e5e54c;border-radius:3px"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#FFFF66;border-color:#ffffff;color:#333333;border-radius:3px"></div></div> IndexError: list index out of range In [7]: notes<div class="su-note" style="border-color:#e5e54c;border-radius:3px"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#FFFF66;border-color:#ffffff;color:#333333;border-radius:3px"></div></div> Out[7]: 'a' In [8]: notes[note-11] Out[8]: 'a'
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0