[Tutor] Setting thresholds in a compact way
Martin A. Brown
martin at linux-ip.net
Wed Jan 1 22:25:49 EST 2020
Hello there,
>First of all let me wish a great 2020 for all of you kind souls and seekers
>of knowledge :)
>
>I am trying to setup a varying time.sleep value (in house) depending on a
>priorly determined threshold.
>
>If threshold <= .9 AND > .8 then sleep should be 6 hours
>if threshold <= 0.8 AND > .4 then sleep should be 4 hours
>if threshold <= .4 AND > .1 then sleep should be 3 hours
>if threshold <= .1 then sleep should be set to 1 hour
>
>Instead of a complex/lengthy series of (nested?) if/ands based on the
>above, I was wondering if I could declare a dictionary such as:
>
>sleep_thresholds_hours = {.9:6, .8:4, .4:3, .1:1}
>
>And then use some sort of single statement to set the sleep_time to the the
>proper value.
I saw the thread here and thought I'd spend a few minutes writing a few
functions that I think you might find helpful.
I like the suggestion Mats had about multiplying (or using some other
mathematical function) based on the input value. But, that may not work in
your case.
I don't know how to apply the sparse array solution, suggested by Alan.
Here is an example or two, of possible utility. If you are simply testing
ranges, you can always cover the search space in order (I start from the
"bottom"):
def series_of_ifs(val):
assert val == abs(val) # -- ineffably positive
if val <= 0.0: return None
if val <= 0.1: return 1
if val <= 0.4: return 3
if val <= 0.8: return 4
if val <= 0.9: return 6
return None
def data_driven_dict(val):
assert val == abs(val) # -- ineffably positive
thresholds = [(0, None),
(0.1, 1),
(0.4, 3),
(0.8, 4),
(0.9, 6)
]
for threshold, result in thresholds:
if val <= threshold:
return result
return None
Attached is a small script with these functions and a little testing
code around them, that should allow you to test other ways of
writing what you want.
If I knew I would want to monkey with the thresholds later, I'd use
the data_driven_dict() solution.
Oh, and I didn't know what you wanted to do with values above 0.9,
so I just chose to "return None" for those. Also, given your sample
data, I sort of assumed that your data were in the range of [0, 1),
but if they are not, you may need to handle negative, as well. I
chose to assert, effectively terminating the program if the value is
negative.
>Not even quite sure that using floats (albeit single decimal) as dictionary
>keys will be ok.
Yep! This will be quite OK. This may be a bit odd, but from a
Python interpreter, I used something as a key, and then, for no
specific reason, I assigned the value to the type of that value.
Which had the amusing side effect that after I was done, I could
write a little loop to assert that the key (retrieved in a loop) was
actually of the type indicated.
>>> d = dict()
>>> d[17] = int
>>> d[0.2] = float
>>> d['hedgehog'] = str
>>> d[('a', 'b', 7)] = tuple
>>> d
{17: <type 'int'>, ('a', 'b', 7): <type 'tuple'>, 0.2: <type 'float'>, 'hedgehog': <type 'str'>}
>>> for k, v in d.items():
... assert type(k) is v
...
>>>
Best of luck,
-Martin
--
Martin A. Brown
http://linux-ip.net/
More information about the Tutor
mailing list