How to restart a programm if input is invalid python - python

first project beginner here! I just finished my first project, a somewhat working calculator i know it is not that great but as i said beginner. I would like to limit the options for number = input meaning if you write anything else than add,substract,divide or multiply you receive an error like " please try again" and afterwards the programm is restarted
Help very much appreciated Thank you.
list = ("add", "substract", "divide" , "multiply" )
number = input("do you want to add substract divide or multiply? ")
if number in list:
print("ok")
else:
print("try again")
number_one = float(input("enter your first number "))
number_two = float(input("enter your second number "))
if number == "add":
solution_one = number_one + number_two
print(solution_one)
if number == "substract":
solution_two = number_one - number_two
print(solution_two)
if number == "divide":
solution_three = number_one / number_two
print(solution_three)
if number == "multiply":
solution_four = number_one * number_two
print(solution_four)
i could only find solutions regarding while loops but i did not know how to use them in this case as these weren't strings but integers.

The fact that you're prompting for a string doesn't change the way the while loop works. Run your code in a loop and break when it's time for the loop to end.
while True:
number = input("do you want to add substract divide or multiply? ")
if number in ("add", "substract", "divide" , "multiply" ):
print("ok")
break
print("try again")
Note that it's considered bad practice to give a variable a name like list (or any other built-in name) since it can lead to very confusing bugs when you try to reference the built-in name later!

You could consider using the operator module.
Build a dictionary that maps the user's selected operation with the relevant function.
import operator
OMAP = {
'add': operator.add,
'subtract': operator.sub,
'divide': operator.truediv,
'multiply': operator.mul
}
while (op := input('Do you want to add, subtract, multiply, divide or end? ')) != 'end':
try:
if (func := OMAP.get(op)):
x = float(input('Enter your first number: '))
y = float(input('Enter your second number: '))
print(func(x, y))
else:
raise ValueError(f'"{op}" is not a valid choice')
except ValueError as e:
print(e)

Related

Is this an efficient calculator in Python?

