Parsing a addition/subtraction/multiplication/division sign from a string - python

I went through a lesson of creating a simple calculator using Python, and I'm trying to simplify it.
The issue is as follows:
I know that it is possible to parse a string (number) into a float using "float()", but I'm trying to parse a addition/subtraction/multiplication/division sign from a string into a float or integer or any other format that would perform the action. Here's a sample of what I'm trying to do:
while True:
user_input = input("""
quit - exit program
add - addition
sub - subtraction
mul - multiplication
div - division
Please choose function:""")
actions = ("+-*/")
user_input_1 = float(input("first number:"))
user_input_2 = float(input("second number:"))
operation = user_input_1 float(action) user_input_2
if user_input == "add":
action = actions[0]
answer = operation
print (answer)
If the user_input is "add"
user_input_1 is "5"
user_input_2 is "7"
then the print(answer) should result in 12
This is just the first part of the code, and I'm getting a syntax error. The issue is most likely the inability to parse the addition sign using "float()". Is there another way of parsing the signs?

Even though you should be posting the full traceback, the SyntaxError comes from this line:
operation = user_input_1 float(action) user_input_2
It is neither a valid Python expression nor a statement.
A solution that doesn't involve eval:
You can use the operator module and a dictionary from "sign" to the operator itself, as seen in this very basic (and error prone) example:
import operator
operations_dict = {'+': operator.add,
'-': operator.sub} # extend to other operators you see fit
a = float(input('first num'))
b = float(input('second_num'))
sign = input('operator')
print(operations_dict[sign](a, b))
>> first num
1
>> second num
2
>> operator
+
>> 3.0

You can use eval in the form eval('1 + 2'), which will give you desired result.
You can read more on eval here https://docs.python.org/2/library/functions.html#eval
but please keep in mind the following statement
The user can expose hidden values in the program, or call a dangerous
function (dangerous_function("/etc/passwd")). Of course in most cases
(desktop programs) the user can't do any more than they could do by
writing their own python script, but in some applications (web apps,
kiosk computers), this could be a risk.
which is from http://lybniz2.sourceforge.net/safeeval.html

In your case this should work :
def operation(action):
return user_input_1 + action + user_input_2
if user_input == "add":
action = actions[0]
answer = operation(action)
print (eval(answer))
but that's not the best way to do the operations. You can simply add or divide like this or you can construct a dictionary for the operations:
def operation(action):
if(action == "add"):
return user_input_1 + user_input_2
elif action == "sub":
return user_input_1 - user_input_2
elif action == "div":
return user_input_1 / user_input_2
# and so on....
answer = operation(user_input)
print (answer)

I do not recommend using eval() however; setting some rules won't hurt using eval(). This is really basic calculator and its easy to understand.
allowed_characters = "0123456789+-/*= "
print("""
Basic calculator application.
Operators:
+ addition
- subtraction
* multiplication
/ division
Type the desired operation and press ENTER.
(Example 23 and 46 to multiple
Type 23 * 46 then press ENTER.)
""")
while True:
data = input("Please enter your calculation: ")
if data == "q":
print("Exiting...")
break
for s in data:
if s not in allowed_characters:
print("Invalid character!")
quit()
calculate = eval(data)
print(calculate)

Related

Beginner Python question, issue using "or" and "if" together

