Reputation: 223
I have the following code condition
if len(content_tags) >= 1 or tags_irrelevant == 'yes'\
and lengthproblem == 0\
and guess_language.guessLanguage(testlanguage) == 'en'\
and len(sentences) >= 3:
The problem is about the logic and the syntax. I want this to be evaluated as false no matter if if len(sentences)
is not >= 3
. But this is not happening. I think I might need some parenthesis somewhere or something. HELP!
Upvotes: 0
Views: 305
Reputation: 9235
The or
part is causing your problem. Just encapsulate it:
if (len(content_tags) >= 1 or tags_irrelevant == 'yes')\
and lengthproblem == 0\
and guess_language.guessLanguage(testlanguage) == 'en'\
and len(sentences) >= 3:
In cases like this, I have tended in the past to use intermediate bools to abstract the final logical statement to a higher level, for instance:
multi_tags = len(content_tags) >= 1
ignore_tags = tags_irrelevant == 'yes'
tags_ok = multi_tags or ignore_tags
length_ok = lengthproblem == 0
is_english = guess_language.guessLanguage(testlanguage) == 'en'
enough_sentences = len(sentences) >= 3
# Notice how much easier the following is to read!
if tags_ok and length_ok and is_english and enough_sentences:
pass
[This is something one learns to do not from blogs, but from the pain of debugging awful, decades-old legacy code littered with massive conditional clauses in if statements and while loop termination conditions. Oh, and the backslashes are gone too.]
Upvotes: 0
Reputation: 2217
According to the python operator precedence rules, the and operator has precedence over the or operator. That said, if you want the len(sentences) >= 3 part to dominate the answer you should isolate the rest in parenthes:
if (len(content_tags) >= 1 or tags_irrelevant == 'yes' and lengthproblem ==0 and guess_language.guessLanguage(testlanguage) =='en') and len(sentences) >= 3
Upvotes: 0
Reputation: 89077
and
has a higher precidence than or
, so the and
s are evaluated first, then the or
, meaning that the logic you have described in text is not the logic you have described in code.
If you want the first or
to be treated as a single case, then use brackets around it.
if (len(content_tags) >= 1 or tags_irrelevant == 'yes')\
and lengthproblem == 0\
and guess_language.guessLanguage(testlanguage) == 'en'\
and len(sentences) >= 3:
That said, you haven't given us a detailed explanation of the logical behaviour you want from this, so I'd suggest sitting down and working that out properly.
If you need to test your logic, then use a simple test function that prints out so you know what gets evaluated and when.
>>> def test(bool):
... print(bool)
... return bool
...
>>> if test(1) or test(2) and test(3) and test(4) and test(False):
... print("Success")
...
1
Success
>>> if (test(1) or test(2)) and test(3) and test(4) and test(False):
... print("Success")
...
1
3
4
False
You can clearly see the first thing evaluated is the first and
, then it tries to evaluate the left hand side of the and
and so gets the or
. It tries to evaluate this, gets True
for the first value, and so short-circuits, returning True
to the and
, which also short circuits, returning True
(well, actually 1, but True
for the purposes of this example). When the brackets are there, it is evaluated in the way you wanted.
Upvotes: 1