Is this an efficient calculator in Python?
def calculator():
print("\nBasic Calculator.\n")
num_1 = input("Enter your first number: ")
operation = input("Enter your operation: ")
num_2 = input("Enter your second number: ")
if operation == ("+"):
sum = float(num_1) + float(num_2)
print ("The answer is:",(sum))
elif operation == ("-"):
sum = float(num_1) - float(num_2)
print ("The answer is:",(sum))
elif operation == ("*"):
sum = float(num_1) * float(num_2)
print ("The answer is:",(sum))
elif operation == ("/") and num_2 == ("0"):
print ("\nYou cannot divide by zero.")
elif operation == ("/"):
sum = float(num_1) / float(num_2)
print ("The answer is:",(sum))
else:
print("Invalid Operation.")
restart = input("\nDo you want to enter another equation? Yes or No?").lower()
if restart == ("yes"):
calculator()
else:
print ("\nEnding Program.")
quit()
calculator()
You can use eval()
a = 1
b = 2
operation = '/'
print(eval(f'{a} {operation} {b}'))
0.5
Handle shenanigans by users:
a = 1
b = 0
operation = '/'
try:
print(eval(f'{a} {operation} {b}'))
except Exception as exp:
print(exp)
Here is another basic example:
operations = {
'+': lambda x, y: x + y,
'-': lambda x, y: x - y,
'*': lambda x, y: x * y,
'/': lambda x, y: x / y,
}
try:
x, sign, y = input("Enter expression separated by whitespace(ex: 2 + 3): ").split()
if sign == '0':
break
else:
print(operations[sign](int(x), int(y)))
except (ValueError, KeyError, ZeroDivisionError):
print("Something went wrong, check your input")
It's decent, but reviews of working code belong on CodeReview.SE, not here.
Call the result variable result instead of sum, that obviously only is meaningful for addition.
As per AlexanderLekontsev's answer, you don't need a huge big if...else ladder that always computes result and prints the output. A dispatch dictionary to (binary or unary) lambda function is better. You could have all the functions be binary, and default arg2=None, that way you can handle unary functions.
You're assuming the user types in valid floats in response to num_1, num_2. But what if they press return? or type pi or e? or 'help' or :-D etc. You should catch the exception ValueError: could not convert string to floatand display the user's invalid input back to them, "expected a number"(/"operator").
You only need num_2 if operation is a binary not a unary operation, but future stuff like sqrt, log, log10, trigonometrics (sin, cos, tan), hyperbolics and their inverses (arc-fns) are all unary operations. Just something to keep in mind for the future. Don't hardwire your parser to one expected input sequence.
Inputting numbers could get more complicated in future. What if you wanted to support both hexadecimal 7e8 and float/general/exponential notation 7e8? You might need multiple try...except clauses. You might add a HEX mode in future. But then you'll need to generalize from num1 to say arg1, and if arg1 == HEX then enable(/toggle) hex mode, and recurse/loop.
Suggest printing print("Invalid Operation: must be +,-,*,/,..."), this actually tells the user which operations are legal. So: % isn't, neither is ^, neither is log, cos, sqrt etc.
So if you implement the above, you can support things like e^x
Supporting parentheses would require recursion.
Try this:
def calculate(num1, num2, operator):
operator = operator.strip()
if operator.strip() in ['+', '-', '*', '/']:
if operator == '/' and eval(num2) == 0:
return None
try:
result = eval(f'float({num1.strip()}) {operator} float({num2.strip()})')
except:
return ""
return result
num1 = '3'
num2 = '5'
operator = '+'
result = calculate(num1, num2, operator)
if result == '':
print('Wrong expression !')
elif result == None:
print('Dive bye zero !')
else:
print(f'The answe is {result} !')
Your code is alright but we can improvise by using eval()
print(" Basic Calculator ")
i = ""
while i != 'exit':
i = input(" Enter the expression to evaluate or type 'exit' to exit : ")
print(eval(i))
Here is a very clean and short calculator script:
num1 = float(input("Enter a number: "))
op = (input("Enter an operation: "))
num2 = float(input("Enter another number: "))
if op == "*":
print(num1 * num2)
elif op == "/":
print(num1 / num2)
elif op == "+":
print(num1 + num2)
elif op == "-":
print(num1 - num2)
elif op == "^":
print(num1 ** num2)
else:
print("error, you did not enter a supported operation")
Also if you were wondering ** means ^ or to the power of.
Try this:
this calculator will take several inputs, and you can choose to clear the values or to delete it before computing the result.
values_collector = [] #empty list for all values
multi = 1
total = 0
index = 0
print('''For addition press the +,
For Subtraction press the -
For division press the /
For Multiplication press the *''')
entries = int(input('Enter the number of the values you want to compute: '))
signs = input('Enter the sign: ')
while index < entries:
my_input = int(input('Enter your values: '))
values_collector.append(my_input)
index +=1
to_remove = input('Do you want to remove any values, enter Y for yes and N for no ').upper()
if to_remove == 'Y':
values_re=[]
x = 0
no_to_remove = int(input('How many variables do you want to remove: '))
while x < no_to_remove:
my_removed = int(input('Enter your values: '))
values_re.append(my_removed)
x +=1
for y in values_re:
values_collector.remove(y)
my_clear = input("Do you want to clear all the values press Y for yes and N for No ").upper()
if my_clear == 'Y':
values_collector.clear()
print('There is no values to compute because its cleared')
elif my_clear == 'N':
if signs == '+':
for x in range(len(values_collector)):
total +=values_collector[x]
elif signs == '-':
for x in range(len(values_collector)):
total -=values_collector[x]
elif signs == '*':
for x in range(len(values_collector)):
multi *=values_collector[x]
total = multi
elif signs == '/':
for x in range(len(values_collector)):
multi /=values_collector[x]
total = multi
print('The computation of all the values {} is {}'.format(values_collector, total))
enter code here

ending a program early, not in a loop?

