hallwyatt
hallwyatt

Reputation: 3

Is there a more elegant way to find where a value fits in a range of values?

I am writing some code that takes in a number and gives that number a score. For example:

    if rev >= 300000000:
        return 10 # this is the score
    elif rev >= 200000000 and rev < 300000000:
        return 7
    elif rev >= 100000000 and rev < 200000000:
        return 5
    elif rev >= 30000000 and rev < 100000000:
        return 3
    else:
        return 1

Is there a more elegant way to do this? I'm new to programming and I couldn't think of another way to search this.

Upvotes: 0

Views: 776

Answers (3)

Gabriel A.
Gabriel A.

Reputation: 641

You could store your values in an array and traverse it based on the numbers of other array. For optimal result, use a ordered array and a binary search. Luckily numpy get us covered

import numpy as np

values = [3e7, 1e8, 2e8, 3e8] # Must be sorted ascending
scores = [1, 3, 5, 7, 10] # One more element than values

return scores[np.searchsorted(values, rev, side='right')]

Upvotes: 0

sytech
sytech

Reputation: 40871

The answer provided by Prune is good for iterating over your ranges and the expected outputs.

I'll add to this by saying you can replace this:

elif rev >= 200000000 and rev < 300000000

With

elif rev in range(200000000, 300000000):
    ...

The contains operator (used for in) for range objects does basically the equivalent operation, provided you're not using floating point values.

Although in Prune's answer, this is obviated because you don't actually need the range.

Upvotes: 0

Prune
Prune

Reputation: 77837

First, your code is redundant: you repeat several value checks. Instead:

if rev >= 300000000:
    return 10 # this is the score
elif rev >= 200000000:
    return 7
elif rev >= 100000000:
    return 5
elif rev >= 30000000:
    return 3
else:
    return 1

Now, generalize the problem: make a list of cutoffs and corresponding scores:

cutoff = [
    (3e8, 10),
    (2e8,  7),
    (1e8,  5),
    (3e7,  3),
    (0e1,  1)
]

Iterate through this list, checking rev against the cutoff value. When you fail a ">=" check, return the previous point value.

Implementation is left as an exercise for the student. Look out for the end-of-list case, too.

Upvotes: 2

Related Questions