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 6 years ago.
I was a bit curious if there's something that I was missing in the code below,
The logic I want the user to enter either "Y" or "H" or "E", which I would like to transfer to another class using a return statement. I use the else part to return boolean False if otherwise.
There is a while loop that would send the control back to this same function until the user enters the required value.
On running the program it never enters the else part no matter what input is received.
def getUserIngameOption(self):
userIngameOption=raw_input("Please Enter Y -> for Turn | H -> Hint | E -> to End")
userDesc=userIngameOption.upper()
if not ( userDesc==("Y") or ("H") or ("E")):
print "Mate PLEASE JUST TYPE WHATTTT is asked for !! not this",userDesc
return False
else:
self.userOpt=userDesc
print "This is detail that you got>>>",self.userOpt
return self.userOpt
You arent making the comparison correctly. You are ORing the result of the first comparison with the boolean value of 'H' and 'E'. Since 'H' and 'E' have a boolean value of True, the IF statement will always be False (since you are inverting the condition's result with not).
Change this:
if not (userDesc==("Y") or ("H") or ("E"))
to:
if userDesc not in ("Y","H","E"):
What is happening is that each one is being evaluated separately, you will need to explicitly compare each value.
if not ( userDesc=="Y" or userDesc=="H" or userDesc=="E")
"E" and "H" will evaluate to True in your current code.
This the the correct method :
if not ( userDesc=="Y" or userDesc=="H" or userDesc=="E")
or this :
if userDesc not in ("H","Y","E").
if not ( userDesc==("Y") or ("H") or ("E")) means (userDesc==("Y")) or (("H")) or (("E")) and the second and third terms are always true.
Related
I am stuck with this question. I am not too concerned about what each function does, but more importantly how does the IF statement work with functions. From my understanding, the IF.... or statements usually work with a condition, but for this scenario it only involves two functions without any conditions?
def disk_check_usage(disk):
du = shutil.disk_usage(disk)
free = du.free/du.total * 100
return free > 20
def check_cpu_usage():
usage = psutil.cpu_percent(1)
return usage < 75
if not disk_check_usage("/") or not check_cpu_usage():
print("ERROR!")
else:
print("Everything is OK")
I want it to give an 'Error!' message when both conditions (free > 20 and usage < 75) are not True/Satisfied.
Edit: When I run the code, 'free' = 17 which gives 'False' and Usage < 75 which gives 'True'. So my IF statement would mean 'If not False or not True:'. What does that mean and how does the system whether to run 'if' or 'else' statement?
Any help will be appreciated!
They are some operations you can do with booleans.
In particular, (not a) or (not b) is equivalent to not(a and b); at least one of the two have to be False
You just have to inverse your tow statements: if everything is ok, print ok else print error
if disk_check_usage("/") and check_cpu_usage():
print("Everything is OK")
else:
print("Error")
From my understanding, the IF.... or statements usually work with a
condition, but for this scenario it only involves two functions
without any conditions?
There's always a condition. The code you posted is no exception.
What you call a "condition" is really just a boolean expression in a specific context. If the entire expression evaluates to True, you enter the body of the if-statement. Otherwise, if it evaluates to False, you don't.
Example
The following code iterates over the characters in a string, and only prints characters which are both alphabetic and uppercase:
string = "Hell2O]WoR3(Ld"
for char in string:
if char.isalpha() and char.isupper():
print(char)
Output:
H
O
W
R
L
>>>
str.isalpha returns a boolean - True if the string (in this case a string consisting of a single character) contains only alphabetic characters, False otherwise.
str.isupper returns a boolean - True if the string (again, just a single character in this case) contains only uppercase characters, False otherwise.
I picked these two string methods to simulate the two functions you have in your code, since they also return booleans.
Let's take the first character, "H":
>>> char = "H"
>>> char.isalpha()
True
>>> char.isupper()
True
>>> char.isalpha() and char.isupper()
True
>>>
You see, the entire boolean expression char.isalpha() and char.isupper() evaluates to True. In order for the entire expression to be evaluated, both functions need to be called - you can think of their return values effectively "replacing" their respective function calls. When char is "H", after calling the functions, the expression really looks like this:
True and True
Which evaluates to True, so we enter the body of the if-statement.
In your case, you used or instead of and. What I said about boolean expressions collapsing down into a single True or False value still applies, the only difference would be in short-circuiting, which isn't that relevant to your question I think.
Example
Here's something closer to what you have. Imagine a scenario where you want to monitor the temperature and radiation of something. If either the temperature OR the radiation levels are not nominal, we trigger an alarm.
def is_temperature_nominal(temp):
return 70 <= temp <= 100
def is_radiation_nominal(rad):
return rad < 200
if not is_temperature_nominal(250) or not is_radiation_nominal(50):
print("Alarm triggered!")
else:
print("Everything is good.")
Output:
Alarm triggered!
>>>
I picked the nominal ranges arbitrarily, and I picked the arguments 250 and 50 arbitrarily as well. With these two hardcoded values, the boolean expression would look like this after calling the two functions:
not False or not True
Which is another way of saying:
True or False
With an or, only one of the operands has to be True in order for the entire expression to evaluate to True - therefore the entire expression evaluates to True, and we enter the body of the if-statement, triggering the alarm (because only one of the values needs to be not nominal in order for the alarm to trigger. If both values are not nominal it would also trigger the alarm. The only way we enter the body of the else is if both values are nominal).
From my understanding, the IF.... or statements usually work with a
condition, but for this scenario it only involves two functions
without any conditions
if (as well as while) needs an expression that evaluates to a logical (type bool) value (either True or False), or can be typecast to a logical value (for example None is typecast to False).
In your case, the conditions (namely, comparisons) are done inside your functions (see the return statements), so that the functions already return logical values.
When calling a method, it's executed and return a value, which can be use in different manner : directly or stored in a variable, this code is exactly the same as the following, but just not saving in variables and inline the methods in the condition
disck_check = disk_check_usage("/") # True or False
cpu_check = check_cpu_usage() # True or False
if not disk_check or not cpu_check: # Boolean conbination
print("ERROR!")
else:
print("Everything is OK")
You have to use 'and' operator instead the 'or' used by you.
def disk_check_usage(disk):
du = shutil.disk_usage(disk)
free = du.free/du.total * 100
return free > 20
def check_cpu_usage():
usage = psutil.cpu_percent(1)
return usage < 75
if not disk_check_usage("/") and not check_cpu_usage():
print("ERROR!")
else:
print("Everything is OK")
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 5 years ago.
I'm just writing a simple if statement. The second line only evaluates to true if the user types "Good!"
If "Great!" is typed it'll execute the else statement. Can I not use or like this? Do I need logical or?
weather = input("How's the weather? ")
if weather == "Good!" or "Great!":
print("Glad to hear!")
else:
print("That's too bad!")
You can't use it like that. The or operator must have two boolean operands. You have a boolean and a string. You can write
weather == "Good!" or weather == "Great!":
or
weather in ("Good!", "Great!"):
What you have written is parsed as
(weather == "Good") or ("Great")
In the case of python, non-empty strings always evaluate to True, so this condition will always be true.
This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 4 months ago.
User_Input = str(input())
if "1" or "2" in User_Input:
print("didn't work [1]")
if "3" in User_Input:
print("didn't work [2]")
elif '4' not in User_Input:
print('didnt work [3]')
elif '5' in User_Input:
print('it worked')
when I make User_Input equal to '5' it doesn't say 'it worked' it instead says
'didnt work [1]' and 'didnt work [3]' which is impossible because 5 doesn't equal 1 or 2 so it shouldn't even get too the line, print('didnt work [3]') but somehow it does. Please help explain this!
You're mixing up how the statements are evaluated, specifically your or.
Here is how it's being evaluated by the interpreter:
# Note: This is evaluated as two separate boolean checks
# as denoted by the parens, rather than one as you are
# intending.
if ("1") or ("2" in User_Input): # "1" is a "truthy" value, e.g. not an empty string, so this is True, and ("2" in User_Input) is not evaluated due to "short circuiting". Meaning no matter what input you get, this if is always True.
Instead what you are trying to see is if the User_Input string is in any of your values:
if User_Input in ["1", "2"]:
# Only happens when 1 or 2 is the user input
What is happening is called short circuiting. Essentially that means that if the result of a boolean operation can be satisfied by the first evaluation, the rest can be skipped.
if True or False: # Since the first is True, the False is never evaluated
if False and True: # Since this is an "and", and the first condition already failed, the True is never evaluated
Now extrapolate that to an expensive function call (not just built ins). It likely saves a lot of time in a larger function. To demonstrate:
import time
def my_long_func():
"""Waits 5 seconds and returns False"""
time.sleep(5)
return False
def my_true_func():
"""Immediately returns True"""
return True
if my_true_func() or my_long_func():
print("This happens immediately, because of short circuiting.")
If you run ^ in your interpreter, you will see that the print happens immediately and your program never waits on the 5s sleep because it's unnecessary (that function is never called). Essentially it's an easy programming optimization that every language I can think of does automatically for you :)
This question already has answers here:
Does Python support short-circuiting?
(3 answers)
How do "and" and "or" act with non-boolean values?
(8 answers)
Closed 9 years ago.
When I test the difference between and and or, I meet this problem. Could you please help me understand it?
This behavior is a weird quirk that comes out of three different features of python code. Non-zeros values are true, logical operation evaluation, and short-circuiting. I'll explain these features below:
Non-Zero Values are True
The first thing you have to know in evaluating these expressions is that they are logical operators. They are designed to work with true or false values:
true and true = true
true and false = false
false and true = false
false and false = false
true or true = true
true or false = true
false or true = true
false or false = false
However, python (and many languages) allow you to put any value in. So long as they are non-zero they are considered true. So:
4 and 5 = true
4 and 0 = false
This is normal so far. Most languages have this.
Logical Operation Evaluation
Here Python does something a little unique. Instead of returning true or false, it actually returns the value of the last item it checked in the statement. So:
4 and 5 = 5 (which will be evaluated as true)
To fully understand which value will actually get returned you have to also understand:
Short-Circuiting
When evaluating these logical operators, the compiler can often stop early. Take the example:
3 or 4
We know that the statement will return true, but which value will it return? To figure this out you have to understand which value will be the last one looked at. The system will look at 3, and realize that the statement is true. It doesn't matter what the second value is, 3 or anything is true. So the value returned is 3 because it is the last value checked.
However, if we use and:
3 and 4
Once we look at 3, we still need to check that the second value is true. It could makes a difference. So the second value is evaluated. If it is true, it returns the last value looked at, in this case 4.
In Conclusion
You just have to think about which value the interpreter can stop on.
3 or 4 = 3 // because we can stop at 3
3 and 4 = 4 // because we have to check the 4
0 or 3 = 3 // because we needed to check the 3
Yes, the and operator requires all arguments to be true, and returns the last one checked, which is 5. (If any of the arguments were false, it would return the first false value, since that would be the last one checked in order to verify if all arguments were true.)
The or operator requires only one argument to be true, and returns the last one checked, which is 4, because 4 represents the first true value in the conditional. (If all arguments were false, then the return value would be equal to the last false value, since that would be the last value checked in order to verify if any of the arguments were true.)
true1 and true2 >>>true2
true1 or true2 >>>true1
when runinng true1 and true2, python must check the value returned by every expression is true or not, so it will return the last one.
but when running true1 or true2 , as true1 retrun "true" (in your example, 4 is "true") already, so it is unncessary to continue checking the rest.
I think the way to look at it is at a simpler level, which was designed for optimization.
and requires that both sides be "truthy." It checks the left side. If it is "truthy," it returns the second value without checking what it is.
or requires only one side to be "truthy." It checks the first side. If it is "truthy," it returns it. If not, it returns the second side, again without checking it.
For "4 and 5", because 4 is "truthy," it returns 5.
For "4 or 5", it returns 4 without even looking at 5.
Need proof? Make these functions:
def four():
print 'Evaluating four!'
return 4
def five():
print 'Evaluating five!'
return 5
Now see what gets printed:
>>> four() and five()
Evaluating four!
Evaluating five!
5
and evaluated four(), and since it was true it returned five().
>>> left() or right()
Evaluating left side!
4
or evaluated four() and since it was true, returned four() without even calling five()!
This question already has answers here:
How do "and" and "or" act with non-boolean values?
(8 answers)
Closed 6 months ago.
I'm a little confused with the results I'm getting with the logical operators in Python. I'm a beginner and studying with the use of a few books, but they don't explain in as much detail as I'd like.
here is my own code:
five = 5
two = 2
print five and two
>> 2
It seems to be just outputting the two variable.
five = 5
two = 2
zero = 0
print five and two and zero
So, I added another variable integer. Then I printed and got the following output:
>> 0
What is going on with Python in the background? Why isn't the output something like 7 or 5, 2.
Python Boolean operators return the last value evaluated, not True/False. The docs have a good explanation of this:
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
As a bit of a side note: (i don't have enough rep for a comment) The AND operator is not needed for printing multiple variables. You can simply separate variable names with commas such as print five, two instead of print five AND two. You can also use escapes to add variables to a print line such as print "the var five is equal to: %s" %five. More on that here: http://docs.python.org/2/library/re.html#simulating-scanf
Like others have said AND is a logical operator and used to string together multiple conditions, such as
if (five == 5) AND (two == 2):
print five, two
Boolean And operators will return the first value 5 if the expression evaluated is false, and the second value 2 if the expression evaluated is true. Because 5 and 2 are both real, non-false, and non-null values, the expression is evaluated to true.
If you wanted to print both variables you could concatenate them to a String and print that.
five = 5
two = 2
print five + " and " + two
Or to print their sum you could use
print five + two
This document explains how to use the logical Boolean operators.
This AND in Python is an equivalent of the && in Java for instance. This doesn't mean the and in the English language. The AND is a logical operator. Assume five holds 5 and two holds 2. From Python documentation: The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned. Basically, it evaluates the last integer in your case which is true.
if (five and two):
... print "True"
... else:
... print "False"
The AND is a logical operator, to test the logic for a specific case, not an arithmetic operator. If you want to get results like 7 for five and two, you should rather use "+" which means adding two integers. See below:
>>> five = 5
>>> two = 2
>>> print five + two
7
Try 0 and 9.
The result is 0 because the value of 0 is false. The operand on the left of the and operator is False so the whole expression is False and returns 0
In Python any non-zero integer value is true; zero is false.
The OP’s values are both non-zero.
The AND operator tests from left to right,
with and, if all values are True, returns the last evaluated value.
If any value is false, returns the first one.
Since both are non-zero, both are true, so the last value is returned
To convert the integer variable to a string , add str in front of each variable
five = 5
two = 2
print(str(five) + " and " + str(two))