I'm attempting to make a short program that will return the factorial of a number, which works fine. The only problem I am having is getting the program to end if the user inputs a non-integer value.
num = input("input your number to be factorialised here!: ")
try:
num1 = int(num)
except ValueError:
print("That's not a number!")
if num1 < 0:
print("You can't factorialise a negative number")
elif num1 == 0:
print("the factorial of 0 is 1")
else:
for i in range(1,num1+1):
ans = ans * i
print("the factorial of", num, "is", ans)
Solution
There are better ways of doing this but given your code structure you can use else. See the docs.
num = input("input your number to be factorialised here!: ")
try:
num1 = int(num)
except ValueError:
print("That's not a number!")
else:
if num1 < 0:
print("You can't factorialise a negative number")
elif num1 == 0:
print("the factorial of 0 is 1")
else:
ans = 1
for i in range(1,num1+1):
ans = ans * i
print("the factorial of", num, "is", ans)
The else clause only executes if no exceptions are thrown.
Suggestions
So as not to give away answers to your homework, here are a couple suggestions that you should take a look at to clean up your code:
Can you use range more efficiently? Hint: you can iterate over decreasing numbers by setting the step to a negative integer.
Can you find a way to get rid of the check num1 == 0?
The OP is actually asking how to terminate the current script execution prematurely. The straightforward way to implement your idea is to use sys.exit() like
try:
num1 = int(num)
except ValueError:
sys.exit()
For more details, see this thread.

How to run the math from an input in python

