3

This is my exercise: get the user's first name, last name and birth year. Create initials from the name (first letter) and calculate the age of the user.

I wrote a script:

def age_name():
    # var= firstName ,lastName ,year
    is_running=True
    firstName =input("What is your name?").lower()
    while is_running==True:
        if firstName.isalpha() and len(firstName)>0:
            lastName = input("What is your last name?").lower()
            if lastName.isalpha() and len(lastName) > 0:
                year = input("What is your birth year?")
                if year.isnumeric() or len(year)==4:
                    year=int(year)
                    print("Your initials are {0}{1} and your age is {2}.".format(firstName[0],lastName[0],2018-year))
                    #print("Your initials are ",firstName[0],lastName[0],"and your age is ",str(2018-year))
                else:
                    print("invalid year. please type your birth year")
                    year = input("What is your birth year?")
            else:
                print("invalid last name. please type your last name")
                lastName = input("What is you last name?").lower()
        else:
            print("invalid name. please type your name")
            firstName = input("What is you name?").lower()

age_name()

I've tested the code and this is what I get:

What is your name?p5
invalid name. please type your name
What is you name?peter
What is your last name?p5
invalid last name. please type your last name
What is you last name?pen
What is your last name?pen
What is your birth year?p5
invalid year. please type your birth year
What is your birth year?10
What is your last name?pen
What is your birth year?1800
Your initials are pp and your age is 218.
What is your last name?

First of all, I think my code is a bit repetitive - if someone has ideas to shorten it. Second and biggest problem - I keep getting the last name question. Where is my bug?

Nick
  • 4,820
  • 18
  • 31
  • 47
V.H
  • 43
  • 1
  • 4
  • Looks like you never alter `is_running`? – syntonym May 26 '18 at 11:44
  • Welcome to StackOverflow. I would consider putting each of the three parts (first name, last name, year) in a separate function. Currently, an invalid entry messes up the flow. You should set `isRunning = False` at some point, once it is finished. – Chris May 26 '18 at 11:45
  • To create specific functions and error handling is also the [consensus of this canonical thread](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) – Mr. T May 26 '18 at 14:41

3 Answers3

1

I think the best readable while least error prone way would be sth like below. The input lines are programmed only once each and everything is dependent on the state of response_invalid.

def age_name():
    response_invalid = True
    while response_invalid:
        firstName = input("What is your name?").lower()
        if firstName.isalpha() and len(firstName)>0:
            response_invalid = False
        else:
            print("invalid name. please type your name")
    response_invalid = True
    while response_invalid:
        lastName = input("What is your last name?").lower()
        if lastName.isalpha() and len(lastName) > 0:
            response_invalid = False
        else:
            print("invalid last name. please type your last name")
    response_invalid = True
    while response_invalid:
        year = input("What is your birth year?")
        if year.isnumeric() or len(year)==4:
            response_invalid = False
        else:
            print("invalid year. please type your birth year")
    year=int(year)
    print("Your initials are {0}{1} and your age is {2}.".format(firstName[0],lastName[0],2018-year))

However, this is the verbose variant of a very common way to implement this, which is I think the shortest, but a little rude...:

def age_name():
    while True:
        firstName = input("What is your name?").lower()
        if firstName.isalpha() and len(firstName)>0:
            break
        print("invalid name. please type your name")
    while True:
        lastName = input("What is your last name?").lower()
        if lastName.isalpha() and len(lastName) > 0:
            break
        print("invalid last name. please type your last name")
    while True:
        year = input("What is your birth year?")
        if year.isnumeric() or len(year)==4:
            break
        print("invalid year. please type your birth year")
    year=int(year)
    print("Your initials are {0}{1} and your age is {2}.".format(firstName[0],lastName[0],2018-year))
SpghttCd
  • 10,510
  • 2
  • 20
  • 25
0

How does this look?

def age_name():
    firstname=input("What is your name?")
    while firstname.isalpha()!=True:
        print("Invalid name, enter again")
        firstname = input("What is your name?")
    lastname = input("What is your last name?")
    while lastname.isalpha()!=True:
        print("Invalid name, enter again")
        lastname = input("What is your last name?")
    year = input("What is your birth year?")
    while len(year) != 4 and year.isdigit():
        print("Invalid year, enter again")
        year = input("What is your birth year?")
    year = int(year)
    print("First Name:",firstname,"\nLast Name:",lastname,"\nBirth Year:",year)

age_name()
loksoni
  • 177
  • 3
  • 12
-1

That looks so much better. Thank you. but look at the error I get when I type year whis letters: What is your birth year?g5
ValueError: invalid literal for int() with base 10: 'g5'. i've changed the last while operator from and to or and it works beautifully.

V.H
  • 43
  • 1
  • 4
  • This was probably intended as a comment to [loksoni's answer](https://stackoverflow.com/a/50543064/3364859)? – marianoju Nov 23 '21 at 09:07