True - False dilemma - python

I can't understand what is happening here?
True = False
False = True
print True, False
output
False False
Isn't the output be printed as False True?

You are setting True = False, and then False = True.
True = False
False = True # But "True" here is now False.
print True, False # True = False, because of the first line. As does False, because you set it equal to "True" which you have already made == False.
I don't know why you would ever want to do this, other than to mess with someone's code, as it's a readability nightmare - as you can see just from the difficulty in using the words to explain it.
If you really want to swap the vaules around, then do:
True, False = False, True

You seem to be using Python 2.
This wouldn't work in Python 3 as True and False were changed to keywords in order to make assignment to those impossible.
Refer to Core Language Changes:
Make True and False keywords. [6]
Reason: make assignment to them impossible.

Once you do True = False, True is no longer a boolean but rather a variable that has been assigned the boolean False. Therefore, the line False = True is actually assigning True's value (False) to the variable False.

Related

Unexpected results from any() and all() functions, and how do I read strings as false? [duplicate]

This question already has answers here:
How does all() in python work on empty lists
(5 answers)
Reason for "all" and "any" result on empty lists
(9 answers)
What is the rationale for all comparisons returning false for IEEE754 NaN values?
(12 answers)
Why does "not(True) in [False, True]" return False?
(8 answers)
What is Truthy and Falsy? How is it different from True and False?
(8 answers)
Closed 2 years ago.
I was testing the all() and any() functions to make sure I understood how they operate. Turns out I do not understand them. Here is my test code:
v1=[True, False, True] # unexpected 2
v2=[True] # wai
v3=[] # unexpected 2
v4=[False] # wai
v5=[False,False] # wai
v6=[False,False, True] # unexpected 2
v7=[False]*4 # wai
v8=[float('nan'),False]# unexpected 1, but I think this is because any() considers "truthy" values. Given this, 2 is unexpected.
v9=['f','t'] # wai, given "truthy" values. Would like this to return False.
v10=['random_string'] # same as above
vlist=[v1,v2,v3,v4,v5,v6,v7,v8,v9,v10]
for v in vlist:
print('any true:',any(v)==True,'| not all false:',not(all(v)==False),'(',v,')')
Returns:
any true: True | not all false: False ( [True, False, True] )
any true: True | not all false: True ( [True] )
any true: False | not all false: True ( [] )
any true: False | not all false: False ( [False] )
any true: False | not all false: False ( [False, False] )
any true: True | not all false: False ( [False, False, True] )
any true: False | not all false: False ( [False, False, False, False] )
any true: True | not all false: False ( [nan, False] )
any true: True | not all false: True ( ['f', 't'] )
any true: True | not all false: True ( ['random_string'] )
Where I've coded the output to display the logical summary of the statement (ex: any true), followed by the evaluated value. This is done for both statements, and then the parenthetical at the end shows the list evaluated.
Most of my surprises come from the not all() combination. But I was also expecting non-true values (ex: float('nan') or 'random_string') to be false. Looking at the documentation I see that this is not the case, but I would like to know how to make this an option.
I attempted to code tests for the logical statements: "are any True?" and "not: are all False?". If I'm not mistaken, these should be logically identical.
Some more detailed explanations for my surprises. I refer to the "inside" statement as all(v)==False and the negation of this being the outside statement:
v1=[True, False, True] - For the inside statement, I consider whether all elements are False. This is clearly not the case, so I expect the statement to be false. The outside not negates this, so the result of this should be True.
v3=[] - The set is empty. Thus all elements are false is True, and not this should be false.
v6=[False,False, True] - It's clear that there are some True elements, so the inside statement is False. Not this, means it should be True.
v8=[float('nan'),False] - This one is a puzzle for me. I'd like 'nan' to read as False (only accept True values), but looking at the documentation this is not how it works. Given this piece of information, it is unexpected that the second statement reads False, since 'nan' is a "truthy" value. So all elements are False is a false statement, and negated I'd expect the output to be True.
v9 and v10 Are working as expected once I learned about the "truthy" values. However, I'd like them to read False under both circumstances (considering only 1 or True as a True value, others as False). Of particular concern to my current project is reading 'nan','NaN',etc. as False.

Can I really remove this seemingly redundant code without breaking things?

