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

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.

Related

Python: Simple calculator only return Addition function, won't return values for other specified functions [duplicate]

This question already has answers here:
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
Closed 3 days ago.
I'm very fresh to Python and am coding a simple text-based calculator that takes choice input and performs a simple arithmetic process depending on the input. My issue arises in this; regardless of whether I input 'Multiply' or 'Divide', the program is always returning to value of the addition function. Any ideas?
def main():
whichCalc()
print(finalNum)
def whichCalc():
choice = input("Please enter one of the following; "
"Add, Multiply or Divide: ")
if choice == 'Add' or 'add' or 'ADD':
addNum()
elif choice == 'Multiply' or 'multiply' or 'MULTIPLY':
multNum()
elif choice == 'Divide' or 'divide' or 'DIVIDE':
divNum()
else:
print('What?')
def addNum():
global finalNum
finalNum = (firstNum + secondNum)
return finalNum
def multNum():
global finalNum
finalNum = (firstNum * secondNum)
return finalNum
def divNum():
global finalNum
finalNum = (firstNum / secondNum)
return finalNum
firstNum = int(input('Enter the first number: '))
secondNum = int(input('Enter the second number: '))
main()
I've tried removing the 'or' syntax as well as shifting things around, I'm not sure as to why it's diehard on only using the 'addNum' function even when I'm not calling it.
When using non-booleans in an if statement, python can act a bit strange if you're not used to it. Let's illustrate this with a code example.
For strings, any empty string ("") will evaluate to False, and any non-empty string will evaluate to True.
def is_string_empty(our_string):
if our_string:
print(f"No, {our_string} is not empty")
else:
print(f"Yes, {our_string} is empty")
is_string_empty("")
is_string_empty("some string")
Now that we understand this, let's look at the syntax error your code example is making. Specifically, let's focus on this line:
if choice == 'Add' or 'add' or 'ADD':
You have three boolean expressions here. First, choice == 'Add', which will work as you intended; it will evaluate to True if choice is 'Add'. However, your mistake comes from the next two boolean expression: 'add', when evaluated as a boolean, is True, since it's not empty! Same for evaluation 'ADD'; it will always be True. Since those are being or'd with choice == 'Add', this if statement will always evaluate to True, so it will execute addNum() no matter the input!
This statement should be rewritten as:
if choice == 'Add' or choice == 'add' or choice == 'ADD':
One last tip: instead of having these ors, you can use the lower() method of strings:
if choice.lower() == 'add':
This will work for add, adD, aDd, Add, aDd, AdD, etc.
i think this will help
def main():
whichCalc()
def whichCalc():
choice = input("Please enter one of the following; "
"Add, Multiply or Divide: ")
if choice == 'Add' or choice =='add' or choice =='ADD':
print(addNum())
elif choice == 'Multiply' or choice =='multiply' or choice =='MULTIPLY':
print(multNum())
elif choice == 'Divide' or choice =='divide' or choice =='DIVIDE':
print(divNum())
else:
print('What?')
def addNum():
finalNum = (firstNum + secondNum)
return finalNum
def multNum():
finalNum = (firstNum * secondNum)
return finalNum
def divNum():
finalNum = (firstNum / secondNum)
return finalNum
firstNum = int(input('Enter the first number: '))
secondNum = int(input('Enter the second number: '))
main()
you do not need global keyword because you are not going to change the value of the global variable
the functions return values then you can put the function inside print() directly
your problem was in this section :
if choice == 'Add' or 'add' or 'ADD':
print(addNum())
elif choice == 'Multiply' or 'multiply' or 'MULTIPLY':
print(multNum())
elif choice == 'Divide' or 'divide' or 'DIVIDE':
print(divNum())
else:
print('What?')
because you can not say
if thing == value1 or value2 or value3
Non empty strings are evaluated as True while empty strings are Falsy. The or operator calls the __or__ method which returns the first true item. Calling or on a bunch of strings will returns the first non-empty string. The and operator returns the first falsy item in the chain.
Normally all-caps are used to indicate constants in python. Also try not to use global variables unless necessary. For specifying behavior, being the mathematical operator, pass in everything the function needs to operate. Then the function is only specifying behavior and is getting its arguments from the call arguments and not breaking scopes.
Also using a dictionary is good for mapping keys to values. In Python, functions are objects, so they can be passed around. This is why I stored the three supported functions in the dictionary. The operator is then pulled out and the called on the two numbers.
The dict.setdefault(key, value_if_key_is_missing) method is a one time use method for safely looking up a key in a dictionary. If the key is not found, the default is returned. This does not change the dictionary in any way.
A lambda function is a more semi-advanced function that is just a one-liner function. Normally you don't want to store lambda functions because that can introduce unexpected errors, but ours are okay.
OPS = {'ADD': lambda x, y: x + y,
'MULTIPLY': lambda x, y: x * y,
'DIVIDE': lambda x, y: x / y}
def which_calc(x, y, operator):
default_response = lambda *_: print('What?')
operator = OPS.setdefault(operator.upper(), default_rsponse)
return operator(x, y)
def main():
x = int(input('Enter the first number: '))
print(x)
y = int(input('Enter the second number: '))
print(y)
choice = input("Please enter one of the following; "
"Add, Multiply or Divide: ")
print(which_calc(x, y, choice))
main()

If statement to sense if variable contains certain strings wont work [duplicate]

This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 3 years ago.
So I am trying to make a simple calculator. I want it so when I ask for input on what operation they want for the two numbers they type to be add, subtract, multiply, or divide. If the input for the operation selection isn't anything other than add, subtract, multiply, or divide then I want it to print("Incorrect Operation"). I had this working before but I had to rewrite the whole thing cause I accidentally deleted the file.
Anyways, I try to achieve this by using and if statement using the == sign to check if the input string is any of the following strings. That part works. The part that seems to be failing is the else statement which seems to not be picking up that anything other than the specified strings should do:
print("Incorrect Operation")
quit()
The output that I get from the script below does not have any errors but does not do what I just specified (to print something and quit the program). If anyone could help me it would be greatly appreciated!
if function_type == 'add' or 'subtract' or 'multiply' or 'divide':
print("Correct Operation!")
else:
print("Incorrect Operation")
quit()
num_1 = float(input("First Number: "))
num_2 = float(input("Second Number: "))
if function_type == "add":
print(num_1 + num_2)
if function_type == "subtract":
print(num_1 - num_2)
if function_type == "multiply":
print(num_1 * num_2)
if function_type == "divide":
print(num_1 / num_2)
Select the type of operation (add, subtract, multiply, divide): nworfr
Correct Operation!
I'm afraid that is not how boolean expressions work. They seem logical cause it sounds like how you would translate into english but unless you explicitly specify the conditions, the values will be evaluated on their own. You would need to change your condition to:
if function_type == 'add' or function_type == 'subtract' or function_type == 'multiply' or function_type == 'divide':
print("Correct Operation!")
else:
print("Incorrect Operation")
quit()
When you mention the string alone, it will evaluate 'subtract' and not funtion_type == 'subtract'. Since the string is not None, it will always be evaluated to True.

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

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

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)

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