OR behaviour in python: - python

I have written the following piece of code, all i want to do is print a yes for if the number passed is a string representation of 1, 0 or 2 and for everything else a false:
number=raw_input()
if number is "1" or "0" or "2":
print "Yes"
else:
print "no"
I know how to make the intended logic work, but i just want need to know why it prints yes for any number i pass to raw_input. I'd like the answer to be as detailed as possible, because i cant understand why it would fail, it seems pythonic enough to me

The problem is that your code, to Python, reads like this:
if (number is "1") or "0" or "2":
And as any non-empty string evaluates to True, it's always True.
To do what you want to do, a nice syntax is:
if number in {"1", "0", "2"}:
Note my use of a set here - while it doesn't matter too much in this case (with only three values) checking against a set is faster than a list, as a membership test for a set is O(1) instead of O(n).
This is simply a nicer and easier of writing this:
if number == "1" or number == "0" or number == "2":
Which is what you wanted.
Note when making a comparison for value you should always use == not is - is is an identity check (the two values are the same object). Generally you should use is for stuff like is True or is None.
If you wanted to handle this as a number, you could do something like this:
try:
value = int(number)
except ValueError:
value = None
if value is not None and 0 <= value <= 2:
...
Which could be more useful in situations where you want to compare to a large range of numbers. Note my use of Python's useful comparison chaining (0 <= value <= 2 rather than 0 <= value and value <= 2).

The correct syntax is as follows:
if number == "1" or number == "0" or number == "2":
print "Yes"
Or the more Pythonic:
if number in ["1", "2", "3"]:
print "Yes"
Or you can cast to int and try:
if int(number) in range(1,4):
print "Yes"
The reason your code evaluates to True is all the time is because it is evaluating the truth of the "0" and "2", which as statements are true in Python.

Because every expression between an or is evaluated as a boolean expression.
if True evaluates to True, if 1: evaluates to True, if "0": evaluates to True.
So what you wrote is more or less the equivalent to:
if number is "1":
print "Yes"
elif "0":
print "Yes"
elif "2":
print "Yes"
else:
print "no"
You should have written if number is "1" or number is "0" or number "2": or, more pythonic: if number in ("1", "0", "2"):

Related

Python - Loop Not Starting At The Right Line; Else doesn't work for this, I have tried it

