Project: Reggie's Linear Regression - Calculation of possible m/bs with / 10 instead of * 0.1 results in different solution?

Link

I created my possible ms and bs like this:
possible_ms = [num / 10 for num in range(-100, 101, 1)]
and get 0.4 1.6 5.0 as best solutions.

In the Solution they calculate the datapoints like this:
possible_ms = [m * 0.1 for m in range(-100, 101)]
and get 0.30000000000000004 1.7000000000000002 4.999999999999999

Everything else is the same. Can please sb. explain where the the difference comes from?

My whole code:

def get_y(m, b, x):
  return m*x + b

def calculate_error(m, b, point):
    x_point = point[0]
    y_point = point[1]
    return abs(y_point - get_y(m, b, x_point))

possible_ms = [num / 10 for num in range(-100, 101, 1)]
possible_bs = [num / 10 for num in range(-200, 201, 1)]

datapoints = [(1, 2), (2, 0), (3, 4), (4, 4), (5, 3)]
smallest_error = float('inf')
best_m = 0 
best_b = 0

for m in possible_ms:
    for b in possible_bs:
        error = calculate_all_error(m, b, datapoints)
        if error < smallest_error:
            best_m = m
            best_b = b
            smallest_error = error
            
print(best_m, best_b, smallest_error)
1 Like

Hello, welcome on the forums!

You can find the whole explanation here

Basically 0.1 cannot be displayed as a binary (or base 2) number, just like we can’t divide 1 by 3 and get a non-repeating float as it will be 0.333333333333 and so on. So we sometimes use 0.3, just like python does when it approximates 0.1 in binary.

Note that this has nothing to do with codecademy or python, it is the nature of binary floating-point numbers.

2 Likes

I read the explanation and kind of understand how floating numbers are built using the binary system.
But shouldn’t there still be the same slightly false results regardless of using * 0.1 and / 10?
I guess the obvious answer is no but what is best practice then since you get two different results?
I also wouldn’t mind understanding the difference between *0.1 and / 10 :slight_smile:.

It is on the page which I sent you, regardless I found a more detailed explanation here.

You could use round with it’s ndigits parameter which will round the given number to the given precision in decimal digits.
You would use it like this:

arr = [m * 0.1 for m in range(-100, 101)]
arr = [round(item,14) for item in arr] # ndigits is the round function's second parameter
print(arr)

You could also convert it into a string and then after removing the last digit (because in this case it always was a float like 9.600000000000001), convert it back into a float