0

I just completed a video exercise from The Modern Python Bootcamp by Colt Steele (Udemy) - Object Oriented Programming. The exercise uses a class User that has attributes for first name, last name, and age. There is also a class method birthday() that wishes the person a happy birthday along with their age.

The issue I have with the birthday method is that it has a static "th" after the person's age, which doesn't make sense if the person is 1, 61, 52 etc. How can I determine if the number has a 1 or 2 at the end or in the case of 1st the begin of the number? Would I have to create a tuple that I test against age?

class User:
    def __init__(self, first, last, age):
        self.first = first
        self.last = last
        self.age = age

    def full_name(self):
        return f"{self.first} {self.last}"

    def initials(self):
        return f"{self.first[0]}.{self.last[0]}."

    def likes(self, thing):
        return f"{self.first} likes {thing}"

    def is_senior(self):
        return self.age >= 65

    def birthday(self):
        self.age += 1
        return f"Happy {self.age}th, {self.first}"


user1 = User("Joe", "Smith", 21)
user2 = User("Blanca", "Lopez", 20)

print(user2.is_senior())
print(user2.birthday())
print(user1.age) 
ndmeiri
  • 4,979
  • 12
  • 37
  • 45
user3574939
  • 819
  • 3
  • 17
  • 34

2 Answers2

1

You can use if-else condition to manually check, though. Something like this:

def birthday(self):
    age = self.age + 1
    age_str = str(age)
    if age // 10 == 1:
        age_str += 'th'
    elif age % 10 == 1:
        age_str += 'st'
    elif age % 10 == 2:
        age_str += 'nd'
    elif age % 10 == 3:
        age_str += 'rd'
    else:
        age_str += 'th'
    return f"Happy " + age_str + ", {self.first}"
Trung Tran
  • 101
  • 6
1

The simplest thing to do is:

if self.age%10 == 1:
    # print with st
elif self.age%10 == 2:
    # print with nd
elif self.age%10 == 3:
    # print with rd
else:
    # print with th

The first thing to do is look for edge cases that might be wrong. What happens with 11? 13? 21? 101? 111? Find all you can and add the logic.

Next, look for a way to simplify things by refactoring. Your four print statements will be nearly identical, except for that st/nd/rd/th, so change the if/elif/else to just do, say, suffix = 'st', and then you can have a single print that includes {suffix}. What about that repeated age%10? Is it worth storing that in a variable, like lastdigit, to avoid repeating yourself? Try it and see.

Also look for whether a data structure can help simplify your logic. If you had a dict that mapped {1: 'st', 2: 'nd', 3: 'rd'}, you could just do suffix = d.get(lastdigit, 'th'), which seems cleaner. But it might not be once you add in dealing with '11' and the like. Again, try it and see.

Finally, this is the kind of thing you’re likely to need more than once. Maybe not in this program, but other programs you write may want to do '2nd'. So extract the suffixing code into a function. Maybe one that takes a number, and returns the ordinal string with the number and suffix together.

abarnert
  • 354,177
  • 51
  • 601
  • 671