0

I want to compare 2 dictionaries only if they meet one of two conditions: either they are equivalent or (more likely) they complement each other in a certain way described below. Do evaluate this, I take values from 2 dictionaries, multiply them together, and run them by a True/False statement. This is my function:

def permissible(dict1,dict2):
    a = dict1['conv_factor']
    b = dict2['conv_factor']
    return a*b == 1.0 or dict1 == dict2

However, when I execute the function, it comes up False, even when mathematically it comes up as True.

source_dict = {'mm': 1, 'cm': 10, 'm': 1000, 'km': 1000000, 'conv_factor': 0.03937007874015748}

dest_dict = {'in': 1, 'ft': 12, 'yd': 36, 'mi': 63360, 'conv_factor': 25.4}

>>>print(permissible(source_dict,dest_dict))
>>>False

The multiplication of a x b evaluates to (1/25.4) x 25.4, which equals 1.0. When I have python print a x b, it returns 1.0. So I am not sure why I can't get the boolean statement to return true.

Dominic D
  • 1,778
  • 2
  • 5
  • 12
  • You have stored an approximate value of `1/25.4` so whrn mulitplyng by 25.4 you don't get 1 exactly – azro Jun 07 '20 at 07:36

2 Answers2

0

This is an issue with floating point arithmetic not being completely precise. If I run the computation in python, I get a value very close but not equal to 1.0.

>>> 0.03937007874015748 * 25.4
0.9999999999999999

Instead, check if the value is close enough to 1.

def permissible(dict1,dict2):
    a = dict1['conv_factor']
    b = dict2['conv_factor']
    return abs((a*b) - 1.0) < 0.00001 or dict1 == dict2
Dominic D
  • 1,778
  • 2
  • 5
  • 12
  • Thank you, I was confused about how python was storing the data. The abs() function works well. The only thing is abs() is its own function, not part of the math module in python 3 – Ari Melinger-Cohen Jun 07 '20 at 21:26
0

You have stored an approximate value of 1/25.4, so multiplying by 25.4 again doesn't give out one

print(0.03937007874015748*25.4) # 0.9999999999999999

But, you're lucky, there is an final value not so far, you may have done print(1/25.4) # 0.03937007874015748 to get it, to know if there a final value, use a bigher numerator like 10**9

print(10**9/25.4) # 39370078.740157485

Which says that the final value you want is 0.039370078740157485 # 5 at the end


For comparing float for almost-equality you can do

return abs(a*b - 1.0)<0.00001 or dict1 == dict2
azro
  • 53,056
  • 7
  • 34
  • 70