Reputation: 1
Birth_date is an integer between 1 and 2359. Every animal is also part of a list. I want to convert the birth date to the list index but I'm not sure how.
if (birth_time >= 2300) or (birth_time < 100):
hour_animal = "RAT"
elif (birth_time >= 100) and (birth_time < 300):
hour_animal = "OX"
elif (birth_time >= 300) and (birth_time < 500):
hour_animal = "TIGER"
elif (birth_time >= 500) and (birth_time < 700):
hour_animal = "RABBIT"
elif (birth_time >= 700) and (birth_time < 900):
hour_animal = "DRAGON"
elif (birth_time >= 900) and (birth_time < 1100):
hour_animal = "SNAKE"
elif (birth_time >= 1100) and (birth_time < 1300):
hour_animal = "HORSE"
elif (birth_time >= 1300) and (birth_time < 1500):
hour_animal = "SHEEP"
elif (birth_time >= 1500) and (birth_time < 1700):
hour_animal = "MONKEY"
elif (birth_time >= 1700) and (birth_time < 1900):
hour_animal = "ROOSTER"
elif (birth_time >= 1900) and (birth_time < 2100):
hour_animal = "DOG"
elif (birth_time >= 2100) and (birth_time < 2300):
hour_animal = "BOAR"
Any thoughts on how this could be simplified?
Thanks!
Upvotes: 0
Views: 121
Reputation: 250961
You can use the bisect module here. Here bisect.bisect_right
finds the particular index in O(log N) time, so your chain of if
-elif
s is reduced to just a single if
:
import bisect
def solve(lis1, lis2, n):
ind = bisect.bisect_right(lis1, n) - 1
if 0 <= ind < len(lis1)-1:
return lis2[ind]
return 'RAT'
birth_time = [100, 300, 500, 700, 900, 1100, 1300, 1500, 1700, 1900, 2100, 2300]
hour_animal = ['OX', 'TIGER', 'RABBIT', 'DRAGON', 'SNAKE', 'HORSE', 'SHEEP', 'MONKEY', 'ROOSTER', 'DOG', 'BOAR']
Demo:
>>> solve(birth_time, hour_animal, 150)
'OX'
>>> solve(birth_time, hour_animal, 2400)
'RAT'
>>> solve(birth_time, hour_animal, 1300)
'SHEEP'
>>> solve(birth_time, hour_animal, 2300)
'RAT'
>>> solve(birth_time, hour_animal, 90)
'RAT'
>>> solve(birth_time, hour_animal, 1600)
'MONKEY'
Upvotes: 0
Reputation: 3908
You could set up a dict with min and max times, and return "RAT" as a default:
birth_times = {"OX": {"min":100, "max":300},
"TIGER": {"min":300, "max":500},
...
}
def animal(btime):
return ([k for k in birth_times.keys()
if birth_times[k]["min"] <= btime < birth_times[k]["max"]]
+ ["RAT"])[0]
Upvotes: 0
Reputation: 11102
Step 1:
if birth_time < 100:
hour_animal = "RAT"
elif birth_time < 300:
hour_animal = "OX"
elif birth_time < 500:
hour_animal = "TIGER"
elif birth_time < 700:
hour_animal = "RABBIT"
elif birth_time < 900:
hour_animal = "DRAGON"
elif birth_time < 1100:
hour_animal = "SNAKE"
elif birth_time < 1300:
hour_animal = "HORSE"
elif birth_time < 1500:
hour_animal = "SHEEP"
elif birth_time < 1700:
hour_animal = "MONKEY"
elif birth_time < 1900:
hour_animal = "ROOSTER"
elif birth_time < 2100:
hour_animal = "DOG"
elif birth_time < 2300:
hour_animal = "BOAR"
else:
hour_animal = "RAT"
Note that I put RAT in twice, at the start and end, and that let me remove half the conditions.
Step 2: Notice that the numbers are multiples of 100, and are 100 away from multiples of 200. So as @Hyperboreus 's solution (he submitted it while I was typing).
Upvotes: 0
Reputation: 32429
If your list starts with RAT
, the index should be (birth_time + 100) // 200 % 12
.
But better verify it:
signs = ['rat', 'ox', 'tiger', 'rabbit', 'dragon', 'snake', 'horse', 'sheep', 'monkey', 'rooster', 'dog', 'boar']
while True:
time = int(input('>> '))
print(signs[(time + 100) // 200 % 12])
Upvotes: 2