Here's a quick mockup, very verbose and only checks one eye but gives you an example. I would need some time to set up classes for prescriptions and glasses to make it a bit more streamlined and to cleanup the code but let me know what you think:
Code:
import math
# single patient implementation patient prescription is in [sph, cyl, axis] notation as a list
patient_prescription = [-2.00, -1.00, 25]
# quick and simple list of glasses a list of prescription within a list, this could probably be
# implemented as a class for prescriptions since all prescriptions glasses of patient will have
# similar components
list_of_glasses = [[-1.00, -2.00, 55], [-2.00, -1.00, 125],
[-2.00, -1.00, 25], [-2.00, -0.50, 22],
[-1.00, -1.00, 15], [-1.00, -0.50, 50]]
def fitness_for_prescription(prescription, glasses):
#list of top 5 glasses that fit the patients prescription the best
fit = []
#patient prescription parameters
pat_sph = prescription[0]
pat_cyl = prescription[1]
pat_axis = math.radians(prescription[2])
#MRE, Cyl@045, Cyl@180 for prescription
pat_MRE = pat_sph + pat_cyl/2
pat_C045 = pat_cyl * math.cos(2 * pat_axis)
pat_C180 = pat_cyl * math.sin(2 * pat_axis)
#iteration through the list of glasses to find the residual error
for pairs in glasses:
# set up eye glass rx and variables
rx_sph = pairs[0]
rx_cyl = pairs[1]
rx_axis = math.radians(pairs[2])
combined_error = 0
#MRE, Cyl@045, Cyl@180 for each pair of glasses
rx_MRE = rx_sph + rx_cyl/2
rx_C045 = rx_cyl * math.cos(2 * rx_axis)
rx_C180 = rx_cyl * math.sin(2 * rx_axis)
#residual error calculations
MRE_err = pat_MRE - rx_MRE
C045_err = pat_C045 - rx_C045
C180_err = pat_C180 - rx_C180
#make sure we don't divide by 0 by adding a negligable amount
if C180_err == 0:
C180_err += 0.00001
# convert errors back to spherocylindrical form
combcyl = C180_err + C045_err
#check to make sure we don't try and square root a negative number
if combcyl < 0:
combcyl *= -1
cyl_err = math.sqrt(combcyl)
sph_err = MRE_err - cyl_err / 2
axis_err = math.atan(C045_err / C180_err) / 2
#combine the spherical and cylindrical errors into a dioptric values
combined_error += sph_err + (cyl_err / 2) + (axis_err / 2)
combined_error = abs(combined_error)
#append the error to our fit list
fit.append(combined_error)
#minimum error in list
minimum = min(fit)
#index of minimum error in glasses
glasses_index = fit.index(minimum)
return list_of_glasses[glasses_index]
print fitness_for_prescription(patient_prescription, list_of_glasses)
print "Dickus"
As nice as it is to have it inside optiboard check it out at the following URL you can test the function:
http://www.codeskulptor.org/#user31_Yvp7WB3xve_0.py
Bookmarks