Posts: 43
Threads: 23
Joined: Jan 2017
Hi all, I dont like my implementation of a cat-human age converter, could you please suggest a a more pythonic approach?
"""
First, allow 15 human years for the first year of your cat's life.
Then, add 9 years for the second year. For instance, a 2-year-old cat will be approximately 24 human years.
Next, add 4 human years for each successive year of your cat's life.
Finally, refer to the accompanying cat-age-to-human-age chart to double check your calculation.
"""
def human_age(cat_age):
total = 0
if cat_age == 1:
total += 15
if cat_age == 2:
total += 15 + 9
if cat_age > 2:
total += (15 + 9) + (cat_age - 2) * 4
return total
Posts: 4,220
Threads: 97
Joined: Sep 2016
I don't think that's necessarily un-Pythonic. If al of the comparisons were >=, to 1, 2, and 3; then you could avoid dupicating the 15 and the 9:
def human_age(cat_age):
total = 0
if cat_age >= 1:
total += 15
if cat_age >= 2:
total += 9
if cat_age >= 3:
total += (cat_age - 2) * 4
return total If you wanted to get rid of the if statements altogether, you could have a list of the human years for each cat year ([15, 9, 4, 4, 4, ...]) and them sum the relevant number of years. Of course, you can't be sure how long that list needs to be. Wikipedia says the oldest reported cat age was 38 years old, although some of those numbers look pretty sketchy.
Posts: 8,165
Threads: 160
Joined: Sep 2016
Oct-27-2019, 08:43 PM
(This post was last modified: Oct-27-2019, 08:43 PM by buran.)
def cat2man(cat_years):
human_years = {1:15, 2:24}
return human_years.get(cat_years, 24 + (cat_years-2)*4)
for cat_years in range(1, 5):
print(f'{cat_years} cat year(s) are equal to {cat2man(cat_years)} human years') def cat2man2(cat_years):
human_years = {0:15, 1:9}
return sum(human_years.get(n, 4) for n in range(cat_years))
for cat_years in range(1, 5):
print(f'{cat_years} cat year(s) are equal to {cat2man2(cat_years)} human years') these are two implementations that will print
1 cat year(s) are equal to 15 human years
2 cat year(s) are equal to 24 human years
3 cat year(s) are equal to 28 human years
4 cat year(s) are equal to 32 human years It's up to you to decide if they are more pythonic. I qgree with ichabood that your code is not neccessarily un-pythonic
maybe I would simplify it like
def human_age(cat_age):
if cat_age == 1:
total = 15
elif cat_age == 2:
total = 24
elif cat_age >= 3:
total = 24 + (cat_age - 2) * 4
return total or even
def human_age(cat_age):
if cat_age == 1:
return 15
elif cat_age == 2:
return 24
elif cat_age >= 3:
return 24 + (cat_age - 2) * 4 all of the above may need extra lines of code to handle incorrect/invalid input like negative, float, str, etc.
Posts: 1,950
Threads: 8
Joined: Jun 2018
Another way is to combine sum, itertools.repeat() and slice:
from itertools import repeat
def human_age(cat_age):
return sum([15, 9, *repeat(4, cat_age - 2)][:cat_age]) This handles 0 age correctly as well.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 4,220
Threads: 97
Joined: Sep 2016
Good old Python, with it's one, obvious way to do things.
Posts: 2,128
Threads: 11
Joined: May 2017
from itertools import repeat, islice
def human_age(cat_age):
return sum(islice((15, 9, *repeat(4, cat_age - 2)), 0, cat_age)) def human_age(cat_age):
formula = (cat_age - 2) * 4
return sum(islice((15, 9, formula), 0, cat_age)) But for beginners this is hard to understand. Most people do have problems with functional style.
I like the itertools approach very much, because you can process with it infinite data without blowing up your memory consumption. But in general the iteration is slower, than working with list-comprehension.
Posts: 1,358
Threads: 2
Joined: May 2019
Perhaps a bit simpler to understand
def human_age(cat_age):
return (cat_age>0)*15+(cat_age>1)*9+(cat_age>2)*(cat_age-2)*4 Also works for 0.
Posts: 17
Threads: 0
Joined: Nov 2019
The Zen of Python: Readability counts.
just kidding. :D
Posts: 4,801
Threads: 77
Joined: Jan 2018
Nov-02-2019, 09:49 AM
(This post was last modified: Nov-02-2019, 09:49 AM by Gribouillis.)
Here is a very readable solution
def human_age(cat_age):
x = cat_age
return 8 - 3 * abs(x - 1) - 2.5 * abs(x - 2) + 9.5 * x It also works for fractional ages such as 4.5 years.
|