I am creating a game in python where I need to run basic math operations. These operations would be provided by a user as input. How do I do this?
So far, I have independent variables for each number and each operator, however, when I run the code, it does not recognize the operator ('+','-','*','/') as an operator, but rather as strings. Therefore, when running the programming it would run as 1'+'1.
print("Now you can solve it. ")
vinput1=int(input("Please input the first number"))
print("First number is recorded as", vinput1)
vop1=input("Please input your first operator")
print("Your operator is recorded as", vop1)
vinput2=int(input("Please input the second number"))
print("Second number is recorded as", vinput2)
vsofar = (vinput1, vop1, vinput2)
print(vsofar)
Computer's output:
(1, '+', 1)
While eval operates in a very general context and so much scope for introducing security issues ast.literal_eval is intended to evaluate string literals only and so has a far narrower and hence safer scope.
from ast import literal_eval
print("Now you can solve it. ")
vinput1=int(input("Please input the first number"))
print("First number is recorded as", vinput1)
vop1=input("Please input your first operator")
print("Your operator is recorded as", vop1)
vinput2=int(input("Please input the second number"))
print("Second number is recorded as", vinput2)
vsofar = (vinput1, vop1, vinput2)
print(literal_eval(''.join(map(str, vsofar))))
Otherwise create a mapping from operators to functions to lookup the function to call for each operator.
import operator
import sys
ops = {'+': operator.add,
'-': operator.sub}
v1 = int(input('enter first num'))
op1 = input('input operator')
if not op1 in ops:
print('unsupported operation')
sys.exit(1)
v2 = int(input('enter second num'))
print(ops[op1](v1, v2))
The great thing about this is that you don't have to screw around in the program logic to add new (binary) operations. You just add them to the dict, with far less opportunity to make a typo in a long if/elif chain.
The safest and simplest method is to use an if-statement to check which symbol was input. A sample if-statement would be:
print("Now you can solve it. ")
vinput1=int(input("Please input the first number"))
print("First number is recorded as", vinput1)
vop1=input("Please input your first operator")
print("Your operator is recorded as", vop1)
vinput2=int(input("Please input the second number"))
print("Second number is recorded as", vinput2)
if (vop1 == "-"):
vsofar = vinput1 - vinput2
print(vsofar)
elif (vop1 == "+"):
vsofar = vinput1 + vinput2
print(vsofar)
elif (vop1 == "/"):
vsofar = vinput1 / vinput2
print(vsofar)
elif (vop1 == "*"):
vsofar = vinput1 * vinput2
print(vsofar)
else
print("Invalid operator entered.")
Just to quickly explain, these if-statements check whether the operator entered, which is stored in vop1, matches the -, +, *, or / operator. If it matches any of these, then its respective operation is carried out and stored in the variable vsofar,cwhich is printed in the line after that operation. If none of the operations work, then an invalid statement is printed.
This is the most bland, simple, and somewhat long way of doing it. However, the eval() function is not safe to use. A shorter yet more complex than my way is the answer of Paul Rooney.
Hope this helps!
You Can evaluate!
>>> input1=1
>>> input2=3
>>> vop1="+"
>>> print eval(str(input1)+vop1+str(input2))
4
Have a look at this
Hope this helps!
If you don't want to use eval() you might try a series of conditionals to test the operator and then perform the correct calculation based on that.
if vop1 == "+":
return vinput1 + vinput2
if vop1 == "-":
return vinput1 - vinput2
num1= int(input("first number: "))
num2= int(input("2md number: "))
sign= input("sign operator: ")
if sign == '+':
print("Answer is", num1+num2)
elif sign == '-':
print("Answer is", num1-num2)
elif sign == '*':`enter code here
print("Answer is", num1*num2)
elif sign == '/':
print("Answer is", num1/num2)
else:
print("am not built to use this sign yet")

If statements printing after a variable is entered

I'm new to programming/coding and I'm using Python in my course. I have been asked to create a calculator that can add, subtract, divide and multiply. I'm trying to get the program to receive the numbers through input, then ask for what to do with it (eg. plus or minus) through a number entered and then give a result. I have the input stages of the code working but when I get to the last part I cant get it to work. This is the code
FirstNumber = "blank1"
SecondNumber = "blank2"
Device = "blank3"
FirstNumber = input("First number?")
SecondNumber = input("Second number?")
Device = input("Select a Number. Options are; 1.Plus, 2.Minus, 3.Times, 4.Divide.")
if "Device" == 1:
print("FirstNumber"+"SecondNumber")
When it gets the the end it does nothing, help please.
The condition "Device" == 1 will always be False because no string is equal to an integer. You probably want to change it to Device == 1, but this will (likely) still fail because on python3.x, input returns a string. You probably want something like:
Device = int(input("Select a Number. Options are; 1.Plus, 2.Minus, 3.Times, 4.Divide."))
if Device == 1:
print(FirstNumber + SecondNumber)
Of course, for the same reason, you'll probably also want to convert FirstNumber and SecondNumber into some numeric type ...
ops = {
"+": lambda a,b: a+b,
"-": lambda a,b: a-b,
"*": lambda a,b: a*b,
"/": lambda a,b: a/b
}
a = int(input("Please enter the first number: "))
op = input("Please enter an operator: ")
b = int(input("Please enter the second number: "))
print("{} {} {} == {}".format(a, op, b, ops[op](a,b)))

Python Calculator Using 2 vars, Operators, and Q (Quit)

I am trying to create a simple python calculator for an assignment. The basic idea of it is simple and documented all over online, but I am trying to create one where the user actually inputs the operators. So instead of printing 1: addition, 2: subtraction, etc, the user would select + for addition, - for subtraction, etc. I am also trying to make Q or q quit the program.
Any ideas for how to allow the user to type operators to represent the operation?
Note: I know I still need to define my remainder operation.
import math
loop = 1
choice = 0
while loop == 1:
print("your options are:")
print("+ Addition")
print("- Subtraction")
print("* Multiplication")
print("/ Division")
print("% Remainder")
print("Q Quit")
print("***************************")
choice = str(input("Choose your option: "))
if choice == +:
ad1 = float(input("Add this: "))
ad2 = float(input("to this: "))
print(ad1, "+", ad2, "=", ad1 + ad2)
elif choice == -:
su2 = float(input("Subtract this: "))
su1 = float(input("from this: "))
print(su1, "-", su2, "=", su1 - su2)
elif choice == *:
mu1 = float(input("Multiply this: "))
mu2 = float(input("with this: "))
print(mu1, "*", mu2, "=", mu1 * mu2)
elif choice == /:
di1 = float(input("Divide this: "))
di2 = float(input("by this: "))
print(di1, "/", di2, "=", di1 / di2)
elif choice == Q:
loop = 0
print("Thank-you for using calculator")
First off, you don't need to assign choice to zero
Second, you have your code right, but you need to put quotes around the operators in your if statements like this
if choice == '+':
to show that you are checking for a string
make your loop like this:
while 1: #or while True:
#do stuff
elif choice == 'Q': #qoutes around Q
break #use the `break` keyword to end the while loop
then, you don't need to assign loop at the top of your program
You should try replacing if choice == + by if choice == "+".
What you're getting from the input is actually a string, which means it can contain any character, even one that represents an operator.

Categories