I found a snippet in our code base that looks kind of useless to me but I suspect that somebody put it there for a reason that eludes me; so I thought I'd ask around. The part is something like this:
someParam = 'nope' # someParam is actually a query result, not a fixed string
if someParam != 'nope' and True or False
In my opinion the and True or False is doing exactly nothing for the evaluation and can be removed since the first part, the equality check, combined with the and True (operator precedence and > or, IIRC) is the same as the first part:
If first part evaluates to True -> True and True -> True
If the first part is False -> False and True -> False
now those results with the appended or False:
True or False -> True
False or False -> False
So the result of the condition would not change if I removed the and True or False, correct? Or am I missing something here?
Also could the behaviour of this change while switching from Python 2 to 3? I think not but I'm not quite sure.
You can remove and True or False from if statement, as it return same result what someParam != 'nope' will give.
You can check it by simple example as:
True and True or False
The output is always True Whereas
False and True or False
The output is always False
As you say, the expression foo and True or False is just a complicated way of converting the "truthiness" of the value foo into an actual boolean:
>>> 'foo' and True or False # non-empty strings are truth-y
True
>>> '' and True or False # empty strings are false-y
False
(You can see the rules for built-in types' truthiness here.)
This is because and and or return one of their operands, per the docs:
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.
The expression x or y first evaluates x; if x is true, its value
is returned; otherwise, y is evaluated and the resulting value is
returned.
and, as you say, the operator precedence for and is higher than or.
That code is totally redundant, for a number of reasons:
Because Python already gives you a built-in way to do that, bool:
>>> bool('foo')
True
>>> bool('')
False
Because foo is already a boolean anyway; != is a comparison, and the result of any comparison is either True or False, so any conversion to boolean is redundant.
Because in a context like if foo:, even if foo wasn't already boolean, Python will automatically evaluate the truthiness of foo rather than only accepting a boolean, so if foo and True or False: and if bool(foo) are both pointless; you can just write if foo:.
And no, none of the above points changed between Python 2 and 3. You can check the equivalent links for all of the above in the new version:
Truthiness
Boolean operations
Operator precedence
bool
Comparisons
Yes, x and True or False can be simplified to just x when x is a boolean value.

How are conditional statements with multiple conditions evaluated?

I'd expect the following two code blocks to be evaluated the same way, but it would seem that is not the case. For example, with this:
if True or False and False:
print('True')
else:
print('False')
True is printed. But with this:
if (True or False) and False:
print('True')
else:
print('False')
False is printed. Here's my breakdown of the logic:
True or False = True
True and False = False
By substitution, (True or False) and False = True and False = False.
Why does this happen?
This is because of operator precedence. Per the Python 2.x and 3.x docs, the and operator has higher precedence than the or operator. Also, have a look at the boolean truth table:
That means in your expression:
if True or False and False:
In the expression, False and False is grouped together because of precedence. That means Python evaluates it as:
if True or (False and False):
Now, it's evaluated left to right. Since the first condition is True, it short-circuits and skips the second condition and evaluates to True printing 'True'. (This short-circuits because if the first side is true, it has to be true.)
Now in your second example:
if (True or False) and False:
This makes True or False evaluate first, which gives True. Then it does True and False which is False, printing 'False'.
>>> print(True or False)
True
>>> print(True and False)
False
(True or False) evaluates to True. Therefore (True or False) and False evaluates to True and False, which evaluates to False.
This answer explains the rules for boolean evaluation quite well: https://stackoverflow.com/a/16069560/1470749
Standard Order of operations gives and precedence over or, so the first statement True or False and False is logically equivalent to
True or (False and False)
This evaluates to True.
The second statement is
(True or False) and False
This evaluates to False.

Python, Boolean - Conditionals & Control Flow - Not understanding

I cant seem to grasp Bootlean operators. I'm using an example from Code Academy. At first I read it wrong and was putting True or not False and False Instead of True or False.
Can someone explain this a bit more clearly for me so I can get more of an understanding.
Assign True or False as appropriate for bool_one through bool_five.
Set bool_one equal to the result of False or not True and True
Set bool_two equal to the result of False and not True or True
Set bool_three equal to the result of True and not (False or False)
Set bool_four equal to the result of not not True or False and not True
Set bool_five equal to the result of False or not (True and True)
You have three boolean operations and some rules:
not, which just inverses (aka not True => False, not False => True)
or, which works on two operands x or y and returns True if either is True and False if they are both False
and, which works on two operands x and y and returns True if both are True and False otherwise
They are evaluated from left to right
not has the highest precedence, and after that, lastly or
You can use () to change the precedence of operations, just as in everyday math
5.15 Operator Precendence (listed lowest to highest, and I trimmed many operators)
or
and
not
(expressions...)
So you can see that from low to high precedence it is or then and then not then (). Example
False or not True and True
So if I add parentheses to emphasize order
(False or (not True)) and (True)
becomes
(False or False) and (True)
False and True
False
You can follow this process with the other lines
A boolean variable can have one of two values - True or False. There are several operators that can help you manipulate boolean values:
not inverts the value - True becomes False and vise-versa
and returns True if and only if both operands evaluate to True
or returns True if either or the operands evaluate to True
This exercise asks you to translate the English statements to python:
bool_one = False or not True and True
bool_two = False and not True or True
bool_three = True and not (False or False)
bool_four = not not True or False and not True
bool_five = False or not (True and True)

not (not false) = True?

I'm currently on page Conditionals & Control Flow, Python, Code Academy.
I've made this thinking it will be False but it is wrong.
Make me false!
bool_three = not (not False) == True
Objects in parentheses are worked out first, so by my logic:
not (not False [which becomes True]) = True
not True [which is false] = True
not (not False [which becomes True]) = True
What makes you think "not not false" would be true? If a boolean value is negated, it becomes the opposite value. If it's negated again, it becomes the original value.
Let's derive it a step at a time...
not (not False) == True
not (True) == True
False == True
False
bool_three = not (not False) == True
Here that's goes :
not ( not False ) become not ( true ) became false.
Then False == True (which is false)
so then bool_three = false
Quick Python interpreter check:
>>> not not False == True
False

Categories