Reputation: 29
As I ended up with many ugly if-elif's when comparing temperature to determine an adjective for the temperature, I thought that I can look for the temperature value in a list in a dictionary, where its key will be the corresponding adjective for the temperature:
def deternmine_temp(temp):
temps = {
'FREEZING' : [i for i in range(-20, 0)],
'very cold' : [i for i in range(0, 6)],
'cold' : [i for i in range(6, 11)],
'chilly' : [i for i in range(11, 16)],
'cool' : [i for i in range(16, 21)],
'warm' : [i for i in range(21, 26)],
'hot' : [i for i in range(26, 31)],
'very hot' : [i for i in range(31, 36)],
'dangerously hot' : [i for i in range(36, 40)],
'extremely dangerously hot': [i for i in range(41, 46)]
}
temp = int(temp.replace('°', '').strip())
for word, values in temps.items():
if temp in values:
return word
This is a lot better than 7+ if-elif's, but I don't think it is very efficient, especially if temps had a lot more data (for example if I had a narrower range of values that correspond to an adjective).
What would be some ways to make this more efficient? Maybe some functions in the dictionary? Above is really the best I can think of.
Upvotes: 1
Views: 89
Reputation: 29
This is closest to what i was looking for.
def switch(x):
return {
-20<x<=2: 'FREEZING',
2<x<=5: 'very cold',
5<x<=10: 'cold',
10<x<=15: 'chilly',
15<x<=22: 'cool',
22<x<=25: 'warm',
25<x<=30: 'hot',
30<x<=33: 'very hot',
33<x<=35: 'extremely hot',
35<x<=40: 'dangerously hot'
}[1]
print(switch(40))
output:
dangerously hot
Upvotes: 0
Reputation: 57105
If you decide to represent temperature as a floating-point number, your code in general will not work. To make sure your code works with non-integer temperatures (just in case), represent ranges as pairs of min-max values and use explicit comparison:
temps = {
'FREEZING' : (-20, 0),
'very cold' : (0, 6),
....
}
for word, values in temps.items():
if values[0] <= temp < values[1]:
return word
You may as well use a list of tuples because you do not use dictionary-specific functionality:
temps = [
('FREEZING', -20, 0),
('very cold', 0, 6),
....
]
for word, value1, value2 in temps:
if value1 <= temp < values2:
return word
Finally, for consistency, you may define only the upper range boundary (which simultaneously is the lower boundary of the next range):
temps = [
('FREEZING', 0),
('very cold', 6),
....
('extremely dangerously hot': float('inf'))
]
for word, value in temps:
if temp < value:
return word
Upvotes: 0
Reputation: 50909
You need to store the ranges somehow, and since the ranges don't have the same interval you can't really shorten the dictionary initialization. You can extract the dictionary creation to a function, however you will still have to call it as many times as you have options.
You can however remove the list comprehension from the dictionary and replace the loop with next
def deternmine_temp(temp):
temps = {
'FREEZING': range(-20, 0),
'very cold': range(0, 6),
'cold': range(6, 11),
'chilly': range(11, 16),
'cool': range(16, 21),
'warm': range(21, 26),
'hot': range(26, 31),
'very hot': range(31, 36),
'dangerously hot': range(36, 40),
'extremely dangerously hot': range(41, 46)
}
temp = int(temp.replace('°', '').strip())
return next((word for word, values in temps.items() if temp in values), None)
Upvotes: 1