I use pycharm and a few times when using if
statements I have seen the suggestion to change the statement using De Morgan laws, such as with the following if
statement:
if new_odds > 10 and new_odds <= 30:
if not (not (new_odds > 10) or not (new_odds <= 20)):
For me it makes it less readable, so is there any advantage to using De Morgan's laws or is it strictly a personal choice?
Given the results below it would seem that the more complex/less readable expression is also the slowest. In any case readability is most of the time more valuable in python.
In some cases, it makes things more verbose and readable. However, in cases where you already have a bunch of
not
s sprinkled around, or where you're comparing things in a less-than-natural order, demorganing can reduce the number ofnot
s or reverse the order of the unequal comparisons. For example:(The second one is debatable… but that's exactly what you'd expect from a question of readability and style.)
So, if it makes your code more readable, do it; otherwise, don't.
There are a handful of languages (logic, constraint-satisfaction, relational, etc.) where this is not true, because applying a
not
to a value isn't just flipping True and False but generating a converse, possibly much slower, or possibly even indeterminate, query.But that isn't the case with Python, or most other "general-purpose" languages.
In Python it is almost always better to be clear than slightly faster (if that even would have been, which I doubt).
I prefer this even simpler statement:
It can be useful sometimes for readability but it's the same thing at execution. For example with:
The execution will be the same with
a()
True or False.For your example, the best solution remains to use the power of the Python syntax and write:
This syntax is extremely useful for checking that a numeric value is in a particular range.
De Morgan's laws state that:
Which are used to transform logic between alternate forms. So while the transformation you've done conforms to De Morgan's laws, it has become more difficult to read. As others have suggested the much simpler
10 < new_odds <= 30
would be much more readable, however it is very important to understand that this is short for10 < new_odds and new_odds <= 30
because, following from this you can do logic like:Which expands to:
So with that syntactic sugar in mind, lets look at another example:
We will consider a contrived example in simple role-playing game where we look at a skill we will call "dutch courage". The premise of this attack is that you can a bonus if you are at max health, and either your armor or your attack rating is insufficient to attack an enemy. I need to know when this rule won't apply.
Writing this out we have 4 conditions:
Using De Morgan's laws I can decompose this thus:
Well, now I can decompose this further...
Here we assume the opposite of
== max_health
is< max_health
otherwise its not the maximum.Although contrived, this shows us that De Morgan's laws are a tool to enable us to rewrite logic. Whether this logic is improved or not is up to the programmer, but the intent is to be able produce simpler constructs, that are first more readable and secondly and hopefully require less instructions and are thus faster.