5
\$\begingroup\$

This is for an assignment in my robotics class so the requirements I needed to meet was that it had to be in a while loop and the input numbers needed to be float point. I just want to make sure that I'm not using any bad practices and if there are any areas that can be improved.

while (True):
    # Gets operator, converts to int and breaks if its not a number
    try: operator = int(input("Choose an Operator:\n1) Addition\n2) Subtraction\n3) Multiplication\n4) Division\nInput (1/2/3/4):"))
    except:
        print('Invalid Input: Choose A Valid Operation')
        break
    
    # Checks the operator is within 1 and 4
    if operator > 4 or operator < 1: 
        print('Invalid Input: Choose A Valid Operation')
        break
    
    # Gets first and second number, converts numbers to float and breaks if its not a number
    try: firstnum = float(input('First Number:'))
    except: 
        print('Invalid Input: Not a valid number')
        break
    try: secondnum = float(input('Second Number:'))
    except: 
        print('Invalid Input: Not a valid number')
        break
    
    if operator == 1:
        print('{0} + {1} ='.format(firstnum, secondnum), end =" ")
        print(firstnum + secondnum)
        break
    if operator == 2:
        print('{0} - {1} ='.format(firstnum, secondnum), end =" ")
        print(firstnum - secondnum)
        break
    if operator == 3:
        print('{0} * {1} ='.format(firstnum, secondnum), end =" ")
        print(firstnum * secondnum)
        break
    if operator == 4:
        print('{0} / {1} ='.format(firstnum, secondnum), end =" ")
        print(firstnum / secondnum)
        break
\$\endgroup\$
  • \$\begingroup\$ consider accepting one of the answers :) \$\endgroup\$ – Aryan Parekh Oct 2 at 11:39
3
\$\begingroup\$

Formatting strings in Python

foo = 5
print('{foo}'.format(foo))

This is a nice way to format string, But there is a short and cleaner way to format strings in Python 3 known as the f-String. The problem with str.format() is that if you have multiple parameters. Your string starts to look a little werid.For example

first_name = "Eric"
last_name = "Idle"
age = 74
profession = "comedian"
affiliation = "Monty Python"
print(("Hello, {first_name} {last_name}. You are {age}. " + 
        "You are a {profession}. You were a member of {affiliation}.") \
        .format(first_name=first_name, last_name=last_name, age=age, \
               profession=profession, affiliation=affiliation))

With f-strings. The same would look like.

print(f"Hello, {first_name} {last_name}. You are {age}. " +
      f"You are a {profession}. You were a member of {affiliation}.")

This is why you should prefer using f-strings.

eval in Python

When you want to perform the arithmetic part, I see that you have used a thread of if-statements. But we can use Python's eval function to make life much easier. We simple place the operator entered by the user un between the two numbers.

old

if operator == 1:
    print('{0} + {1} ='.format(firstnum, secondnum), end =" ")
    print(firstnum + secondnum)
    break
if operator == 2:
    print('{0} - {1} ='.format(firstnum, secondnum), end =" ")
    print(firstnum - secondnum)
    break
if operator == 3:
    print('{0} * {1} ='.format(firstnum, secondnum), end =" ")
    print(firstnum * secondnum)
    break
if operator == 4:
    print('{0} / {1} ='.format(firstnum, secondnum), end =" ")
    print(firstnum / secondnum)
    break

We ask the user to enter the operation the want directly , for example

Choose an operator: +

Or if you want to stick to using numbers. operators = operators = {'+':1,'-':2,'*':3,'/':4}

I have gone with the 1st method. You can use whatever you prefer to

new

print(f"{firstnum} {operator} {secondnum} = {float(eval(firstnum + operator + secondnum))}")

The new code using eval would like

operators = ['+','-','*','/']
while (True):
    # Gets operator, converts to int and breaks if its not a number
    try: operator = input("Choose an Operator:\n1) Addition\n2) Subtraction\n3) Multiplication\n4) Division\nInput\n(+,-,*,/):")
    except:
        print('Invalid Input: Choose A Valid Operation')
        break

    # Checks the operator is within 1 and 4
    if operator not in operators:
        print('Invalid Input: Choose A Valid Operation')
        break

    # Gets first and second number, converts numbers to float and breaks if its not a number
    try: firstnum = input('First Number:')
    except:
        print('Invalid Input: Not a valid number')
        break
    try: secondnum = input('Second Number:')
    except:
        print('Invalid Input: Not a valid number')
        break

    print(f"{firstnum} {operator} {secondnum} = {float(eval(firstnum + operator + secondnum))}")

With that simple change, I removed about 20 lines of code into one. Making it much more readable

Clearing the screen

It would be nicer to see a clear terminal after finishing one job. There are many ways to clear the terminal in python. A common way for windows users is

os.system('cls')

But this way is considered bad as it is quite expensive. You can get away by simply

print(chr(27) + "[2J")

Adding this to the start of each iteration in the while(True): loop will give a better experience to the user.

Waiting for input

Lastly, adding this line of code to the end will pause on the current text before going to the next one. input("Press any key to continue...")

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

I don't think the program should stop if a person entered something incorrectly. Also, the part at the end is larger than need be and you don't need the 0 and 1 within the braces as they are added by defalt. Here's a solution(although it uses multiple while loops):

operators = ["+", "-", "*", "/"]
while True:
    # Gets operator, converts to int and breaks if it's a number
    try: operator_switch = int(input("Choose an Operator:\n1) Addition\n2) Subtraction\n3) Multiplication\n4) Division\nInput (1/2/3/4):"))
    except:
        print('Invalid Input: Choose A Valid Operation')
    else:
        # Checks the operator is within 1 and 4
        if operator_switch > 4 or operator_switch < 1:
            print('Invalid Input: Choose A Valid Operation')
            continue # goes straight back to the beginning without running what's after
        operator = operators[operator_switch - 1]
        break
while True:
    # Gets first and second number, converts numbers to float and breaks only if it's a number
    try: firstnum = float(input('First Number:'))
    except: 
        print('Invalid Input: Not a valid number')
        continue
    try: secondnum = float(input('Second Number:'))
    except: 
        print('Invalid Input: Not a valid number')
        continue
    else:
        break
# Shortens the end significantly. Don't read this if you don't want to
op_func = int.__add__ if operator == "+" else int.__sub__ if operator == "-" else int.__mul__ if operator == "*" else int.__div__
print(f"{firstnum} {operator} {secondnum} = {op_func(firstnum, secondnum)}")
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ When trying it after inputing the two numbers it loops back to asking the first number. I think its not exiting that second while loop. \$\endgroup\$ – Jack W Sep 29 at 19:47
  • \$\begingroup\$ The first paragragh is a pretty good answer, there really isn't any need to provide an alternate solution. \$\endgroup\$ – pacmaninbw Sep 30 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.