# Find line of best fit

This is an update of Test thousands of combinations quickly.

I have a physical robot which has a function, turn(degrees). For different robots, there will be small differences in the accuracy of the turn. I have fine turning variables, multiplier and adder. The degrees are multiplied by the multiplier, and then adder is added on.

The data set will be manually created by someone requesting a turn, and recording what the actual turn was. This means the data set will usually be around 4 to 8 results long.

The PRECISION is how accurate we want the result to be. Ideally it would be as precise as possible, but since the robot has a fair amount of unpredictability, 2 d.p is fine.

The Code:

from numpy import arange

# list of actual test results in the form
# (requested turn degrees, actual turn degrees)
REAL_RESULTS = (
(90, 101),
(100, 112),
(110, 123),
(120, 134),
(130, 145),
)
# how accurate a multiplier you want
PRECISION = 0.001
# multiplier will be less than this
# and more than negative this
MULTIPLIER_BOUNDS = 10
# number of results to print
PRINT_TOP_RESULTS = 3

def calculateLine(multiplier, test_cases):
"""Calculates the absolute error and adder."""
# calculate the error with no adder
for test in test_cases:
error_no_adder -= test[0] * multiplier - test[1]
# the adder is the average error

# calculate error with the adder
error = 0
for test in test_cases:
error += abs((test[1] - adder) / multiplier - test[0])

if __name__ == "__main__":
# calculate results for every multiplier
results = [calculateLine(multiplier, REAL_RESULTS) for multiplier in
arange(-MULTIPLIER_BOUNDS, MULTIPLIER_BOUNDS, PRECISION)]
# sort from lowest error to highest error
results.sort()

printed_num = 0
i = -1
last_multiplier = 999
# print the top (least error) x results
while printed_num < PRINT_TOP_RESULTS:
i += 1
# don't print results with very similar precision
if abs(results[i][2] - last_multiplier) < PRECISION * 20:
continue
printed_num += 1
last_multiplier = results[i][2]
# print average error, the adder and multiplier
.format(*results[i]))


Have I followed standard coding conventions? pep8online says that it is fine.

Is it "better" - performance or conventions - to map the results or use list comprehension? I had previously used map and the calculate function used the global variable REAL_RESULTS, but I changed this because it defeats the purpose of reusable modules if a function relies on predefined global variables.

Are there any areas where performance could be improved? Performance isn't really an issue anymore because it has been hugely improved from my original code, but it's still nice to know if it could be better. Also this code could theoretically be used with a much larger data set where performance could matter.

PEP-8 issue: Function names should be lowercase_with_underscores.
• Haha thanks, the name change was a quick fix for being non-descriptive (before it was just called calculate). I won't update the question as this would invalidate your answer. – DarkMatterMatt Jun 23 '17 at 6:20