I find code like this really confusing:
if a and b and c:
if d or e:
elif f and g:
Furthermore, updating those rules is nasty. I’m very likely to get something wrong, especially when “if a” is really some elaborate method call with several parameters.
It get a little more obvious when I flatten it out like this:
if a and b and c and (d or e or (f and g)):
That looks OK for this contrived example, but imagine I need to stick in another clause that says also return True when a and g are True. It ain’t so easy to arrange the code any more.
Over the years, I’ve run into this situation a lot. Usually, I’m doing something like registering a new user, and I want to rule out that this new user is already in the database. So I have to look up the user on a variety of fields, like maybe email address, their user name, their mobile number, etc.
When I can boil the action down into something like “do this, unless any of these scenarios apply” I write the code in this format:
# Beginning of the gauntlet
if not a:
if not b:
if not c:
if not d or e:
# End of the gauntlet
I put the fastest reasons to disqualify the action at the beginning. The really elaborate stuff belongs at the bottom.