gists/string_tensions/strings.py
2018-10-11 16:45:37 +02:00

118 lines
3.4 KiB
Python
Executable File

#!/usr/bin/python
from data import *
from notes import note2freq
stock = []
stock += daddario_plain_steel
stock += daddario_nickle_wound
stock += kalium_plain
stock += kalium_hybrid_wound
uw_const = 386.4
def uw2tension(uw, freq, SL):
return (uw*(2*SL*freq)**2)/uw_const
def tension2uw(t, freq, SL):
return (t*uw_const)/(2*SL*freq)**2
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, 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 and kind == 'P' and name[2] != 'P':
continue
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)
closest_tension = uw2tension(closest[1], freq, SL)
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
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
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()
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)