I am using Python to create a very basic calculator. for whatever reason the numbers will only add - they will not do any of the other functions. Please help!
equation_type = input("What kind of math do you want to do? ")
equation_type = equation_type.lower()
first_number = float(input("What is the first number? "))
second_number = float(input("What is the 2nd number? "))
if equation_type == "add" or "addition":
result = first_number + second_number
elif equation_type == "subtract" or "subtraction":
result = (first_number - second_number)
elif equation_type == "multiply" or "multiplication":
result = first_number * second_number
elif equation_type == "divide" or "division":
result = first_number / second_number
else:
print("not a valid entry :/")
print(result)
equation_type == "add" or "addition" does not do what you think it does.
It's tempting to read Python code as if it were English. It is not! Python is still a programming language, and programming languages have strict rules.
The expression equation_type == "add" or "addition" is parsed as (equation_type == "add") or "addition". The first part, (equation_type == "add") might be true or false depending on the user's input. However, the second part "addition" is always true from the perspective of if.
Therefore Python always uses the first branch in your if/elif/else chain, and ignores the others, because the first branch is always "true" from its perspective!
The or operator has only one purpose: it combines expressions using logical disjunction. It does not repeatedly apply an equality check for multiple values! Refer to the official documentation for details on what operators like or and and can and cannot do.
You probably wanted to write if equation_type in ("add", "addition"):. The in operator checks whether a value is an element of some collection:
x = "apple"
if x in ("carrot", "celery"):
print("vegetable")
elif x in ("apple", "pear"):
print("fruit")
The in operator works on all kinds of collections: tuples (a, b, c), lists [a, b, c], and the keys (not values!) of dictionaries {a: 1, b: 2}.
The conditions should be like (one of many ways of doing it):
equation_type == "add" or equation_type == "addition":
When checking multiple conditions you need to repeat the equality. There are other ways but since you are in a beginner course you should try to make this one work.
Do the same with the other conditions and see if it works.

I'm creating a (very crude) calculator and would like to know what's wrong with this code

