In [1]:
def modBase1(num, base):
    return ((num - 1) % base) + 1
modBase1(13, 12)
modBase1(15, 12)
modBase1(14, 12)


Out[1]:
2

In [2]:
notes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

note_to_num_hash = {}
num_to_note_hash = {}
num_to_note_hash['normal'] = {}
num_to_note_hash['flat'] = {}
num_to_note_hash['sharp'] = {}
#normals 
note_to_num_hash['C'] = 1
num_to_note_hash['normal'][1] = 'C'
note_to_num_hash['D'] = 3
num_to_note_hash['normal'][3] = 'D'
note_to_num_hash['E'] = 5
num_to_note_hash['normal'][5] = 'E'
note_to_num_hash['F'] = 6
num_to_note_hash['normal'][6] = 'F'
note_to_num_hash['G'] = 8
num_to_note_hash['normal'][8] = 'G'
note_to_num_hash['A'] = 10
num_to_note_hash['normal'][10] = 'A'
note_to_num_hash['B'] = 12
num_to_note_hash['normal'][12] = 'B'

#sharps                      # zero index for the mod
note_to_num_hash['C#'] = modBase1(note_to_num_hash['C'] + 1, 12)
num_to_note_hash['sharp'][ modBase1(note_to_num_hash['C'] + 1, 12)] = 'C#'
note_to_num_hash['D#'] = modBase1(note_to_num_hash['D'] + 1, 12)
num_to_note_hash['sharp'][modBase1(note_to_num_hash['D'] + 1, 12)] = 'D#'
note_to_num_hash['E#'] = modBase1(note_to_num_hash['E'] + 1, 12)
num_to_note_hash['sharp'][modBase1(note_to_num_hash['E'] + 1, 12)] = 'E#'
note_to_num_hash['F#'] = modBase1(note_to_num_hash['F'] + 1, 12)
num_to_note_hash['sharp'][modBase1(note_to_num_hash['F'] + 1, 12)] = 'F#'
note_to_num_hash['G#'] = modBase1(note_to_num_hash['G'] + 1, 12)
num_to_note_hash['sharp'][modBase1(note_to_num_hash['G'] + 1, 12)] = 'G#'
note_to_num_hash['A#'] = modBase1(note_to_num_hash['A'] + 1, 12)
num_to_note_hash['sharp'][modBase1(note_to_num_hash['A'] + 1, 12)] = 'A#'
note_to_num_hash['B#'] = modBase1(note_to_num_hash['B'] + 1, 12)
num_to_note_hash['sharp'][modBase1(note_to_num_hash['B'] + 1, 12)] = 'B#'

#flats
note_to_num_hash['Cb'] = modBase1(note_to_num_hash['C'] - 1, 12)
num_to_note_hash['flat'][modBase1(note_to_num_hash['C'] - 1, 12)] = 'Cb'
note_to_num_hash['Db'] = modBase1(note_to_num_hash['D'] - 1, 12)
num_to_note_hash['flat'][modBase1(note_to_num_hash['D'] - 1, 12)] = 'Db'
note_to_num_hash['Eb'] = modBase1(note_to_num_hash['E'] - 1, 12)
num_to_note_hash['flat'][modBase1(note_to_num_hash['E'] - 1, 12)] = 'Eb'
note_to_num_hash['Fb'] = modBase1(note_to_num_hash['F'] - 1, 12)
num_to_note_hash['flat'][modBase1(note_to_num_hash['F'] - 1, 12)] = 'Fb'
note_to_num_hash['Gb'] = modBase1(note_to_num_hash['G'] - 1, 12)
num_to_note_hash['flat'][modBase1(note_to_num_hash['G'] - 1, 12)] = 'Gb'
note_to_num_hash['Ab'] = modBase1(note_to_num_hash['A'] - 1, 12)
num_to_note_hash['flat'][modBase1(note_to_num_hash['A'] - 1, 12)] = 'Ab'
note_to_num_hash['Bb'] = modBase1(note_to_num_hash['B'] - 1, 12)
num_to_note_hash['flat'][modBase1(note_to_num_hash['B'] - 1, 12)] = 'Bb'

note_to_num_hash


Out[2]:
{'A': 10,
 'A#': 11,
 'Ab': 9,
 'B': 12,
 'B#': 1,
 'Bb': 11,
 'C': 1,
 'C#': 2,
 'Cb': 12,
 'D': 3,
 'D#': 4,
 'Db': 2,
 'E': 5,
 'E#': 6,
 'Eb': 4,
 'F': 6,
 'F#': 7,
 'Fb': 5,
 'G': 8,
 'G#': 9,
 'Gb': 7}