I am trying to make a calculator and trying to have it loop. I made a new file to test it, when I run it instead of starting at while numvars =="1" it is starting at e = int(input("What exponent do you want"). This is even happening if you say no for the exponent. What exactly is the problem that is occurring?
from math import sqrt
numvars = input("how many numbers do you want? Please only pick a number 1-3. Only type out the numberical character")
switch = True
for x in numvars:
while numvars == "1":
if switch == True:
a = int(input("What number would you like? Type ONLY the numberical character and not the word"))
exponents = input("Want to use exponents? MUST BE written as 'yes' or 'no'")
if exponents == "yes" or "Yes" or "YES" or "Y":
root = input("Would you like to do a square root? yes or no")
if root == "yes" or "Yes" or "YES" or "Y":
e = int(input("What exponent do you want?"))
b = a ** e
c = sqrt(b)
print(a, "was put to the power of", e, "giving the result", b)
print(b, "was then square rooted giving", c)
if root == "no" or "No" or "NO":
e = int(input("What exponent do you want?"))
b = a ** e
print(a, "was put to the power of", e)
print("Giving the final answer of", b)
root = input("Would you like to do a square root? yes or no")
if exponents == "no" or "No" or "NO" or "N":
root = input("Would you like to do a square root? yes or no")
if root == "yes" or "Yes" or "YES" or "N":
b = sqrt(a)
print(a, "was square rooted giving the answer of", b)
This issue is also happening if I have it as if numvars == "1". else also hasn't been working for me (using VisualStudio Code). Where I am wanting it to go back to is numvars = input("how many numbers do you want? Please only pick a number 1-3. Only type out the numberical character"); only reason that for x in numvars: being after the intended restart is just so I don't get an error of numvars not being properly defined (unless I have loops misunderstood, which is possible).
numvars is a string.
I am quite sure you intended to have it as an int.
numvars=int(input(...))
And then
while numvars==1
instead of numvars=="1"
I see that you know how to convert a string to a int, since you did it several time in your code. So that is why I am only "quite sure" this one should be an int too.
Because if it is a string, then
for x in numvars
iterates x among characters of numvars. For example if user types 132 for numvars, then x will be '1' then '3' then '2'. Again, quite sure that is not a wanted behavior.
Also, I fail to see why you have a while numvars==1 (or "1" that is not the point). Since you never change numvars from the start, either it is not 1, and your program will do nothing, either it is 1, and your program will loop forever. Either cases, probably not what you want.
Last remark:
if root=="no" or "No" or "NO":
certainly does not what you want. If root is "no", well, then this is true and does what you want. But in any other cases, root=="no" will evaluate as False, so the second term of the "or" operator is checked. That second term is the string "No", which is considered True.
A or B is A if A is not a False value (None, False, 0, [], ...), or else it is B. So root=="no" or "No" aka (root=="no") or ("No") is True if root=="no" is, or else it is "No".
It doesn't mean (root=="no") or (root=="No")

For my if-else statement, the else should display, not the if. I dont know why

when I enter 3, it should display, "you are a curious person", but instead it displays "you are an optimistic person". Why is this
eyeList = ["blue", "brown","green","hazel","grey","none"]
print(eyeList)
eyecolor = int(input("Pick your eye color: "))
if eyecolor == 1 or 2:
print("you are a optimistic person")
else:
print("you are a curious person")
The or operator in python is to be used as the logical or between two expressions (i.e. expr1 or expr2) which will be true when either one, or both of the expressions are true.
In your case, you are using eyecolor == 1 as expr1 and 2 as expr2. Using this method, the condition will always evaluate as true, because 2 will always evaluate as true.
I think what you are looking for is
if (eyecolor == 1) or (eyecolor == 2):
You should be using
if eyecolor == 1 or eyecolor == 2 or eyecolor == (1 or 2). Since you are using an if statement without parentheses, Python is interpreting the two if statements separately. eyecolor == 1 is false but 2 which is an int always evaluates to True.

Not being able to make an integer greater than another one

I'm making a program that gives you different basic operations to solve.
If you choose subtraction, it also gives you a choice if negative numbers are allowed or not. If the user says "No", it's supposed to change the variable that determines the minuend to a different number and check if it's greater than the subtrahend, and if it isn't, it tries again.
I've tried using a while loop that keeps regenerating the minuend until it's greater than the subtrahend, I've tried placing after FAT1 (minuend) = random.randint(1,50) > FAT2 (subtrahend) or FAT1 = random.randint(1,50 > FAT2).
I've also tried placing it in a function, or making a boolean used in the while loop instead of FAT1 < FAT2, but it keeps not working.
Variables I made throughout (all global):
FAT1 = first number (int)
FAT2 = second number (int)
OPER = the operation the user chooses (string)
NEG = if the user chooses yes or no to negative numbers (string)
Problematic part of the code:
#No negative numbers
elif NEG == "NO" or "No" or "no" or "nO" :
while True :
FAT1 = random.randint(1,50)
FAT2 = random.randint(1,50)
#Here it takes what the user typed and converts it in an int
TYP = input()
NUM = int(TYP)
while FAT1 < FAT2 :
FAT1 = random.randint(1,50)
RES = FAT1 - FAT2
print("What's",FAT1," - ",FAT2)
if NUM == RES :
print("Correct!")
elif NUM != RES :
print("Wrong! Try again!")
EDIT: As I said in my comment:
I get the input before the problem gets made because the user may choose a different operation. This question could be clearer with the whole code, but i didn't feel like putting it all there because it felt redundant Here's the code: pastebin.com/ZfqhY2md
EDIT2: I tried making this dictionary at the beginning (all in one line):
dict = {'Addition': 'Addition', 'Subtraction': 'Subtraction', 'No': 'No',
'Yes': 'Yes'}
And at the beginning of every if statement i tried this:
if NEG == dict.get('Yes') :
And it works for every suite except the one with No to negative numbers...
New full code here:
https://pastebin.com/600TpkZe
I think the problem may be in your elif condition.
Checking: NEG == "NO" or "No" or "no" or "nO" is going to return True if, and only if, NEG = 'NO'
rather try:
elif NEG.upper() == 'NO':
I found out this is a duplicate...
I made a tuple for any No you might type and check with:
(Notup is the list of NOs)
if OPER in Notup :
Then I made tuples for everything else.

Why won't my if, else statment work in python in the while loop [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)
How do I do a case-insensitive string comparison?
(15 answers)
Closed 4 years ago.
I have this code:
print("Christian Dooley")
print("Lab #5")
import sys
def calculation():
counter = 0
NumberOfElements = 1
numbers = []
sum = (0)
for i in range(NumberOfElements):
value=eval(input("Enter a new number:"))
numbers.append(value)
while counter <= value:
print(counter)
sum+=counter
counter+=1
if counter % 2 != 0:
print("This number is even")
else:
print("This number is odd")
print(sum)
while True:
calculation()
repeat = input("Do you want to 'count' another number \n Awnser yes or no: ")
if repeat == "Yes" or "yes":
calculation()
elif repeat == str("no") or str("No"):
break
When the code runs, it should ask the user to input a number; print every number leading up to it; tell if the number is even or odd; print the sum; and finally have the user enter if he wants to repeat the process or not.
This part of the code is giving me trouble:
if repeat == "Yes" or "yes":
calculation()
elif repeat == str("no") or str("No"):
break
The if statement will keep running over and over, no matter what I enter for the repeat variable. Why does this happen?
The or statement evaluates the first boolean, if it's False it then evaluates the second. Your second boolean statement is actually a string and strings are always True, meaning they exist. The only string that would return False is an empty string "".
Therefore whatever the value of the first boolean, meaning whatever the value of repeat, "yes" will always evaluate to True.
You want if repeat == "Yes" or repeat == "yes" or if repeat in ['Yes', 'yes'] or better still with a set: if repeat in {'Yes', 'yes'}

Python: Keyboard prompt with capital/noncapital letters

In this code:
if raw_input("\n Enter 'y' or 'Y': ")==("y" or "Y"):
print("\n Success!")
It doesn't take the "OR" properly, instead if the in this case noncapital 'y' is entered the condition is fulfilled. If I enter the capital 'Y' I don't get the Success!
What's wrong here?
Try this
if raw_input("\n Enter 'y' or 'Y': ").lower() == "y":
Try to make a list of values and use the in keyword. Something like this will work,
if raw_input("\n Enter 'y' or 'Y': ") in ('y', 'Y'):
print("\n Success!")
The in keyword tests the string against a tuple of strings and on a correct match it returns True.
Since here you have just one character, you can build a string "yY". Something like this will work,
if raw_input("\n Enter 'y' or 'Y': ") in "yY":
print("\n Success!")
Here each character of the string acts like one element of the tuple above.
ERROR in your code:
You used ("y" or "Y"). This does not work in Python. This will only return "y" as both "y" and "Y" are treated as True values. However, if you type (0 or "Y"), you will get "Y" as 0 is treated as a False value.
The right-hand-side of your if-statement is wrong and I think you need to understand a little better how the or operator behaves between strings.
Keep in mind that the return value of or is the value that has been evaluated last, and that Python evaluates empty string as boolean False and non-empty strings as boolean True.
In your case, the interpreter reads ("y" or "Y"), it then evaluates the boolean value of "y" which is True, as it is a non-empty string. Therefore, the boolean value of the or statement it True and the return value of the statement becomes "y", the last evaluated value.
This is how I would write this code. I would keep the return value of raw_input in _input, which will make it easier for me and others to read and understand the if-statement:
_input = raw_input("\n Enter 'y' or 'Y': ")
if input in ["y", "Y"]:
print("\n Success!")
What's wrong here?
In many programming languages, OR is a boolean operator. You apply it to values that are TRUE or FALSE. The operation evaluates to TRUE if at least one operand is TRUE:
TRUE OR TRUE == TRUE
TRUE OR FALSE == TRUE
FALSE OR TRUE == TRUE
FALSE OR FALSE == FALSE
In Python, you can apply or on non-boolean operands:
x or y
returns x if x casted to boolean is True; else it returns y. For boolean operands, this leads to the same results as above, but for non-boolean operands this has interesting effects:
[] or {} is {} (because empty lists are False when casted to
boolean)
[1] or {} is [1] (because non-empty lists are True when casted to boolean)
[1] or 1/0 is also [1] (the right operand doesn't even get evaluated when the left one is True, so we don't hit the ZeroDivisionError. This is known as (left-to-right) short-circuit evaluation.)
Thus, other than in natural language, the Python or cannot be interpreted as separating alternative values. (Only alternative conditions / boolean expressions.)
There are several possibilities on how to make your code behave as expected:
The naive approach:
answer = raw_input("\n Enter 'y' or 'Y': ")
if answer == "y" or answer == "Y":
print("\n Success!")
Normalizing the input:
if raw_input("\n Enter 'y' or 'Y': ").lower() == 'y':
print("\n Success!")
Comparing to set of alternative values with membership operator in:
if raw_input("\n Enter 'y' or 'Y': ") in {'y', 'Y'}:
print("\n Success!")

Categories