Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Looping a Program
#1
I am new in Python, however I am not a student learning programming. I just thought that learning how to code is a fun thing to do. I have the latest version in 32-bit installed in Windows 8.1.
Today I made a code that prints out a name of a student and his corresponding score. Here is my code:

print("Enter the name and scores of your students.")
name = str(input("Enter name: "))
score = int(input("Enter score: "))
while score != 0 and score != 1 and score != 2 and score != 3 and score != 4 and score != 5:
    print("Only numbers 0 to 5 are acceptable!")
    score = int(input("Enter score: "))
    print()
else:
    if score == 0:
        print(name,"got a grade of F.")
    elif score == 1:
        print(name,"got a grade of E.")
    elif score == 2:
        print(name,"got a grade of D.")
    elif score == 3:
        print(name,"got a grade of C.")
    elif score == 4:
        print(name,"got a grade of B.")
    elif score == 5:
        print(name,"got a grade of A.")
I want to include another line below which requires an input, that gives option whether the user would still like to use the program or to exit. The problem comes with looping this whole set of codes. If it is possible, how can I do it? Thanks for the help.
Sorry if my post is badly formatted, this is my first post. And python is fun :)
Reply
#2
Here's a variation of your code with the requested loop added (explanation follows):

while True:
    print("Enter the name and scores of your students.")
    name = str(input("Enter name: "))
    score = int(input("Enter score: "))

    while score != 0 and score != 1 and score != 2 and score != 3 and score != 4 and score != 5:
        print("Only numbers 0 to 5 are acceptable!")
        score = int(input("Enter score: "))
        print()
        else:
            if score == 0:
                print(name,"got a grade of F.")
            elif score == 1:
                print(name,"got a grade of E.")
            elif score == 2:
                print(name,"got a grade of D.")
            elif score == 3:
                print(name,"got a grade of C.")
            elif score == 4:
                print(name,"got a grade of B.")
            elif score == 5:
                print(name,"got a grade of A.")

    while True:
        repeat = input("Would you like to continue? Y/N")
        
        if repeat.lower() not in ("y", "n"):
            print("Invalid input.\n")
        else: break

    if repeat.lower() == "n":
        print("Goodbye")
        break
On line 1, I added another while loop to encompass the full code. On lines 24 through 29, I added a while loop inside to vet the user input to ensure that the input is acceptable. This ensures that the input is something the remainder of the code recognizes and obviates errors arising from unrecognized inputs.

On lines 27 and 31, I call the lower() method on our input string. If capitalization is not important to our inputs, we can user lower() or upper() methods to control the capitalization of the string for comparison. Doing this allows the user to enter "Y", "y", "N", or "n" and the program will recognize them because at the comparison they change to either "y" or "n".

Line 29 breaks the inner while loop for the inputting vetting. Break terminates the associated loop. Likewise, on line 33, I have another break to terminate the outer loop that encompasses the full code if the user wants to end it.

Now, with that out of the way, we can make this code more Pythonic...

Let's change the first while loop inside the code to an if statement with a tuple. Change:

while score != 0 and score != 1 and score != 2 and score != 3 and score != 4 and score != 5:
        print("Only numbers 0 to 5 are acceptable!")
        score = int(input("Enter score: "))
        print()
To:

if score not in  ("0",  "1",  "2",  "3",  "4",  "5"):
    print("Only numbers 0 to 5 are acceptable!")
    continue
The interpeter will iterate over the tuple to check if the inputted score is in the tuple. You may also notice that the numbers are now strings; I removed the calls to str() and int() on lines 12 and 13 because they are unneeded. This change also continues our while loop to employ our initial input when the score input is not acceptable and it can repeat that ad infinitum as needed.

Your if statement can be change to a dictionary:

if score == 0:
    print(name,"got a grade of F.")
elif score == 1:
    print(name,"got a grade of E.")
elif score == 2:
    print(name,"got a grade of D.")
elif score == 3:
    print(name,"got a grade of C.")
elif score == 4:
    print(name,"got a grade of B.")
elif score == 5:
    print(name,"got a grade of A.")
can change to:

grades = {
    "0": "F",
    "1": "E",
    "2": "D",
    "3": "C",
    "4": "B",
    "5": "A"
}
then, when we assign the grade, we can do this:

grade = grades[score]
The last big change is your print:

print(name,"got a grade of A.")
While there is nothing wrong with this, we can make this more concise with a f-string (format string):

print(f"{name} got a grade of {grade}.")
Format strings (and a couple other methods for formatting a string) pick up the value of the variables in the curly braces and replaces the variable call in the string with the value.

So, the updated code becomes:

grades = {
    "0": "F",
    "1": "E",
    "2": "D",
    "3": "C",
    "4": "B",
    "5": "A"
}

while True:
    print("Enter the name and scores of your students.")
    name = input("Enter name: ")
    score = input("Enter score: ")

    if score not in  ("0",  "1",  "2",  "3",  "4",  "5"):
        print("Only numbers 0 to 5 are acceptable!")
        continue

    grade = grades[score]

    print(f"{name} got a grade of {grade}.")

    while True:
        repeat = input("Would you like to continue? Y/N")

        if repeat.lower() not in ("y", "n"):
            print("Invalid input.\n")
        else: break

    if repeat.lower() == "n":
        print("Goodbye")
        break
Reply
#3
Is this what you are looking for?

marks = {i: s for i, s in enumerate(['E', 'D', 'C', 'B', 'A'])}

while True:
    print("Enter the name and scores of your students.")
    name = input("Enter name: ")
    score = int(input("Enter score: "))
    while score not in marks:
        print("Only numbers 0 to 5 are acceptable!")
        score = int(input("Enter score: "))
        print()
    print("{} got a grade of {}.".format(name, marks[score]))

    again = ''
    while again not in ['y', 'n']:
        again = input('\nAgain? [y/n]')
    if again == 'n':
        break
Reply
#4
One way of doing it:

while True:
    print("Enter the name and scores of your students.")
    name = input("Enter name: ")
    while True:
        try:
            score = int(input("Enter score: "))
            if score in range(6):
                break
            else:
                print('Only numbers 0 to 5 are acceptable!')
        except ValueError:
            print('Only numbers 0 to 5 are acceptable!')

    for i, v in enumerate(['F', 'E', 'D', 'C', 'B', 'A']):
        if i == score:
            grade = v

    print(f'{name} got a {grade}')
    repeat = input('Would you like to continue? Y/N ').lower()
    if repeat == 'y':
        continue
    else:
        break
This code will repeat only when user enter either 'Y' or 'y'. All other entries will end the program
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.
Reply
#5
To simplify this thread, I split the discussion about best practices into its own thread here: https://python-forum.io/Thread-split-Looping-a-Program
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Need help looping this program JakobeTheKid 1 2,108 May-19-2019, 05:30 AM
Last Post: SheeppOSU
  [split] Looping a Program volcano63 7 4,075 Oct-09-2018, 12:26 AM
Last Post: micseydel

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020