In [3]:
def note_to_num(note):
    return note_to_num_hash[note]

print(note_to_num('C#'))
print(note_to_num('Fb'))


2
5

In [4]:
def num_to_note(num, kind='normal'):
    normalized_num = ((num - 1) % 12) + 1
    normal = num_to_note_hash['normal'].get(normalized_num)
    sharp = num_to_note_hash['sharp'].get(normalized_num)
    flat = num_to_note_hash['flat'].get(normalized_num)
    if (kind == 'sharp' and sharp != None):
        return sharp
    elif (kind == 'flat' and flat != None):
        return flat
    # We default to sharp if it's not a normal note
    elif (normal == None):
        return sharp
    else:
        return normal
    
print(num_to_note(4, 'sharp'))
print(num_to_note(4, 'flat'))
print(num_to_note(6, 'sharp'))
#print(num_to_note(4))


D#
Eb
E#

In [5]:
def notes_for_nums(nums, kind='normal'):
    return list(map(
        lambda num: num_to_note(num, kind),
        nums
    ))
notes_for_nums([1, 5, 8])


Out[5]:
['C', 'E', 'G']

In [6]:
intervals = {}
# returns the number of halfsteps between the base note and the other note of the interval
intervals['prime'] = 0
intervals['minor 2'] = 1
intervals['major 2'] = 2
intervals['minor 3'] = 3
intervals['major 3'] = 4
intervals['perfect 4'] = 5
intervals['tritone'] = 6
intervals['perfect 5'] = 7
intervals['minor 6'] = 8
intervals['major 6'] = 9
intervals['minor 7'] = 10
intervals['major 7'] = 11
intervals['octave'] = 12
intervals['minor 9'] = 13
intervals['major 9'] = 14
# min 10 - 14
# maj 10- 15
intervals['minor 11'] = 16
intervals['major 11'] = 17
# min 12

In [7]:
scales = {}
scales['Major'] = ['major 2', 'major 2', 'minor 2', 'major 2', 'major 2', 'major 2', 'major 2', 'minor 2']

In [8]:
chord_quality = {}
chord_quality[''] = ['prime', 'major 3', 'perfect 5']
chord_quality['maj7'] = ['prime', 'major 3', 'perfect 5', 'major 7']
chord_quality['-7'] = ['prime', 'minor 3', 'perfect 5', 'minor 7']
chord_quality['7'] = ['prime', 'major 3', 'perfect 5', 'minor 7']
chord_quality['7b9'] = ['prime', 'major 3','minor 7', 'minor 9']
chord_quality['6'] = ['prime', 'major 3', 'perfect 5', 'major 6']

In [9]:
def chromatic_scale_from(note=1):
    return list(map(lambda x: modBase1(x, 12), range(note, note+12)))

print(chromatic_scale_from(1))
print(chromatic_scale_from(3))
print(chromatic_scale_from(30))


[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]
[6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5]

In [10]:
def lookup_multi(keys, lookupable):
    return list(map(
        lambda key: lookupable[key]
        , keys
    ))

In [11]:
def nums_for_quality(quality='', base_note='C'):
    quality_intervals = chord_quality[quality]
    nums = lookup_multi(quality_intervals, intervals)
    adjusted = list(map(lambda x: x + note_to_num(base_note)
                       , nums))
    return adjusted

print(nums_for_quality(base_note='D'))
print(notes_for_nums(nums_for_quality(base_note='D')))
print(nums_for_quality(base_note='Eb', quality='maj7'))
print(notes_for_nums(nums_for_quality(base_note='Eb', quality='maj7'), kind='flat'))
print(nums_for_quality(base_note='Cb', quality='-7'))


[3, 7, 10]
['D', 'F#', 'A']
[4, 8, 11, 15]
['Eb', 'G', 'Bb', 'D']
[12, 15, 19, 22]

In [12]:
for quality in chord_quality:
    print(quality + ' - ' + str(nums_for_quality(quality=quality)))


 - [1, 5, 8]
maj7 - [1, 5, 8, 12]
-7 - [1, 4, 8, 11]
7 - [1, 5, 8, 11]
7b9 - [1, 5, 11, 14]
6 - [1, 5, 8, 10]

In [13]:
nums_for_quality(base_note='Eb', quality='maj7')


Out[13]:
[4, 8, 11, 15]

In [14]:
def string_for(note='E', frets=18):
    baseNum = note_to_num(note)
    nums = list(range(baseNum, baseNum + frets))
    return nums

print(string_for(note='E'))
print(string_for(note='B'))
print(string_for(note='G'))
print(string_for(note='D'))
print(string_for(note='A'))
print(string_for(note='E'))


