Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better way to check if a number is range of two numbers

I am trying to check if a number is in range of integers and returns a number based on which range it lies. I was wondering if is there a better and more efficient way of doing this:

def checkRange(number):
    if number in range(0, 5499):
        return 5000
    elif number in range(5500, 9499):
        return 10000
    elif number in range(9500, 14499):
        return 15000
    elif number in range(14500, 19499):
        return 20000
    elif number in range(19500, 24499):
        return 25000
    elif number in range(24500, 29499):
        return 30000
    elif number in range(29500, 34499):
        return 35000
    elif number in range(34500, 39499):
        return 40000
    elif number in range(39500, 44499):
        return 45000

This felt like a waste of resources and would greatly appreciate if there is a better way to do this.

like image 431
user13539846 Avatar asked May 31 '20 02:05

user13539846


People also ask

How do you elegantly check if a number is within a range?

The idea is to multiply (x-low) and (x-high). If x is in range, then it must be greater than or equal to low, i.e., (x-low) >= 0.

What operator is used to ensure that a number is between 2 numbers?

In Syntax 1, the – operator is the arithmetic subtraction operator used to find the difference between two numbers.

How do you find the range of numbers?

To find the range, first put all the numbers in order. Then subtract (take away) the lowest number from the highest.

How do you check if a number is within a range of another number Python?

You can check if a number is present or not present in a Python range() object. To check if given number is in a range, use Python if statement with in keyword as shown below. number in range() expression returns a boolean value: True if number is present in the range(), False if number is not present in the range.

How to check if a number is in range in Excel?

The function isInRange is used to find out if a number is in range or not. It takes three parameters: lower limit, an upper limit and the number itself. Note that we are using only one line inside the function to verify this. It will return true (or 1) if the number is greater than the lower limit and less than the upper limit.

How to check if x is in range?

The idea is to multiply (x-low) and (x-high). If x is in range, then it must be greater than or equal to low, i.e., (x-low) >= 0. And must be smaller than or equal to high i.e., (high – x) <= 0. So if result of the multiplication is less than or equal to 0, then x is in range. Else not. Thanks to eva for suggesting this method.

How to determine if a number or value is present in Excel?

Select the range you want to determine if a number or value is located, then click Kutools > Select > Select Specific Cells . 2.

How to select a cell in excel if number does not exist?

If the number or value exists in the specified range, you will get the following dialog box. Click the OK button, then the cell will be selected immediately. But if the number or value does not exist in the specified range, you will get the below dialog box.


5 Answers

Since you have continuous, sorted ranges, a quicker and less verbose way to do this, is to use the bisect module to find the index in a list of breakpoints and then use it to get the corresponding value from a list of values:

import bisect

break_points = [5499,  9499, 14499, 19499, 24499, 29499, 34499, 39499, 44499]
values       = [5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000]

n = 10000
index = bisect.bisect_left(break_points, n)

values[index]
# 15000

You'll need to test for n values that exceed the last breakpoint if that's a possibility. Alternatively you can add a default value to the end of the values list.

like image 54
Mark Avatar answered Oct 18 '22 21:10

Mark


If by better, you mean faster, it's a good idea to check the lower and upper limits, as the previous comments/answers have suggested.

However, note that in Python3, the range() object does this for you, resulting in the in range() check being a nearly constant time operation, so I don't think the runtime should be bad using your code.

I'd highly recommend reading this thread:

Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?

like image 6
adamgy Avatar answered Oct 18 '22 22:10

adamgy


If there are many ranges your solution becomes very verbose. You may want to give this (simpler) code a try:

limits = (0, 5500, 9500, 14500, 19500, 24500, 29500, 34500, 39500, 44500)

def checkRange(number):
    for i, (low, high) in enumerate(zip(limits[:-1], limits[1:]), 1):
        if low <= number < high:
            return 5000*i
    return 0  # when the passed number is out of range

It is worth pointing out that your logic has an off-by-one error, whereas in my implementation this issue is fixed.

Demo:

In [188]: checkRange(5499)
Out[188]: 5000

In [189]: checkRange(5500)
Out[189]: 10000

In [190]: checkRange(24872)
Out[190]: 30000
like image 4
Tonechas Avatar answered Oct 18 '22 21:10

Tonechas


If your ranges are set in stone you could loop through a list of your ranges:

ranges = [[0,5499],[5500,9499],[9500,14499],[14500,19499],[19500,24499],[24500,29499],[29500,34499],[34500,39499],[39500,44499]]
returns = [5000,10000,15000,20000,25000,30000,35000,40000,45000]

def checkRange(number):
    for i in range(len(returns)):
        if number in range(ranges[i][0], ranges[i][1]):
            return returns[i]

# Test a few values:
print(checkRange(10))
print(checkRange(6000))

I get output:

5000 
10000

Also, be sure to fix your 8th entry so that it is a range and not a single int.

like image 1
Willow Treeman Avatar answered Oct 18 '22 20:10

Willow Treeman


If your goal is really to do this kind of "rounding up" operation, it might be the fastest to just use math:

def round_up_to(num, factor):
    return -(-num // factor ) * factor

def checkRange2(num):
    if num < 5500:  # was this first interval perhaps a mistake?
        return 5000
    else:
        return round_up_to(num + 501, 5000))

This will work for arbitrarily large integers.

like image 1
chthonicdaemon Avatar answered Oct 18 '22 20:10

chthonicdaemon