De Morgan's laws state that:
"not (A and B)" is the same as "(not A) or (not B)"
and also,
"not (A or B)" is the same as "(not A) and (not B)"
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 for 10 < new_odds and new_odds <= 30
because, following from this you can do logic like:
10 < new_odds <= 30 != max_odds | default_condition
Which expands to:
10 < new_odds and new_odds <= 30 and 30 != max_odds and max_odds | default_condition
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:
A = health == max_health
B = armor > enemy.attack
C = attack > enemy.defense
no_bonus = not(A and not(B and C))
Using De Morgan's laws I can decompose this thus:
not(A and not(B and C))
not(A) or not(B and C)
not(A) or not(B) or not(C)
not(health == max_health) or not(armor > enemy.attack) or (attack > enemy.defense)
Well, now I can decompose this further...
health < max_meath or armor < enemy.attack < attack > enemy.defense
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.
10 < new_odds <= 30
? – Twelvemonth