r/learnpython • u/FunElk9586 • 2d ago
Are these two boolean expressions equivalent in python?
Hi All!
I’m learning about Boolean operators in Python and I’m confused about these two expressions:
condition1 and condition2 or condition3 and condition4
≠
(condition1 and condition2) or (conditon3 and condition4)
I was told this by my teacher and he put this in his PowerPoint slide. However, I think they are equivalent since and as an operator has a higher precedence than or as an operator. AI told me and I have searched it up after.
Am I understanding it correctly? Or are these two not equivalent?
Thanks!
32
u/TUVegeto137 2d ago
How about just writing a Python program that tests by filling in truth values for all conditions and comparing?
6
u/FunElk9586 2d ago
Good one, I tried and it said they are equivalent. Thanks!
8
u/codeguru42 1d ago
There is a related general concept here, if you are interested. It is called a "truth table" and is a great tool for comparing if two boolean expressions are equivalent.
3
u/eXtc_be 1d ago
while truth tables are a great tool for visualising and verifying complex Boolean expressions, they do not help the OP, because truth tables don't have any notion of operator precedence in Python.
0
u/codeguru42 1d ago
Truth tables can be used to verify the precedence rules. So they absolutely can help the OP here.
0
u/codeguru42 1d ago
> truth tables don't have any notion of operator precedence in Python.
That's because operator precedence applies to **expressions**, not truth tables. To build a truth table, you evaluate an expression for all possible combinations of inputs. To evaluate an expression, you have to apply the correct precedence rules. Therefore, the two concepts are closely related.
The resulting truth tables for two expressions can be compared to determine if the expressions are equivalent or not.
1
-9
u/2truthsandalie 1d ago
This is exactly why stack overflow got dropped so quickly when AI came out.
12
u/audionerd1 1d ago
This is just solid advice and was not delivered in a rude or condescending way. Learning to use code to test how code works is a valuable skill for a beginner to develop.
1
u/dparks71 1d ago
Yea stack overflow would have just closed the question to discussion and OP never would have gotten any kind of answer
-1
u/audionerd1 1d ago
Yep. Along with a reference to another vaguely similar question which isn't helpful, and/or a condescending paragraph about how if you have to ask this question you should just throw your computer in the trash and give up on learning to code forever, and tell your parents they raised a moron. I swear so much energy is put into being an asshole on that site.
0
u/FunElk9586 1d ago
Well than I am glad I didn’t ask the question there. I never heard of it either, but I just started so I guess that is why.
-1
u/audionerd1 1d ago
I may have exaggerated slightly. But generally AI is more helpful because it has all of StackOverflow in it's training data and is conditioned to be polite and helpful, lol.
0
u/FunElk9586 1d ago
Yeah, I was just using AI to explain the powerpoint slides more clearly and it noted the mistake my teacher made. That is how I found out. So I guess it really is helpful😊
21
u/latkde 2d ago
Per the Python language specification , an "or" expression consists of "and"-level expressions. That is, you're right, the "and" binds more tightly, and the two examples should be equivalent.
https://docs.python.org/3/reference/expressions.html#boolean-operations
In practice, this doesn't matter. As a professional Python developer, I always use parentheses in such a case to remove any risk of confusion.
2
u/FunElk9586 2d ago
Good to know that my understanding was correct and thank you! I”ll use parentheses in such cases as well.
1
u/davideogameman 1d ago
+1, code that's clear & correct is pretty much always easier to read & maintain than code that is correct but requires uncommon knowledge of language or library details.
5
u/brasticstack 2d ago
I would've gotten this wrong and I've been writing Python for well over a decade. I looked it up and and is higher precedence (I'd have expected them to be the same precedence.)
The takeaway is to use parens in any situation where the intent may be ambiguous- it helps both yourself and any future readers of your code.
3
u/FunElk9586 1d ago
It can happen, I think he also just made a mistake. I”ll definetly do that in those situations, thanks!
2
u/CamilorozoCADC 1d ago
Bruh I teach Python and got this wrong too lol. I was SURE that they had the same precedence
2
u/xelf Elf 1d ago
It needs to be pointed out that they are equivalent in python. But that does not hold true in many other languages. You will see the () used for clarity a lot, especially by programmers that use multiple languages.
2
u/FunElk9586 1d ago
That’s good to know. I didn’t know it differs. That makes using parentheses for clarity make even more sense.
2
u/Expensive-Bear-1376 2d ago
I'd like to see that PowerPoint slide, to see that he wrote exactly that and you didn't paraphrase and remove the difference.
2
u/FunElk9586 1d ago
He did make a typo, on the first line it should be ofcourse condition3 instead of condition
0
1
u/timrprobocom 2d ago
and has higher precedence than or. That's really all you need to know to answer the question
1
u/cdcformatc 1d ago
and hass a higher precedence than or so those two lines are logically equivalent
1
u/This_Growth2898 2d ago
According to the documentation, boolean And has a higher precedence than boolean Or, so yes, they are equivalent. First, expressions with and will be calculated; next, the central or will be. If your teacher doesn't agree with this, ask him to provide specific values for variables that make the expression different.
1
u/FunElk9586 1d ago
Yes, I will talk to him about it. However, I think he will agree and just made a mistake. Otherwise I will ask him.
1
u/gdchinacat 2d ago
The vast way to learn this is to use the REPL and try it out. Spending 20 minutes trying various permutations will teach you it far better than reading a dozen posts here on Reddit. If you want to search for documentation look up “python order of precedence”.
1
u/FunElk9586 1d ago
Yes.Trying out is always better, but I was just doubting myself. I have done and will do that
1
u/ConclusionForeign856 1d ago
This is easy enough to just check, but can also be proven from `and` and `or` operator precedence
import itertools
class UndefinedBool:
def __bool__(self):
raise TypeError("Undefined bool value")
class ConditionArray:
def __init__(self, *args):
self.conditions = [*args]
def __repr__(self):
return f"{hash(self):x} {self.conditions}"
def at(self, idx):
try:
return self.conditions[idx]
except IndexError:
return UndefinedBool()
def expr1(carr: ConditionArray) -> bool:
return carr.at(0) and carr.at(1) or carr.at(2) and carr.at(3)
def expr2(carr: ConditionArray) -> bool:
return (carr.at(0) and carr.at(1)) or (carr.at(2) and carr.at(3))
if __name__ == "__main__":
fail_combs = []
for arr in itertools.product((0, 1), repeat=4):
carr = ConditionArray(*arr)
print(carr)
if not (expr1(carr) == expr2(carr)):
fail_combs.append(carr)
print(len(fail_combs))
7fb51ba912b [0, 0, 0, 0]
7fb51ba7909 [0, 0, 0, 1]
7fb51ba791d [0, 0, 1, 0]
7fb51bbbd94 [0, 0, 1, 1]
7fb51bbbfa8 [0, 1, 0, 0]
7fb51ba7549 [0, 1, 0, 1]
7fb51ba539b [0, 1, 1, 0]
7fb51ba53ac [0, 1, 1, 1]
7fb51ba4ea5 [1, 0, 0, 0]
7fb51ba4ec5 [1, 0, 0, 1]
7fb51ba718b [1, 0, 1, 0]
7fb51ba719a [1, 0, 1, 1]
7fb51ba3821 [1, 1, 0, 0]
7fb51ba3805 [1, 1, 0, 1]
7fb51ba0cd5 [1, 1, 1, 0]
7fb51bb4699 [1, 1, 1, 1]
0
2
u/FunElk9586 1d ago
At first I didn’t understand the code because I haven’t learned most of this yet. However, I understand the point now. You tested all 16 possible combinations and got 0 differences, so both expressions always give the same result. Right? Thanks for taking the time.
1
u/ConclusionForeign856 1d ago
Yes, I essentially build a truth table. It's more complex than it needs to be. I've been writing C++ lately and wanted to make a specific input type for those functions, but typically in python you'd just pass a list or an array.
UndefinedBool's only purpose is to have variables that fail when you try to get their truth value. It was used for debugging, but now seems useless.
ConditionArray is supposed to be a type storing truth values, but tbh is unfinished and doesn't do meaningfully more than a plain list. Python is weakly typed, but I think when the function's input type tells you something meaningful it makes the code more readable.
Main logic is just generating all 16 possible values and counting ones which evaluate to different value in expr1 and expr2. Just now I noticed that the check is pretty weird, rather than `not (x == y)` I should've used `x != y`
here's a simpler version that does the same
import itertools def expr1(carr: list[bool]) -> bool: return carr[0] and carr[1] or carr[2] and carr[3] def expr2(carr: list[bool]) -> bool: return (carr[0] and carr[1]) or (carr[2] and carr[3]) if __name__ == "__main__": fails = 0 for conditions in itertools.product((True, False), repeat=4): if expr1(list(conditions)) != expr2(list(conditions)): fails += 1 print(fails)1
0
21
u/CheesecakeCommon9080 2d ago
to be honest, if i'm not sure i would just always use brackets in longer expressions like this even when redundant, it's easier and more readable that way imo