avi
avi

Reputation: 1846

Efficiently checking if number is in range of 2nd number +-10%?

I need to write a function which checks if a number is in range of 10% from another number.

I wrote this function:

def IsCloseEntough(num1, num2 ):
    percent = num1/100
    if num1-percent < num2 and num2< num1+percent:
       return True;
    else:
       return False;

It returns True if num1-10% of num1 < num2 < num1+10%. This solves the problem however it feels like this code isn't very "Python Like". Is there a way to make it simpler?

Upvotes: 4

Views: 221

Answers (3)

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160417

PEP 0485 introduced the math.isclose() function (and it's complex cousin cmath.isclose() for making these sort of checks; it also checks for special values such as NaN, Inf et al. The apparent downside is, it only appears in Python 3.5 from what I know and it's still in it's infancy so it might get some face-lifts in the future.

Basic functionality:

math.isclose(1, 1.09, abs_tol=0.1)
Out[20]: True

math.isclose(1.0, 1.2, abs_tol=0.1)
Out[23]: False

math.isclose(1.0, 0.9, abs_tol=0.1)
Out[24]: True

This is a built-in (so you could use it efficiently with things like filter() ) that's made to check how close two numerics are and allows for greater flexibility when trying to find approximations.

Internally it uses the abs solutions in a similar manner presented here, take a look at the C source for yourself, it is most likely as efficient as it can get. (A version of it python can be found here)

For older versions of Python, you could use the solutions already pointed out or look at how math.isclose() was implemented and get inspired.


Note that in most cases rel_tol should be specified, unless dealing with values near 0. Additionally, for cases where array elements should be evaluated, the most efficient use is probably supplied by the numpy.isclose() function.

Upvotes: 8

MaTh
MaTh

Reputation: 217

You can do

def IsCloseEnough(num1, num2 ):
     return abs(float(num1 - num2) / float(num1)) < 0.1 

Upvotes: 6

tobias_k
tobias_k

Reputation: 82899

I think the clearest way is very close to your function, with a few alterations:

  • you check whether the number is within 1%, not within 10%
  • you can use comparison chaining
  • you can directly return the result, instead of using an if/else

Like this:

def isCloseEnough(num1, num2):
    return num1 * 0.9 < num2 < num1 * 1.1

Upvotes: 5

Related Questions