# Pick the numbers you'd like to use
number1 = (input('What is the first number?\n'))
number2 = (input('What is the second number?\n'))
# Choose what to do with those numbers
Choice = input('Would you like to add, subtract, multiply or divide?\n ')
# Where the calculating happens, if it doesn't go through the error message asking you to use numbers will happen
try :
# Converting the numbers from str into float, if this doesnt happen it means numbers were not used
num1 = float(number1)
num2 = float(number2)
if Choice is add :
answer = num1 + num2
elif Choice is subtract :
answer = num1 - num2
elif Choice is divide :
answer = num1/num2
elif Choice is multiply
answer = num1 * num2
print(answer)
# The error message if the numbers you gave werent in numeric form
except :
print('Please choose proper numbers in numeric form instead of letter/words')
This is the code, the issue I get is:
'File "main.py", line 13
elif Choice is subtract :
^
SyntaxError: invalid syntax'
Any help would be appreciated, thanks :). (If this code just wouldn't work at all, please lmk. Im currently going through a book on how to code and thought this would be fun to try since I just learned about booleans and variables)
I think you mean to do this:
if Choice == 'add':
answer = num1 + num2
elif Choice == 'subtract':
answer = num1 - num2
elif Choice == 'divide':
answer = num1/num2
elif Choice == 'multiply':
answer = num1 * num2
Be careful with indentation. If you have a single if / elseif / elseif / elseif / else chain, each condition should be at the same indent level, and each body should match its condition plus one indent (typically 4 spaces or 1 tab).
To compare a string captured from the user with input() to a literal string, you would do:
if Choice == 'add':
You need to specify the quotation marks around 'add', otherwise it would try to reference a variable called add, which isn't defined.
For == vs is when checking the string, see Why does comparing strings using either '==' or 'is' sometimes produce a different result?

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")

Parts of my code won't show in shell. (if/elif statement)

I'm new to Python. When I run this code, the last part where the results should be calculated is not shown on shell. Can someone tell me how should I fix this? The last part seems a little bit awkward, but I have no idea how to convert str into operations.
# Set variables
opList = ["plus", "minus", "times", "divided-by", "equals"]
# Instrution
print("Intructions: Please enter + as plus, - as minus, * as times and / as divided-by.")
# Read user's equation as a string
equation = input("\nPlease, enter your equation by following the syntax expressed above: ")
# Echo to the screen what the user has entered
print('The equation you entered is "%s".' %equation)
# Parse the equation into a list
theParts = equation.split() # default is whitespace
# print("Here is a list containing the operands and operator of the equation: ", theParts) # For debugging purposes
if len(theParts) == 0 :
print("\nHave you simply pressed the Enter key? Please, enter an equation next time! :)")
elif len(theParts) == 1 :
print("\nThis is not a equaltion so it cannot be calculated. Please, enter an equation next time! :)")
elif len(theParts) == 2 :
print("\nThis is not a equaltion so it cannot be calculated. Please, enter an equation next time! :)")
elif len(theParts) == 3 :
print("\nThe equation entered by the user is %s %s %s." %(theParts[0], theParts[1], theParts[2]))
if theParts[1] is str("plus"):
theAnswer == theParts[0] + theParts[2]
print('The anwser of the input equation is "%i".' %theAnswer)
elif theParts[1] is str("minus"):
theAnswer == theParts[0] - theParts[2]
print('The anwser of the input equation is "%i".' %theAnswer)
elif theParts[1] is str("times"):
theAnswer == theParts[0] * theParts[2]
print('The anwser of the input equation is "%i".' %theAnswer)
elif theParts [1] is str("divided-by"):
theAnswer == theParts[0] / theParts[2]
print('The anwser of the input equation is "%i".' %theAnswer)
print("\nBye!")
Assuming you're using Python 2.x, the main issue that's getting you hung up is that you're using input instead of raw_input. input will evaluate your equation and use the evaluation in your program, whereas raw_input will get exactly what the user types as a string. For example:
input
# what the user types
3 + 7
# what the program gets as an integer
10
raw_input
# what the user types
3 + 7
# what the program gets as a string
"3 + 7"
No matter what version of Python you're using, you'll have to fix the following:
Indentation
You'll need to indent the code for your case where theParts has three integers so it executes only then. Otherwise it will execute no matter what and give you an array out of bounds error or the you'll get an indentation formatting error.
Testing string equality
Rather than use is str("[string]") simply use ==. Don't try to over-complicate things.
Strings vs. Numbers
In order to do math, you'll have to convert your strings to numbers. You can do that using something like int("5") which is equal to 5 (integer).
Example Code
# case 3
elif len(theParts) == 3:
# do stuff
if "plus" == theParts[1]:
theAnswer = int(theParts[0]) + int(theParts[2])
Assuming you are using a modern Python, input is actually the correct function to use (there is no raw_input in 3.x, and input is always a string). But, as mentioned, there are other problems.
Here's a version with some corrections.
# Instruction
# I changed the instructions to make them more precise and get rid of the unneccesarily awkward operators
print("Instructions: Please enter a simple equation of the form 'integer [operator] integer', where [operator] is '+', '-', '*' or '/'.")
print("Instructions: Make sure to put spaces between each element.")
# Read user's equation as a string
equation = input("\nPlease, enter your equation by following the syntax expressed above: ")
# Echo to the screen what the user has entered
print('The equation you entered is "%s".' % equation)
# Parse the equation into a list
theParts = equation.split() # default is whitespace
# print("Here is a list containing the operands and operator of the equation: ", theParts) # For debugging purposes
if len(theParts) == 0 :
print("\nHave you simply pressed the Enter key? Please, enter an equation next time! :)")
# Since the two conditions warranted the same response, I just condensed them.
elif len(theParts) == 1 or len(theParts) == 2:
print("\nThis is not a equaltion so it cannot be calculated. Please, enter an equation next time! :)")
elif len(theParts) == 3 :
#print("\nThe equation entered by the user is %s %s %s." % (theParts[0], theParts[1], theParts[2]))
# I set the answer before the conditions to a float, so division can result in more meaningful answers
theAnswer = 0.0
# I cast the input strings to integers
p1 = int(theParts[0])
p2 = int(theParts[2])
if theParts[1] is str("+"):
theAnswer = p1 + p2
elif theParts[1] is str("-"):
theAnswer = p1 - p2
elif theParts[1] is str("*"):
theAnswer = p1 * p2
elif theParts [1] is str("/"):
theAnswer = p1 / p2
print('The anwser of the input equation is "{}".'.format(theAnswer))
print("\nBye!")
If you wanted division to have a more school book response, with a quotient and remainder, then instead of p1 / p2, you should use divmod(p1, p2) and parse out the two parts in your printed response.

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