From cf0d3cf8966edf64754c97db844fccc1af06e443 Mon Sep 17 00:00:00 2001 From: Connor Date: Mon, 29 Sep 2014 21:14:37 -0700 Subject: [PATCH 01/10] --- .dummy | 1 + 1 file changed, 1 insertion(+) create mode 100644 .dummy diff --git a/.dummy b/.dummy new file mode 100644 index 0000000..945c9b4 --- /dev/null +++ b/.dummy @@ -0,0 +1 @@ +. \ No newline at end of file From bb5eabbd5689cc737597a1e4093ed6e597415eba Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Mon, 29 Sep 2014 21:15:51 -0700 Subject: [PATCH 02/10] . --- .dummy | 1 - strings.py | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+), 1 deletion(-) delete mode 100644 .dummy create mode 100755 strings.py diff --git a/.dummy b/.dummy deleted file mode 100644 index 945c9b4..0000000 --- a/.dummy +++ /dev/null @@ -1 +0,0 @@ -. \ No newline at end of file diff --git a/strings.py b/strings.py new file mode 100755 index 0000000..35d1492 --- /dev/null +++ b/strings.py @@ -0,0 +1,198 @@ +#!/usr/bin/python + +mm_to_in = 0.03937 +scale_length = 648*mm_to_in + +string_sets = { + 'regular light': ( + # (desired note, tension, and type) + ('E4' , 16, 'PL'), + ('B3' , 16, 'PL'), + ('G3' , 16, 'PL'), + ('D3' , 16, 'NW'), + ('A2' , 16, 'NW'), + ('E2' , 16, 'NW'), + ), + 'light jazz': ( + ('E4' , 24, 'PL'), + ('B3' , 24, 'PL'), + ('G3' , 24, 'NW'), + ('D3' , 24, 'NW'), + ('A2' , 24, 'NW'), + ('E2' , 24, 'NW'), + ), + 'regular light (DADGAD)': ( + ('D4' , 16, 'PL'), + ('A3' , 16, 'PL'), + ('G3' , 16, 'PL'), + ('D3' , 16, 'NW'), + ('A2' , 16, 'NW'), + ('D2' , 16, 'NW'), + ), + 'open G (6-string)': ( + ('D4' , 16, 'PL'), + ('B3' , 16, 'PL'), + ('G3' , 16, 'PL'), + ('D3' , 16, 'NW'), + ('B2' , 16, 'NW'), + ('D2' , 16, 'NW'), + ), + 'open G (7-string)': ( + ('D4' , 16, 'PL'), + ('B3' , 16, 'PL'), + ('G3' , 16, 'PL'), + ('D3' , 16, 'NW'), + ('B2' , 16, 'NW'), + ('G2' , 16, 'NW'), + ('D2' , 16, 'NW'), + ), +} + +# D'Addario stock via http://www.daddario.com/upload/tension_chart_13934.pdf +stock = ( +# (product name, unit weight) +# plain steel + ('PL007' , .00001085), + ('PL008' , .00001418), + ('PL0085', .00001601), + ('PL009' , .00001794), + ('PL0095', .00001999), + ('PL010' , .00002215), + ('PL0105', .00002442), + ('PL011' , .00002680), + ('PL0115', .00002930), + ('PL012' , .00003190), + ('PL013' , .00003744), + ('PL0135', .00004037), + ('PL014' , .00004342), + ('PL015' , .00004984), + ('PL016' , .00005671), + ('PL017' , .00006402), + ('PL018' , .00007177), + ('PL019' , .00007997), + ('PL020' , .00008861), + ('PL022' , .00010722), + ('PL024' , .00012760), + ('PL027' , .00014975), + +# nickelplated steel round wound (XL) + ('NW017' , .00005524), + ('NW018' , .00006215), + ('NW019' , .00006947), + ('NW020' , .00007495), + ('NW021' , .00008293), + ('NW022' , .00009184), + ('NW024' , .00010857), + # they have a NW025 used in EXL110BT but it's not listed + ('NW026' , .00012671), + ('NW028' , .00014666), + ('NW030' , .00017236), + ('NW032' , .00019347), + ('NW034' , .00021590), + ('NW036' , .00023964), + ('NW038' , .00026471), + ('NW039' , .00027932), + ('NW042' , .00032279), + ('NW044' , .00035182), + ('NW046' , .00038216), + ('NW048' , .00041382), + ('NW049' , .00043014), + ('NW052' , .00048109), + ('NW054' , .00053838), + ('NW056' , .00057598), + ('NW059' , .00064191), + ('NW060' , .00066542), + ('NW062' , .00070697), + ('NW064' , .00074984), + ('NW066' , .00079889), + ('NW068' , .00084614), + ('NW070' , .00089304), + ('NW072' , .00094124), + ('NW074' , .00098869), + ('NW080' , .00115011), +) + +A = 440 +notes = { + 'C' : 0, + 'D' : 2, + 'E' : 4, + 'F' : 5, + 'G' : 7, + 'A' : 9, + 'B' : 11, +} +rel = (2**(1/12.)) +def note2freq(name): + sharp = name[1] == '#' + flat = name[1] == 'b' + if sharp or flat: + note = name[0:1] + octave = int(name[2]) + else: + note = name[0] + octave = int(name[1]) + num = notes[note] + if sharp: + num += 1 + if flat: + num -= 1 + fullnum = num + 12*(octave - 5) + return A*rel**(fullnum + 3) + +def test(name, expected): + print('{:3} gave {: 9.2f} Hz\nexpected {: 9.2f} Hz'.format(name, note2freq(name), expected)) +if False: + test('C2' , 65.41) + test('Ab4', 415.30) + test('A4' , 440.00) + test('B4' , 493.88) + test('B#4', 523.25) + test('Cb5', 493.88) + test('C5' , 523.25) + print() + test('E4' , 329.63) + test('B3' , 246.94) + test('G3' , 196.00) + test('D3' , 146.83) + test('A2' , 110.00) + test('E2' , 82.41) + +uw_const = 386.4 +def uw2tension(uw, freq): + return (uw*(2*scale_length*freq)**2)/uw_const + +def tension2uw(t, freq): + return (t*uw_const)/(2*scale_length*freq)**2 + +outfmt = '{:<6} at {:> 5.2f} lbs ({:>+4.2f})' +finalfmt = 'total: {:>7.2f} lbs ({:>+5.2f})' +def print_ideal_stock(strings): + total_tension = 0 + total_desired_tension = 0 + for note, tension, kind in strings: + freq = note2freq(note) + uw = tension2uw(tension, freq) + + closest = ('n/a', 0) + for name, stock_uw in stock: + if kind and name[:len(kind)] != kind: + continue + if abs(stock_uw - uw) < abs(closest[1] - uw): + closest = (name, stock_uw) + + closest_tension = uw2tension(closest[1], freq) + diff = closest_tension - tension + print(outfmt.format(closest[0], closest_tension, diff)) + + total_tension += closest_tension + total_desired_tension += tension + + error = total_tension - total_desired_tension + print(finalfmt.format(total_tension, error)) + +print('for a scale length of {:>5.2f} inches'.format(scale_length)) +for name, strings in string_sets.items(): + print() + print('"{}"'.format(name)) + print_ideal_stock(strings) From 1fb3df1403a01a7f6df4101a51618c3c8fed9bd2 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Mon, 29 Sep 2014 21:47:58 -0700 Subject: [PATCH 03/10] . --- strings.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/strings.py b/strings.py index 35d1492..f2840a4 100755 --- a/strings.py +++ b/strings.py @@ -13,7 +13,7 @@ string_sets = { ('A2' , 16, 'NW'), ('E2' , 16, 'NW'), ), - 'light jazz': ( + 'jazz light': ( ('E4' , 24, 'PL'), ('B3' , 24, 'PL'), ('G3' , 24, 'NW'), @@ -29,7 +29,7 @@ string_sets = { ('A2' , 16, 'NW'), ('D2' , 16, 'NW'), ), - 'open G (6-string)': ( + 'regular light (open G, 6)': ( ('D4' , 16, 'PL'), ('B3' , 16, 'PL'), ('G3' , 16, 'PL'), @@ -37,7 +37,7 @@ string_sets = { ('B2' , 16, 'NW'), ('D2' , 16, 'NW'), ), - 'open G (7-string)': ( + 'regular light (open G, 7)': ( ('D4' , 16, 'PL'), ('B3' , 16, 'PL'), ('G3' , 16, 'PL'), @@ -83,7 +83,7 @@ stock = ( ('NW021' , .00008293), ('NW022' , .00009184), ('NW024' , .00010857), - # they have a NW025 used in EXL110BT but it's not listed + ('NW025*', .00011875), # from the EXL110BT, an approximation ('NW026' , .00012671), ('NW028' , .00014666), ('NW030' , .00017236), @@ -157,6 +157,8 @@ if False: test('D3' , 146.83) test('A2' , 110.00) test('E2' , 82.41) + import sys + sys.exit(0) uw_const = 386.4 def uw2tension(uw, freq): @@ -165,6 +167,15 @@ def uw2tension(uw, freq): def tension2uw(t, freq): return (t*uw_const)/(2*scale_length*freq)**2 +if False: + scale_length = 25.4825 + D3 = note2freq('D3') + print('NW024 {:10.8f} == 0.00010857'.format(tension2uw(15.73, D3))) + print('NW025* {:10.8f} == ? '.format(tension2uw(17.21, D3))) + print('NW026 {:10.8f} == 0.00012671'.format(tension2uw(18.38, D3))) + import sys + sys.exit(0) + outfmt = '{:<6} at {:> 5.2f} lbs ({:>+4.2f})' finalfmt = 'total: {:>7.2f} lbs ({:>+5.2f})' def print_ideal_stock(strings): From 115a30cc5bdfef43545527218df0a23c3979c632 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Tue, 30 Sep 2014 02:13:14 -0700 Subject: [PATCH 04/10] . --- data.py | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++ strings.py | 138 +++++++++++++++---------------------------------- 2 files changed, 189 insertions(+), 96 deletions(-) create mode 100644 data.py diff --git a/data.py b/data.py new file mode 100644 index 0000000..086e38b --- /dev/null +++ b/data.py @@ -0,0 +1,147 @@ +# (product name, unit weight) + +# D'Addario stock via http://www.daddario.com/upload/tension_chart_13934.pdf +# Circle K String stock http://circlekstrings.com/CKSIMAGES/UnitWeightChart130105.pdf + +# Circle K strings lack offical names, so were given + +daddario_plain_steel = ( + ('DAPL007' , .00001085), + ('DAPL008' , .00001418), + ('DAPL0085', .00001601), + ('DAPL009' , .00001794), + ('DAPL0095', .00001999), + ('DAPL010' , .00002215), + ('DAPL0105', .00002442), + ('DAPL011' , .00002680), + ('DAPL0115', .00002930), + ('DAPL012' , .00003190), + ('DAPL013' , .00003744), + ('DAPL0135', .00004037), + ('DAPL014' , .00004342), + ('DAPL015' , .00004984), + ('DAPL016' , .00005671), + ('DAPL017' , .00006402), + ('DAPL018' , .00007177), + ('DAPL019' , .00007997), + ('DAPL020' , .00008861), + ('DAPL022' , .00010722), + ('DAPL024' , .00012760), + ('DAPL027' , .00014975), +) + +daddario_nickle_wound = ( # XL + ('DANW017' , .00005524), + ('DANW018' , .00006215), + ('DANW019' , .00006947), + ('DANW020' , .00007495), + ('DANW021' , .00008293), + ('DANW022' , .00009184), + ('DANW024' , .00010857), + ('DANW025*', .00011875), # from the EXL110BT, an approximation + ('DANW026' , .00012671), + ('DANW028' , .00014666), + ('DANW030' , .00017236), + ('DANW032' , .00019347), + ('DANW034' , .00021590), + ('DANW036' , .00023964), + ('DANW038' , .00026471), + ('DANW039' , .00027932), + ('DANW042' , .00032279), + ('DANW044' , .00035182), + ('DANW046' , .00038216), + ('DANW048' , .00041382), + ('DANW049' , .00043014), + ('DANW052' , .00048109), + ('DANW054' , .00053838), + ('DANW056' , .00057598), + ('DANW059' , .00064191), + ('DANW060' , .00066542), + ('DANW062' , .00070697), + ('DANW064' , .00074984), + ('DANW066' , .00079889), + ('DANW068' , .00084614), + ('DANW070' , .00089304), + ('DANW072' , .00094124), + ('DANW074' , .00098869), + ('DANW080' , .00115011), +) + +circle_k_plain = ( + ('CKPL008', .000014240), + ('CKPL009', .000018022), + ('CKPL010', .000022252), + ('CKPL011', .000026925), + ('CKPL012', .000032039), + ('CKPL013', .000037605), + ('CKPL014', .000043607), + ('CKPL015', .000050050), + ('CKPL016', .000056961), + ('CKPL017', .000064300), + ('CKPL018', .000072088), + ('CKPL019', .000080360), + ('CKPL020', .000089031), + ('CKPL021', .000098155), + ('CKPL022', .000107666), + ('CKPL023', .000117702), +) + +circle_k_hybrid_wound = ( + ('CKHW021', .000093873), + ('CKHW022', .000103500), + ('CKHW023', .000113985), + ('CKHW024', .000124963), + ('CKHW025', .000136054), + ('CKHW026', .000144691), + ('CKHW027', .000153146), + ('CKHW028', .000161203), + ('CKHW029', .000178551), + ('CKHW031', .000198902), + ('CKHW033', .000223217), + ('CKHW035', .000249034), + ('CKHW037', .000276237), + ('CKHW039', .000304788), + ('CKHW041', .000334965), + ('CKHW043', .000366357), + ('CKHW045', .000404956), + ('CKHW047', .000447408), + ('CKHW049', .000475438), + ('CKHW051', .000512645), + ('CKHW053', .000551898), + ('CKHW055', .000584407), + ('CKHW057', .000625704), + ('CKHW059', .000679149), + ('CKHW061', .000720293), + ('CKHW063', .000765973), + ('CKHW065', .000821116), + ('CKHW067', .000870707), + ('CKHW070', .000939851), + ('CKHW073', .001021518), + ('CKHW076', .001110192), + ('CKHW079', .001188974), + ('CKHW082', .001293598), + ('CKHW086', .001416131), + ('CKHW090', .001544107), + ('CKHW094', .001677765), + ('CKHW098', .001831487), + ('CKHW102', .001986524), + ('CKHW106', .002127413), + ('CKHW112', .002367064), + ('CKHW118', .002616406), + ('CKHW124', .002880915), + ('CKHW130', .003154996), + ('CKHW136', .003441822), + ('CKHW142', .003741715), + ('CKHW150', .004051506), + ('CKHW158', .004375389), + ('CKHW166', .005078724), + ('CKHW174', .005469937), + ('CKHW182', .006071822), + ('CKHW190', .006605072), + ('CKHW200', .007311717), + ('CKHW210', .008037439), + ('CKHW222', .009091287), + ('CKHW232', .009888443), + ('CKHW244', .010907182), + ('CKHW254', .011787319), +) diff --git a/strings.py b/strings.py index f2840a4..8cfc3b3 100755 --- a/strings.py +++ b/strings.py @@ -1,117 +1,61 @@ #!/usr/bin/python +from data import * + +stock = [] +stock += daddario_plain_steel +stock += daddario_nickle_wound +#stock += circle_k_plain +#stock += circle_k_hybrid_wound + mm_to_in = 0.03937 scale_length = 648*mm_to_in string_sets = { 'regular light': ( # (desired note, tension, and type) - ('E4' , 16, 'PL'), - ('B3' , 16, 'PL'), - ('G3' , 16, 'PL'), - ('D3' , 16, 'NW'), - ('A2' , 16, 'NW'), - ('E2' , 16, 'NW'), + ('E4' , 16, 'P'), + ('B3' , 16, 'P'), + ('G3' , 16, 'P'), + ('D3' , 16, 'W'), + ('A2' , 16, 'W'), + ('E2' , 16, 'W'), ), 'jazz light': ( - ('E4' , 24, 'PL'), - ('B3' , 24, 'PL'), - ('G3' , 24, 'NW'), - ('D3' , 24, 'NW'), - ('A2' , 24, 'NW'), - ('E2' , 24, 'NW'), + ('E4' , 24, 'P'), + ('B3' , 24, 'P'), + ('G3' , 24, 'W'), + ('D3' , 24, 'W'), + ('A2' , 24, 'W'), + ('E2' , 24, 'W'), ), 'regular light (DADGAD)': ( - ('D4' , 16, 'PL'), - ('A3' , 16, 'PL'), - ('G3' , 16, 'PL'), - ('D3' , 16, 'NW'), - ('A2' , 16, 'NW'), - ('D2' , 16, 'NW'), + ('D4' , 16, 'P'), + ('A3' , 16, 'P'), + ('G3' , 16, 'P'), + ('D3' , 16, 'W'), + ('A2' , 16, 'W'), + ('D2' , 16, 'W'), ), 'regular light (open G, 6)': ( - ('D4' , 16, 'PL'), - ('B3' , 16, 'PL'), - ('G3' , 16, 'PL'), - ('D3' , 16, 'NW'), - ('B2' , 16, 'NW'), - ('D2' , 16, 'NW'), + ('D4' , 16, 'P'), + ('B3' , 16, 'P'), + ('G3' , 16, 'P'), + ('D3' , 16, 'W'), + ('B2' , 16, 'W'), + ('D2' , 16, 'W'), ), 'regular light (open G, 7)': ( - ('D4' , 16, 'PL'), - ('B3' , 16, 'PL'), - ('G3' , 16, 'PL'), - ('D3' , 16, 'NW'), - ('B2' , 16, 'NW'), - ('G2' , 16, 'NW'), - ('D2' , 16, 'NW'), + ('D4' , 16, 'P'), + ('B3' , 16, 'P'), + ('G3' , 16, 'P'), + ('D3' , 16, 'W'), + ('B2' , 16, 'W'), + ('G2' , 16, 'W'), + ('D2' , 16, 'W'), ), } -# D'Addario stock via http://www.daddario.com/upload/tension_chart_13934.pdf -stock = ( -# (product name, unit weight) -# plain steel - ('PL007' , .00001085), - ('PL008' , .00001418), - ('PL0085', .00001601), - ('PL009' , .00001794), - ('PL0095', .00001999), - ('PL010' , .00002215), - ('PL0105', .00002442), - ('PL011' , .00002680), - ('PL0115', .00002930), - ('PL012' , .00003190), - ('PL013' , .00003744), - ('PL0135', .00004037), - ('PL014' , .00004342), - ('PL015' , .00004984), - ('PL016' , .00005671), - ('PL017' , .00006402), - ('PL018' , .00007177), - ('PL019' , .00007997), - ('PL020' , .00008861), - ('PL022' , .00010722), - ('PL024' , .00012760), - ('PL027' , .00014975), - -# nickelplated steel round wound (XL) - ('NW017' , .00005524), - ('NW018' , .00006215), - ('NW019' , .00006947), - ('NW020' , .00007495), - ('NW021' , .00008293), - ('NW022' , .00009184), - ('NW024' , .00010857), - ('NW025*', .00011875), # from the EXL110BT, an approximation - ('NW026' , .00012671), - ('NW028' , .00014666), - ('NW030' , .00017236), - ('NW032' , .00019347), - ('NW034' , .00021590), - ('NW036' , .00023964), - ('NW038' , .00026471), - ('NW039' , .00027932), - ('NW042' , .00032279), - ('NW044' , .00035182), - ('NW046' , .00038216), - ('NW048' , .00041382), - ('NW049' , .00043014), - ('NW052' , .00048109), - ('NW054' , .00053838), - ('NW056' , .00057598), - ('NW059' , .00064191), - ('NW060' , .00066542), - ('NW062' , .00070697), - ('NW064' , .00074984), - ('NW066' , .00079889), - ('NW068' , .00084614), - ('NW070' , .00089304), - ('NW072' , .00094124), - ('NW074' , .00098869), - ('NW080' , .00115011), -) - A = 440 notes = { 'C' : 0, @@ -187,7 +131,9 @@ def print_ideal_stock(strings): closest = ('n/a', 0) for name, stock_uw in stock: - if kind and name[:len(kind)] != kind: + if kind == 'P' and name[2] != 'P': + continue + if kind == 'W' and name[3] != 'W': continue if abs(stock_uw - uw) < abs(closest[1] - uw): closest = (name, stock_uw) From 3aae7d6c1d723328fac331137c3c8c5e483d313f Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Thu, 2 Oct 2014 00:54:55 -0700 Subject: [PATCH 05/10] . --- data.py | 3 +++ strings.py | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/data.py b/data.py index 086e38b..94d96be 100644 --- a/data.py +++ b/data.py @@ -45,13 +45,16 @@ daddario_nickle_wound = ( # XL ('DANW032' , .00019347), ('DANW034' , .00021590), ('DANW036' , .00023964), + ('DANW037*', .00024872), # from the EXL115BT, an approximation ('DANW038' , .00026471), ('DANW039' , .00027932), + ('DANW040*', .00029570), # from the EXL120BT, an approximation ('DANW042' , .00032279), ('DANW044' , .00035182), ('DANW046' , .00038216), ('DANW048' , .00041382), ('DANW049' , .00043014), + ('DANW050*', .00044720), # from the EXL115BT, an approximation ('DANW052' , .00048109), ('DANW054' , .00053838), ('DANW056' , .00057598), diff --git a/strings.py b/strings.py index 8cfc3b3..69af7ac 100755 --- a/strings.py +++ b/strings.py @@ -112,16 +112,33 @@ def tension2uw(t, freq): return (t*uw_const)/(2*scale_length*freq)**2 if False: + # DAd's data is all screwy so we use change scale lengths for a best-fit scale_length = 25.4825 D3 = note2freq('D3') + A2 = note2freq('A2') + E2 = note2freq('E2') print('NW024 {:10.8f} == 0.00010857'.format(tension2uw(15.73, D3))) print('NW025* {:10.8f} == ? '.format(tension2uw(17.21, D3))) print('NW026 {:10.8f} == 0.00012671'.format(tension2uw(18.38, D3))) + print() + print('NW036 {:10.8f} == 0.00023964'.format(tension2uw(19.04, A2))) + print('NW037* {:10.8f} == ? '.format(tension2uw(20.23, A2))) + print('NW038 {:10.8f} == 0.00026471'.format(tension2uw(20.96, A2))) + print() + scale_length = 25.18 + print('NW039 {:10.8f} == 0.00027932'.format(tension2uw(12.46, E2))) + print('NW040* {:10.8f} == ? '.format(tension2uw(13.18, E2))) + print('NW042 {:10.8f} == 0.00032279'.format(tension2uw(14.37, E2))) + print() + scale_length = 25.02 + print('NW049 {:10.8f} == 0.00043014'.format(tension2uw(18.97, E2))) + print('NW050* {:10.8f} == ? '.format(tension2uw(19.68, E2))) + print('NW052 {:10.8f} == 0.00048109'.format(tension2uw(21.15, E2))) import sys sys.exit(0) -outfmt = '{:<6} at {:> 5.2f} lbs ({:>+4.2f})' -finalfmt = 'total: {:>7.2f} lbs ({:>+5.2f})' +outfmt = '{:<8} at {:> 5.2f} lbs ({:>+4.2f})' +finalfmt = 'total: {:>7.2f} lbs ({:>+5.2f})' def print_ideal_stock(strings): total_tension = 0 total_desired_tension = 0 From 83f1fbe6fc225564f85cd137c25b230bc29e3e05 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Thu, 2 Oct 2014 01:21:52 -0700 Subject: [PATCH 06/10] . --- data.py | 0 notes.py | 52 ++++++++++++++++ run.py | 58 ++++++++++++++++++ strings.py | 175 +++++++++++++---------------------------------------- 4 files changed, 152 insertions(+), 133 deletions(-) mode change 100644 => 100755 data.py create mode 100755 notes.py create mode 100755 run.py diff --git a/data.py b/data.py old mode 100644 new mode 100755 diff --git a/notes.py b/notes.py new file mode 100755 index 0000000..b76a31a --- /dev/null +++ b/notes.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +A = 440 +notes = { + 'C' : 0, + 'D' : 2, + 'E' : 4, + 'F' : 5, + 'G' : 7, + 'A' : 9, + 'B' : 11, +} + +rel = (2**(1/12.)) +def note2freq(name): + sharp = name[1] == '#' + flat = name[1] == 'b' + if sharp or flat: + note = name[0:1] + octave = int(name[2]) + else: + note = name[0] + octave = int(name[1]) + num = notes[note] + if sharp: + num += 1 + if flat: + num -= 1 + fullnum = num + 12*(octave - 5) + return A*rel**(fullnum + 3) + +if __name__ == '__main__': + def test(name, expected): + print('{:3} gave {: 9.2f} Hz\nexpected {: 9.2f} Hz'.format(name, note2freq(name), expected)) + + test('C2' , 65.41) + test('Ab4', 415.30) + test('A4' , 440.00) + test('B4' , 493.88) + test('B#4', 523.25) + test('Cb5', 493.88) + test('C5' , 523.25) + print() + test('E4' , 329.63) + test('B3' , 246.94) + test('G3' , 196.00) + test('D3' , 146.83) + test('A2' , 110.00) + test('E2' , 82.41) + + import sys + sys.exit(0) diff --git a/run.py b/run.py new file mode 100755 index 0000000..be6937e --- /dev/null +++ b/run.py @@ -0,0 +1,58 @@ +#!/usr/bin/python + +from strings import print_ideal_stock + +in_mm = 25.4 +scale_length = 648/in_mm + +string_sets = { + 'regular light': ( + # (desired note, tension, and type) + ('E4' , 16, 'P'), + ('B3' , 16, 'P'), + ('G3' , 16, 'P'), + ('D3' , 16, 'W'), + ('A2' , 16, 'W'), + ('E2' , 16, 'W'), + ), + 'jazz light': ( + ('E4' , 24, 'P'), + ('B3' , 24, 'P'), + ('G3' , 24, 'W'), + ('D3' , 24, 'W'), + ('A2' , 24, 'W'), + ('E2' , 24, 'W'), + ), + 'regular light (DADGAD)': ( + ('D4' , 16, 'P'), + ('A3' , 16, 'P'), + ('G3' , 16, 'P'), + ('D3' , 16, 'W'), + ('A2' , 16, 'W'), + ('D2' , 16, 'W'), + ), + 'regular light (open G, 6)': ( + ('D4' , 16, 'P'), + ('B3' , 16, 'P'), + ('G3' , 16, 'P'), + ('D3' , 16, 'W'), + ('B2' , 16, 'W'), + ('D2' , 16, 'W'), + ), + 'regular light (open G, 7)': ( + ('D4' , 16, 'P'), + ('B3' , 16, 'P'), + ('G3' , 16, 'P'), + ('D3' , 16, 'W'), + ('B2' , 16, 'W'), + ('G2' , 16, 'W'), + ('D2' , 16, 'W'), + ), +} + +print('for a scale length of {:>5.2f} inches'.format(scale_length)) +for name, strings in string_sets.items(): + print() + print('"{}"'.format(name)) + print_ideal_stock(strings, scale_length) + diff --git a/strings.py b/strings.py index 69af7ac..407059a 100755 --- a/strings.py +++ b/strings.py @@ -1,6 +1,7 @@ #!/usr/bin/python from data import * +from notes import note2freq stock = [] stock += daddario_plain_steel @@ -8,143 +9,22 @@ stock += daddario_nickle_wound #stock += circle_k_plain #stock += circle_k_hybrid_wound -mm_to_in = 0.03937 -scale_length = 648*mm_to_in - -string_sets = { - 'regular light': ( - # (desired note, tension, and type) - ('E4' , 16, 'P'), - ('B3' , 16, 'P'), - ('G3' , 16, 'P'), - ('D3' , 16, 'W'), - ('A2' , 16, 'W'), - ('E2' , 16, 'W'), - ), - 'jazz light': ( - ('E4' , 24, 'P'), - ('B3' , 24, 'P'), - ('G3' , 24, 'W'), - ('D3' , 24, 'W'), - ('A2' , 24, 'W'), - ('E2' , 24, 'W'), - ), - 'regular light (DADGAD)': ( - ('D4' , 16, 'P'), - ('A3' , 16, 'P'), - ('G3' , 16, 'P'), - ('D3' , 16, 'W'), - ('A2' , 16, 'W'), - ('D2' , 16, 'W'), - ), - 'regular light (open G, 6)': ( - ('D4' , 16, 'P'), - ('B3' , 16, 'P'), - ('G3' , 16, 'P'), - ('D3' , 16, 'W'), - ('B2' , 16, 'W'), - ('D2' , 16, 'W'), - ), - 'regular light (open G, 7)': ( - ('D4' , 16, 'P'), - ('B3' , 16, 'P'), - ('G3' , 16, 'P'), - ('D3' , 16, 'W'), - ('B2' , 16, 'W'), - ('G2' , 16, 'W'), - ('D2' , 16, 'W'), - ), -} - -A = 440 -notes = { - 'C' : 0, - 'D' : 2, - 'E' : 4, - 'F' : 5, - 'G' : 7, - 'A' : 9, - 'B' : 11, -} -rel = (2**(1/12.)) -def note2freq(name): - sharp = name[1] == '#' - flat = name[1] == 'b' - if sharp or flat: - note = name[0:1] - octave = int(name[2]) - else: - note = name[0] - octave = int(name[1]) - num = notes[note] - if sharp: - num += 1 - if flat: - num -= 1 - fullnum = num + 12*(octave - 5) - return A*rel**(fullnum + 3) - -def test(name, expected): - print('{:3} gave {: 9.2f} Hz\nexpected {: 9.2f} Hz'.format(name, note2freq(name), expected)) -if False: - test('C2' , 65.41) - test('Ab4', 415.30) - test('A4' , 440.00) - test('B4' , 493.88) - test('B#4', 523.25) - test('Cb5', 493.88) - test('C5' , 523.25) - print() - test('E4' , 329.63) - test('B3' , 246.94) - test('G3' , 196.00) - test('D3' , 146.83) - test('A2' , 110.00) - test('E2' , 82.41) - import sys - sys.exit(0) - uw_const = 386.4 -def uw2tension(uw, freq): - return (uw*(2*scale_length*freq)**2)/uw_const +def uw2tension(uw, freq, SL): + return (uw*(2*SL*freq)**2)/uw_const -def tension2uw(t, freq): - return (t*uw_const)/(2*scale_length*freq)**2 - -if False: - # DAd's data is all screwy so we use change scale lengths for a best-fit - scale_length = 25.4825 - D3 = note2freq('D3') - A2 = note2freq('A2') - E2 = note2freq('E2') - print('NW024 {:10.8f} == 0.00010857'.format(tension2uw(15.73, D3))) - print('NW025* {:10.8f} == ? '.format(tension2uw(17.21, D3))) - print('NW026 {:10.8f} == 0.00012671'.format(tension2uw(18.38, D3))) - print() - print('NW036 {:10.8f} == 0.00023964'.format(tension2uw(19.04, A2))) - print('NW037* {:10.8f} == ? '.format(tension2uw(20.23, A2))) - print('NW038 {:10.8f} == 0.00026471'.format(tension2uw(20.96, A2))) - print() - scale_length = 25.18 - print('NW039 {:10.8f} == 0.00027932'.format(tension2uw(12.46, E2))) - print('NW040* {:10.8f} == ? '.format(tension2uw(13.18, E2))) - print('NW042 {:10.8f} == 0.00032279'.format(tension2uw(14.37, E2))) - print() - scale_length = 25.02 - print('NW049 {:10.8f} == 0.00043014'.format(tension2uw(18.97, E2))) - print('NW050* {:10.8f} == ? '.format(tension2uw(19.68, E2))) - print('NW052 {:10.8f} == 0.00048109'.format(tension2uw(21.15, E2))) - import sys - sys.exit(0) +def tension2uw(t, freq, SL): + return (t*uw_const)/(2*SL*freq)**2 outfmt = '{:<8} at {:> 5.2f} lbs ({:>+4.2f})' finalfmt = 'total: {:>7.2f} lbs ({:>+5.2f})' -def print_ideal_stock(strings): +def print_ideal_stock(strings, scale_length=25.512): + SL = scale_length total_tension = 0 total_desired_tension = 0 for note, tension, kind in strings: freq = note2freq(note) - uw = tension2uw(tension, freq) + uw = tension2uw(tension, freq, SL) closest = ('n/a', 0) for name, stock_uw in stock: @@ -155,7 +35,7 @@ def print_ideal_stock(strings): if abs(stock_uw - uw) < abs(closest[1] - uw): closest = (name, stock_uw) - closest_tension = uw2tension(closest[1], freq) + closest_tension = uw2tension(closest[1], freq, SL) diff = closest_tension - tension print(outfmt.format(closest[0], closest_tension, diff)) @@ -165,8 +45,37 @@ def print_ideal_stock(strings): error = total_tension - total_desired_tension print(finalfmt.format(total_tension, error)) -print('for a scale length of {:>5.2f} inches'.format(scale_length)) -for name, strings in string_sets.items(): +if __name__ == '__main__': + # DAd's data is all screwy so we use change scale lengths for a best-fit + SL = 25.4825 + D3 = note2freq('D3') + A2 = note2freq('A2') + E2 = note2freq('E2') + + test_fmt = '{:8} {:10.8f} == {:10}' + def test(name, unit, tension, note): + print(test_fmt.format(name, tension2uw(tension, note, SL), unit)) + + test('NW024' , '0.00010857', 15.73, D3) + test('NW025*', '?' , 17.21, D3) + test('NW026' , '0.00012671', 18.38, D3) print() - print('"{}"'.format(name)) - print_ideal_stock(strings) + + test('NW036' , '0.00023964', 19.04, A2) + test('NW037*', '? ', 20.23, A2) + test('NW038' , '0.00026471', 20.96, A2) + print() + + SL = 25.18 + test('NW039' , '0.00027932', 12.46, E2) + test('NW040*', '? ', 13.18, E2) + test('NW042' , '0.00032279', 14.37, E2) + print() + + SL = 25.02 + test('NW049' , '0.00043014', 18.97, E2) + test('NW050*', '? ', 19.68, E2) + test('NW052' , '0.00048109', 21.15, E2) + + import sys + sys.exit(0) From 9ef423de71aeeab816470e341781e889df0fe783 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Thu, 2 Oct 2014 01:26:46 -0700 Subject: [PATCH 07/10] . --- data.py | 2 +- notes.py | 3 --- strings.py | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/data.py b/data.py index 94d96be..1d0a26a 100755 --- a/data.py +++ b/data.py @@ -3,7 +3,7 @@ # D'Addario stock via http://www.daddario.com/upload/tension_chart_13934.pdf # Circle K String stock http://circlekstrings.com/CKSIMAGES/UnitWeightChart130105.pdf -# Circle K strings lack offical names, so were given +# string names don't necessarily match up with their actual product names daddario_plain_steel = ( ('DAPL007' , .00001085), diff --git a/notes.py b/notes.py index b76a31a..019e09f 100755 --- a/notes.py +++ b/notes.py @@ -47,6 +47,3 @@ if __name__ == '__main__': test('D3' , 146.83) test('A2' , 110.00) test('E2' , 82.41) - - import sys - sys.exit(0) diff --git a/strings.py b/strings.py index 407059a..b3e7704 100755 --- a/strings.py +++ b/strings.py @@ -76,6 +76,3 @@ if __name__ == '__main__': test('NW049' , '0.00043014', 18.97, E2) test('NW050*', '? ', 19.68, E2) test('NW052' , '0.00048109', 21.15, E2) - - import sys - sys.exit(0) From f9375479911743de5aca2e8919a1ac7e1dcaa9b8 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Thu, 2 Oct 2014 01:33:47 -0700 Subject: [PATCH 08/10] . --- notes.py | 3 ++- strings.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/notes.py b/notes.py index 019e09f..c9a4674 100755 --- a/notes.py +++ b/notes.py @@ -30,8 +30,9 @@ def note2freq(name): return A*rel**(fullnum + 3) if __name__ == '__main__': + test_fmt = '{:3} gave {: 9.2f} Hz\nexpected {: 9.2f} Hz' def test(name, expected): - print('{:3} gave {: 9.2f} Hz\nexpected {: 9.2f} Hz'.format(name, note2freq(name), expected)) + print(test_fmt.format(name, note2freq(name), expected)) test('C2' , 65.41) test('Ab4', 415.30) diff --git a/strings.py b/strings.py index b3e7704..978ad11 100755 --- a/strings.py +++ b/strings.py @@ -16,8 +16,8 @@ def uw2tension(uw, freq, SL): def tension2uw(t, freq, SL): return (t*uw_const)/(2*SL*freq)**2 -outfmt = '{:<8} at {:> 5.2f} lbs ({:>+4.2f})' -finalfmt = 'total: {:>7.2f} lbs ({:>+5.2f})' +outfmt = '{:<8} at {:> 5.2f} lb ({:>+4.2f})' +finalfmt = 'total: {:>7.2f} lb ({:>+5.2f})' def print_ideal_stock(strings, scale_length=25.512): SL = scale_length total_tension = 0 From a6aed4fcc57778ac5c8430aa4dd5e5d87a687068 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Mon, 3 Nov 2014 12:54:18 -0800 Subject: [PATCH 09/10] a whole heap of crap --- run.py | 119 ++++++++++++++++++++++++++++++++--------------------- run2.py | 84 +++++++++++++++++++++++++++++++++++++ strings.py | 55 +++++++++++++++++++++---- 3 files changed, 202 insertions(+), 56 deletions(-) create mode 100755 run2.py diff --git a/run.py b/run.py index be6937e..a8f2725 100755 --- a/run.py +++ b/run.py @@ -3,56 +3,79 @@ from strings import print_ideal_stock in_mm = 25.4 -scale_length = 648/in_mm +default_scale_length = 648/in_mm -string_sets = { - 'regular light': ( - # (desired note, tension, and type) - ('E4' , 16, 'P'), - ('B3' , 16, 'P'), - ('G3' , 16, 'P'), - ('D3' , 16, 'W'), - ('A2' , 16, 'W'), - ('E2' , 16, 'W'), - ), - 'jazz light': ( - ('E4' , 24, 'P'), - ('B3' , 24, 'P'), - ('G3' , 24, 'W'), - ('D3' , 24, 'W'), - ('A2' , 24, 'W'), - ('E2' , 24, 'W'), - ), - 'regular light (DADGAD)': ( - ('D4' , 16, 'P'), - ('A3' , 16, 'P'), - ('G3' , 16, 'P'), - ('D3' , 16, 'W'), - ('A2' , 16, 'W'), - ('D2' , 16, 'W'), - ), - 'regular light (open G, 6)': ( - ('D4' , 16, 'P'), - ('B3' , 16, 'P'), - ('G3' , 16, 'P'), - ('D3' , 16, 'W'), - ('B2' , 16, 'W'), - ('D2' , 16, 'W'), - ), - 'regular light (open G, 7)': ( - ('D4' , 16, 'P'), - ('B3' , 16, 'P'), - ('G3' , 16, 'P'), - ('D3' , 16, 'W'), - ('B2' , 16, 'W'), - ('G2' , 16, 'W'), - ('D2' , 16, 'W'), - ), -} +sets = """ +regular light +E4 16 PD +B3 16 PD +G3 16 PD +D3 16 WD +A2 16 WD +E2 16 WD -print('for a scale length of {:>5.2f} inches'.format(scale_length)) -for name, strings in string_sets.items(): +jazz medium +E4 24 PD +B3 24 PD +G3 24 WD +D3 24 WD +A2 24 WD +E2 24 WD + +regular light (DADGAD) +D4 16 PD +A3 16 PD +G3 16 PD +D3 16 WD +A2 16 WD +D2 16 WD + +fanned-fret bass +G2 35 WC 34.00 +D2 35 WC 34.75 +A1 35 WC 35.50 +E1 35 WC 36.25 +B0 35 WC 37.00 + +regular light (Open G 7-string) +D4 16 PD +B3 16 PD +G3 16 PD +D3 16 WD +B2 16 WD +G2 16 WD +D2 16 WD +""" + +string_sets = {} +sets = sets+'\n\n' +title = None +for line in sets.splitlines(): + if not line: + title = None + continue + if not title: + title = line + string_sets[title] = [] + else: + fields = line.split() + note, tension = fields[0:2] + tension = int(tension) + + req = '' + if len(fields) > 2: + req = fields[2] + + length = None + if len(fields) > 3: + length = float(fields[3]) + + string = (note, tension, req, length) + string_sets[title].append(string) + +print('for a scale length of {:>5.2f} inches'.format(default_scale_length)) +for name, strings in sorted(string_sets.items()): print() print('"{}"'.format(name)) - print_ideal_stock(strings, scale_length) + print_ideal_stock(strings, default_scale_length) diff --git a/run2.py b/run2.py new file mode 100755 index 0000000..eb9dfb0 --- /dev/null +++ b/run2.py @@ -0,0 +1,84 @@ +#!/usr/bin/python + +from strings import print_tensions + +in_mm = 25.4 +default_scale_length = 648/in_mm + +sets = """ +E standard (super light balanced) +E4 DAPL009 +B3 DAPL012 +G3 DAPL015 +D3 DANW022 +A2 DANW030 +E2 DANW040 + +E standard (medium balanced) +E4 DAPL011 +B3 DAPL015 +G3 DAPL019 +D3 DANW028 +A2 DANW037 +E2 DANW050 + +C standard (medium balanced) +C4 DAPL011 +G3 DAPL015 +D#3 DAPL019 +A#2 DANW028 +F2 DANW037 +C2 DANW050 + +C standard (jazz medium) +C4 DAPL013 +G3 DAPL017 +D#3 DANW026 +A#2 DANW036 +F2 DANW046 +C2 DANW056 + +C standard (CKS-G6-14-59mb) +C4 CKPL014 +G3 CKPL019 +D#3 CKHW025 +A#2 CKHW033 +F2 CKHW045 +C2 CKHW059 + +B standard (CKS-G6-14-59mb) +B3 CKPL014 +F#3 CKPL019 +D3 CKHW025 +A2 CKHW033 +E2 CKHW045 +B1 CKHW059 + +D standard drop C (medium balanced) +D4 DAPL011 +A3 DAPL015 +F3 DAPL019 +C3 DANW028 +G2 DANW037 +C2 DANW050 +""" + +string_sets = {} +sets = sets+'\n\n' +title = None +for line in sets.splitlines(): + if not line: + title = None + continue + if not title: + title = line + string_sets[title] = [] + else: + note, string = line.split() + string_sets[title].append((note, string)) + +print('for a scale length of {:>5.2f} inches'.format(default_scale_length)) +for name, strings in sorted(string_sets.items()): + print() + print('"{}"'.format(name)) + print_tensions(strings, default_scale_length) diff --git a/strings.py b/strings.py index 978ad11..d9e3ec6 100755 --- a/strings.py +++ b/strings.py @@ -6,8 +6,8 @@ from notes import note2freq stock = [] stock += daddario_plain_steel stock += daddario_nickle_wound -#stock += circle_k_plain -#stock += circle_k_hybrid_wound +stock += circle_k_plain +stock += circle_k_hybrid_wound uw_const = 386.4 def uw2tension(uw, freq, SL): @@ -16,21 +16,39 @@ def uw2tension(uw, freq, SL): def tension2uw(t, freq, SL): return (t*uw_const)/(2*SL*freq)**2 -outfmt = '{:<8} at {:> 5.2f} lb ({:>+4.2f})' -finalfmt = 'total: {:>7.2f} lb ({:>+5.2f})' +outfmt = '\ +{:<8} at {:>6.2f} lb ({:>+4.2f})' +finalfmt = '\ +average: {:>7.2f} lb ({:>+5.2f})\n\ +total: {:>7.2f} lb ({:>+5.2f})' +tension_outfmt = '\ +{:<3} {:<8} at {:>6.2f} lb' +tension_finalfmt = '\ +average: {:>7.2f} lb\n\ +total: {:>7.2f} lb' + def print_ideal_stock(strings, scale_length=25.512): SL = scale_length total_tension = 0 total_desired_tension = 0 - for note, tension, kind in strings: + for note, tension, req, length in strings: freq = note2freq(note) + if length: + SL = length + else: + SL = scale_length uw = tension2uw(tension, freq, SL) + kind = len(req) > 0 and req[0] + brand = len(req) > 1 and req[1] + closest = ('n/a', 0) for name, stock_uw in stock: - if kind == 'P' and name[2] != 'P': + if kind and kind == 'P' and name[2] != 'P': continue - if kind == 'W' and name[3] != 'W': + if kind and kind == 'W' and name[3] != 'W': + continue + if brand and brand[0] != name[0]: continue if abs(stock_uw - uw) < abs(closest[1] - uw): closest = (name, stock_uw) @@ -43,7 +61,28 @@ def print_ideal_stock(strings, scale_length=25.512): total_desired_tension += tension error = total_tension - total_desired_tension - print(finalfmt.format(total_tension, error)) + average_tension = total_tension/len(strings) + average_error = error/len(strings) + print(finalfmt.format(average_tension, average_error, total_tension, error)) + +def print_tensions(strings, scale_length=25.512): + SL = scale_length + total_tension = 0 + for note, name in strings: + freq = note2freq(note) + uw = 0 + for stock_name, stock_uw in stock: + if name == stock_name or name + '*' == stock_name: + uw = stock_uw + break + if uw: + tension = uw2tension(uw, freq, SL) + else: + tension = 0 + print(tension_outfmt.format(note, name, tension)) + total_tension += tension + + print(tension_finalfmt.format(total_tension/len(strings), total_tension)) if __name__ == '__main__': # DAd's data is all screwy so we use change scale lengths for a best-fit From 6a2eb1ffaec8a806f3eaacdd2331e368b19c455c Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Sun, 14 Feb 2016 09:43:52 -0800 Subject: [PATCH 10/10] . --- data.py | 22 ++++++++++++++-------- strings.py | 4 ++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/data.py b/data.py index 1d0a26a..63cb28c 100755 --- a/data.py +++ b/data.py @@ -70,13 +70,19 @@ daddario_nickle_wound = ( # XL ('DANW080' , .00115011), ) -circle_k_plain = ( - ('CKPL008', .000014240), - ('CKPL009', .000018022), - ('CKPL010', .000022252), - ('CKPL011', .000026925), - ('CKPL012', .000032039), - ('CKPL013', .000037605), +kalium_plain = ( + ('CKPL008 ',.0000142401458191), + ('CKPL0085',.00001607510288), + ('CKPL009', .0000180219146483), + ('CKPL0095',.00002008032129), + ('CKPL010', .0000222518914107), + ('CKPL0105',.00002453144932), + ('CKPL011', .0000269251480883), + ('CKPL0115',.00002942561205), + ('CKPL012', .0000320389593746), + ('CKPL0125',.00003476567932), + ('CKPL013', .0000376052948255), + ('CKPL0135',.00004055150041), ('CKPL014', .000043607), ('CKPL015', .000050050), ('CKPL016', .000056961), @@ -89,7 +95,7 @@ circle_k_plain = ( ('CKPL023', .000117702), ) -circle_k_hybrid_wound = ( +kalium_hybrid_wound = ( ('CKHW021', .000093873), ('CKHW022', .000103500), ('CKHW023', .000113985), diff --git a/strings.py b/strings.py index d9e3ec6..b292869 100755 --- a/strings.py +++ b/strings.py @@ -6,8 +6,8 @@ from notes import note2freq stock = [] stock += daddario_plain_steel stock += daddario_nickle_wound -stock += circle_k_plain -stock += circle_k_hybrid_wound +stock += kalium_plain +stock += kalium_hybrid_wound uw_const = 386.4 def uw2tension(uw, freq, SL):