[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
[12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]

In [15]:
def contains(my_list, val):
    if val in my_list:
        return True
    return False

In [16]:
def print_string(nums, lookup_fn, formatter_fn):
    base_print = str(num_to_note(nums[0]))
    # first string gets printed a bit differntly
    firstString = True
    for num in nums[1:]:
        base_print = base_print + '|'
        for_num = lookup_fn(num)
        base_print = base_print + formatter_fn(for_num)
    return base_print

c7nums = nums_for_quality('maj7', base_note='D')

print(print_string(string_for('E')
             , lambda num: num_to_note(num) if contains(c7nums, num % 13) else ''
             , lambda val: '{:-^5}'.format(val)
            ))


E|-----|-F#--|-----|-----|--A--|-----|-----|-----|-----|-----|-D#--|-----|-----|-----|--G--|-----|-----

In [17]:
def strings_for_chord(base_note='C', quality='', kind='normal', tuning=['E', 'A', 'D', 'G', 'B', 'E']):
    chord_nums = [modBase1(num, 12) for num in nums_for_quality(quality=quality, base_note=base_note)]
    print(notes_for_nums(chord_nums, kind=kind))
    lookup_fn = lambda num: num_to_note(num, kind=kind) if contains(chord_nums, modBase1(num, 12)) else ''
    formatter_fn = lambda val: '{:-^5}'.format(val)
    strings = []
    for note in reversed(tuning):
        strings.append(print_string(string_for(note), lookup_fn, formatter_fn))
    return strings

strings_for_chord(quality='maj7')


['C', 'E', 'G', 'B']
Out[17]:
['E|-----|-----|--G--|-----|-----|-----|--B--|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----',
 'B|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----|-----|--B--|--C--|-----|-----|-----|--E--',
 'G|-----|-----|-----|--B--|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----|-----|--B--|--C--',
 'D|-----|--E--|-----|-----|--G--|-----|-----|-----|--B--|--C--|-----|-----|-----|--E--|-----|-----|--G--',
 'A|-----|--B--|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----|-----|--B--|--C--|-----|-----',
 'E|-----|-----|--G--|-----|-----|-----|--B--|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----']

In [18]:
space = '{: ^5}'.format('')
dot = '{: ^5}'.format('o')
doubleDot = '{: ^5}'.format('oo')

def dotsFor(frets=18):
    acc = '  '
    for i in range(1, frets):
        if (
            False
            #or i == 3
            or i == 5
            or i == 7
            or i == 15
        ):
            acc = acc + dot
        elif (i == 12):
            acc = acc + doubleDot
        else:
            acc = acc + space
        acc = acc + ' '
    return acc
print(dotsFor())


                            o           o                            oo                 o               

In [19]:
def numsFor(frets=18):
    acc = '  '
    for i in range(1, frets):
        acc = acc + '{: ^6}'.format(i)
    return acc
print(numsFor())


    1     2     3     4     5     6     7     8     9     10    11    12    13    14    15    16    17  

In [20]:
c7nums = nums_for_quality('maj7', base_note='D')


def print_fretboard(strings, frets=18, dots=True, numbers=True):
    guitar = ''
    if (dots):
        strings.append(dotsFor(frets))
    if (numbers):
        strings.insert(0, numsFor(frets))
    for string in strings:
        guitar = guitar + string + '\n'
    return guitar
strings_for_chord()
#print(print_fretboard(strings_for_chord()))


['C', 'E', 'G']
Out[20]:
['E|-----|-----|--G--|-----|-----|-----|-----|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----',
 'B|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----|-----|-----|--C--|-----|-----|-----|--E--',
 'G|-----|-----|-----|-----|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----|-----|-----|--C--',
 'D|-----|--E--|-----|-----|--G--|-----|-----|-----|-----|--C--|-----|-----|-----|--E--|-----|-----|--G--',
 'A|-----|-----|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----|-----|-----|--C--|-----|-----',
 'E|-----|-----|--G--|-----|-----|-----|-----|--C--|-----|-----|-----|--E--|-----|-----|--G--|-----|-----']

In [21]:
print(print_fretboard(strings_for_chord(base_note='D', quality='maj7')))


['D', 'F#', 'A', 'C#']
    1     2     3     4     5     6     7     8     9     10    11    12    13    14    15    16    17  
E|-----|-F#--|-----|-----|--A--|-----|-----|-----|-C#--|--D--|-----|-----|-----|-F#--|-----|-----|--A--
B|-----|-C#--|--D--|-----|-----|-----|-F#--|-----|-----|--A--|-----|-----|-----|-C#--|--D--|-----|-----
G|-----|--A--|-----|-----|-----|-C#--|--D--|-----|-----|-----|-F#--|-----|-----|--A--|-----|-----|-----
D|-----|-----|-----|-F#--|-----|-----|--A--|-----|-----|-----|-C#--|--D--|-----|-----|-----|-F#--|-----
A|-----|-----|-----|-C#--|--D--|-----|-----|-----|-F#--|-----|-----|--A--|-----|-----|-----|-C#--|--D--
E|-----|-F#--|-----|-----|--A--|-----|-----|-----|-C#--|--D--|-----|-----|-----|-F#--|-----|-----|--A--
                            o           o                            oo                 o               


In [22]:
print(print_fretboard(strings_for_chord(base_note='Eb', quality='7b9', kind='flat')))


['Eb', 'G', 'Db', 'Fb']
    1     2     3     4     5     6     7     8     9     10    11    12    13    14    15    16    17  
E|-----|-----|--G--|-----|-----|-----|-----|-----|-Db--|-----|-Eb--|-Fb--|-----|-----|--G--|-----|-----
B|-----|-Db--|-----|-Eb--|-Fb--|-----|-----|--G--|-----|-----|-----|-----|-----|-Db--|-----|-Eb--|-Fb--
G|-----|-----|-----|-----|-----|-Db--|-----|-Eb--|-Fb--|-----|-----|--G--|-----|-----|-----|-----|-----
D|-Eb--|-Fb--|-----|-----|--G--|-----|-----|-----|-----|-----|-Db--|-----|-Eb--|-Fb--|-----|-----|--G--
A|-----|-----|-----|-Db--|-----|-Eb--|-Fb--|-----|-----|--G--|-----|-----|-----|-----|-----|-Db--|-----
E|-----|-----|--G--|-----|-----|-----|-----|-----|-Db--|-----|-Eb--|-Fb--|-----|-----|--G--|-----|-----
                            o           o                            oo                 o               


In [23]:
print(print_fretboard(strings_for_chord(base_note='C', quality='7b9', kind='flat')))


['C', 'Fb', 'Bb', 'Db']
    1     2     3     4     5     6     7     8     9     10    11    12    13    14    15    16    17  
E|-----|-----|-----|-----|-----|-Bb--|-----|--C--|-Db--|-----|-----|-Fb--|-----|-----|-----|-----|-----
B|--C--|-Db--|-----|-----|-Fb--|-----|-----|-----|-----|-----|-Bb--|-----|--C--|-Db--|-----|-----|-Fb--
G|-----|-----|-Bb--|-----|--C--|-Db--|-----|-----|-Fb--|-----|-----|-----|-----|-----|-Bb--|-----|--C--
D|-----|-Fb--|-----|-----|-----|-----|-----|-Bb--|-----|--C--|-Db--|-----|-----|-Fb--|-----|-----|-----
A|-Bb--|-----|--C--|-Db--|-----|-----|-Fb--|-----|-----|-----|-----|-----|-Bb--|-----|--C--|-Db--|-----
E|-----|-----|-----|-----|-----|-Bb--|-----|--C--|-Db--|-----|-----|-Fb--|-----|-----|-----|-----|-----
                            o           o                            oo                 o               


In [27]:
print(print_fretboard(strings_for_chord(base_note='F', quality='6', kind='flat')))


['F', 'A', 'C', 'D']
    1     2     3     4     5     6     7     8     9     10    11    12    13    14    15    16    17  
E|--F--|-----|-----|-----|--A--|-----|-----|--C--|-----|--D--|-----|-----|--F--|-----|-----|-----|--A--
B|--C--|-----|--D--|-----|-----|--F--|-----|-----|-----|--A--|-----|-----|--C--|-----|--D--|-----|-----
G|-----|--A--|-----|-----|--C--|-----|--D--|-----|-----|--F--|-----|-----|-----|--A--|-----|-----|--C--
D|-----|-----|--F--|-----|-----|-----|--A--|-----|-----|--C--|-----|--D--|-----|-----|--F--|-----|-----
A|-----|-----|--C--|-----|--D--|-----|-----|--F--|-----|-----|-----|--A--|-----|-----|--C--|-----|--D--
E|--F--|-----|-----|-----|--A--|-----|-----|--C--|-----|--D--|-----|-----|--F--|-----|-----|-----|--A--
                            o           o                            oo                 o               


In [25]:



Out[25]:
{1: {'chord-part': 'root'}, 5: {'chord-part': '3rd'}, 8: {'chord-part': '5th'}}

In [26]:
nums_for_quality(base_note='C', quality='')


Out[26]:
[1, 5, 8]

In [ ]: