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

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.

Related

How to restart a programm if input is invalid 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)

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

Passing less argument to function then defined in Python

If I have a function with multiple functions, let say, calculating an area or adding three numbers.
The user chose 1 for calculating area and 2 for adding numbers via input
def func_calculate(numberOne, numberTwo, numberThree, userChoise):
if userChoise == "1":
calculate Area
do something
if userChoise == "2":
calculate addition
do something
userChoise is the input from user
If user wants to calculate area there is only two arguments to the function instead of three, if user wants to make an addition.
So, finally to the question...
What is the most appropriate way to handle it?
When I call the function, when the user wants to calculate area, should I just set the numberThree variable to zero or something or is it a more "right" way do do it?
if userChoie == "1":
inputNumberOne = input(...
inputNumberTwo = input(...
inputNumberThree == 0
func_calculate(inputNumberOne, inputNumberTwo, inputNumberThree, userChoise)
If you wan't to perform multiple operations than it is good to have different functions for different operations
choice = input("what user want's to do")
if choice == 1:
add()
elif choice == 2:
multiply()
and than take arguments from user for that operations like
def add():
num1 = input("num1")
num2 = input("num2")
num3 = input("num3")
print(num1 + num2 + num3)
and similarly for other operations
But if you don't wan't to have multiple functions the you can do
def func(choice):
#choice is the integer which user opted
if choice == 1:
num1 = input("num1")
num2 = input("num2")
num3 = input("num3")
print(num1 + num2 + num3)
elif choice == 2:
.........
A good approach to this problem will be to have multiple functions, each with a specific role. You can make two separate functions calculate_area() and add_numbers(). Then, you can simply check the input and call these functions like this:
userChoice = input("Enter choice: ")
if userChoice == "1":
inputNumberOne = input("Enter number 1: ")
inputNumberTwo = input("Enter number 2: ")
calculate_area(inputNumberOne, inputNumberTwo)
elif userChoice == "2":
inputNumberOne = input("Enter number 1: ")
inputNumberTwo = input("Enter number 2: ")
inputNumberThree = input("Enter number 3: ")
add_numbers(inputNumberOne, inputNumberTwo, inputNumberThree)
If you really want to use only one function with a variable number of parameters, you could use *args as argument. For example:
def funct_calculate(*args):
if len(args) == 2:
Calculate Area
else:
Addition
funct_calculate(radius,pi)
funct_calculate(number1,number2,number3)

How to restart for while loops after user input

I've just started coding and I'm slowly understanding it. For my class we have to make a children's program to practice their math and ask them if they would like to try again if it is correct. I cannot understand how to get my while True loop to restart if they input Y. Any tips? Here is my code:
#Addition
A = int(input("What is %i + %i =" %(N1, N2)))
while add != N1 + N2:
add = int(input("Incorrect, what is %i + %i = " %(N1,N2)))
while add == N1 + N2:
repeat =(input("Correct! would you like to try again? Y/N "))
if repeat == 'n':
break
if repeat == 'y':
continue
if op == "-":
#Subrtraction
s = int(input("What is %i - %i =" %(N1, N2)))
while s != N1 - N2:
s = int(input("Incorrect, what is %i - %i = " %(N1,N2)))
while s == N1 - N2:
repeat =(input("Correct! would you like to try again? Y/N "))
if op == "*":
#Multiply
m = int(input("What is %i - %i =" %(N1, N2)))
while m != N1 * N2:
m = int(input("Incorrect, what is %i - %i = " %(N1,N2)))
while m == N1 * N2:
repeat =(input("Correct! would you like to try again? Y/N "))
This program structure does not make sense.
You can do:
while True:
num1 = int(input("num1 "))
num2 = int(input("num2 "))
op = '+'
calc = -1
if op == "+":
while calc != num1 + num2:
calc = int( input(f"Whats {num1} {op} {num2}?"))
elif op == "-":
pass # code the others
elif op == "*":
pass # code the others
elif op == "/":
pass # code the others - use float where needed instead of int
# comparing floats is difficult due to float math rounding imperfection
print("Correct!" , num1, op, num2,"=",calc)
again = input("Again? Y to do it again: ").lower()
if again != "y":
break # leaves the while True
for doing it you can define a function. Maybe it's little more complicated than what you do in class, but still it's pretty basic, so you can learn it easly :)
when using a function, remember to call it in the first time so it'll work.
here's an example:
def function_name():
while True:
'''your code'''
repeat =(input("Correct! would you like to try again? Y/N "))
if repeat == "y":
function_name() # wach time the user say "y" the code calls the function again.
break # the break will finish the while loop and will close the program.
function_name() # that's where I call the function the first time.
by the way, you don't actually have to use the while loop if you are using the function. but I assume it was your work in class so I'll leave it that way :)
I think it is better to enter a while loop first and then take input from the user or determining whether the answer is correct or not and other questions...
# coding: utf-8
# Start of the 1st Question
redo="y"
A1=-1 # can be any integer but not the correct answer
n1, n2 = 2, 3
while (A1 != n1 + n2) or redo.lower()=="y":
# ask the question
A1 = int(input("What is the sum of %i and %i : " % (n1, n2)))
# if answer is correct
if A1 == n1 + n2:
redo = input("Correct ! Would you like to try again? (Y/[N]) : ")
if redo.lower() == "y":
continue
else:
break
else:
print("Your Answer : %d is Incorrect!" % A1)

Is there any way to store functions in variables and create lists of variable-housed functions?

Am new to Python - have done some scripting in PHP, javascript, but am not a programmer (though am a tech writer with experience documenting APIs etc, so pretty extensive 'passive' programming know how).:
Was following steps here: https://en.wikibooks.org/wiki/A_Beginner's_Python_Tutorial/Functions. Specifically see the link re: simple calculator program
Wanted to figure out if I could make the program less redundant by storing all components for different calculations in list form, then have a very simple, generic means of processing any calculation request, by using the user's menu choice as an index into the list. I'm assuming it's good form to structure things in this way, but don't know! The original tutorial is obviously much more readable, but would mean the same error checking would need to be done repeatedly for each little "if" block...
In any case though, I couldn't figure out how to store the actual calculations as elements within a list. Is that possible? Here's as far as I got... where I managed to encapsulate, and call on, some of the specifics within lists, but had to still do a series of "if" statements for each individual calculation.
(Sorry if these questions are basic.. I did a bunch of searching without finding definitive documentation re: here's everything you can and Cannot capture in list form) So - my variation of the linked-to code:
#simple calculator program
# Prompts for possible calculations
add = ["Add this: ", "to this: ", "+"]
subtract = ["Subtract this: ", "from this: ", "-"]
multiply = ["Multiply this: ", "by this: ", "*"]
divide = ["Divide this: ", "by this: ", "/"]
# List of possible calculations
calcPrompts = [add, subtract, multiply, divide]
def promptEntries(Arg):
try:
op1 = int(input(Arg[0]))
op2 = int(input(Arg[1]))
operator = (Arg[2])
return op1, op2, operator
except:
print("Invalid entry. Please try again.")
choice = 0
#This variable tells the loop whether it should loop or not.
# 1 means loop. Anything else means don't loop.
loop = 1
while loop == 1:
#Display the available options
print ("\n\nCalculator options are:")
print (" ")
print ("1) Addition")
print ("2) Subtraction")
print ("3) Multiplication")
print ("4) Division")
print ("5) Quit calculator.py")
print (" ")
try:
choice = int(input("Choose your option: "))
choice = choice - 1
op1, op2, operator = promptEntries(calcPrompts[choice])
print(op1, operator, op2, "=", end=" ")
if choice == 0:
print(op1 + op2)
elif choice == 1:
print(op1 - op2)
elif choice == 2:
print(op1 * op2)
elif choice == 3:
if op2 != 0:
print(op1 / op2)
else:
print("Division by zero is invalid, please try again.")
elif choice == 4:
loop = 0
print ("Thank you for using calculator.py")
except:
print("invalid entry, please try again.")
In your case, you can use the operators as functions, provided by the operator standard library module.
As you can see, you can assign such functions to a variable, e.g. inserting all of them in a list
import operator as op
f = [op.add,
op.sub,
op.mul,
op.div,
op.pow,
op.mod]
then the loop can become
while True:
#Display the available options
print ("\n\nCalculator options are:")
for i, fun in enumerate(f):
print("{}) {}".format(i+1, fun.__name__))
print ("{}) Quit calculator.py".format(len(f)))
choice = int(input("Choose your option: ")) - 1
if choice == len(f):
print("Thank you for using calculator.py")
break
op1 = int(input("enter operand1: "))
op2 = int(input("enter operand2: "))
try:
result = f[choice](op1, op2)
except IndexError:
print("invalid entry, please try again.")
except ZeroDivisionError:
print("Division by zero is invalid, please try again.")
print('{} {} {} = {}'.format(op1, f[choice].__name__, op2, result))
Note: the example works for dyadic functions only. Further work is needed in case you want to offer a mix of functions with a different number of arguments.
Yes, in python functions are first class objects and you can use them any way that you would use any other object. For example you can have two variables reference the same object:
def myFunction():
pass
newVariable = myFunction
print(newVariable is myFunction)
or reference functions from a list or dictionary:
myList = [myFunction, 1, 2, 3]
print(myList[0] is myFunction)
myDict = {0:myFunction, 1:1}
print(myDict[0] is myFunction)
The above is true for both python's built in functions, functions in the standard library and functions you write. For example:
from operator import add
def countZeros(a):
return sum(item == 0 for item in a)
listOfFunctions = [sum, add, countZeros]

Categories