So, while digging around in some external library code I stumbled across this method:
def format(self, value):
if isinstance(value, set):
value = list(value)
return [
self.container.output(idx,
val if (isinstance(val, dict)
or (self.container.attribute
and hasattr(val, self.container.attribute)))
and not isinstance(self.container, Nested)
and not type(self.container) is Raw
else value)
for idx, val in enumerate(value)
]
You can see it is very difficult to understand what is going on there..
Please do not try to understand what the method is doing or where it comes
from. That’s not the point I am trying to make here -
just look inside self.container.output
.
The method self.container.output
gets the parameter idx
and
either val
or value
based on some conditions.
These conditions are the cause why it is hard to understand.
It is val
if three conditions are met, but the first one contains
further nested conditions where one of them is again nested… Complicated.
So I took the liberty to reformat the code without changing the logic of it (just whitespace changes). It turned out to this:
def format(self, value):
if isinstance(value, set):
value = list(value)
return [
self.container.output(
idx,
val
if (
isinstance(val, dict)
or (
self.container.attribute
and hasattr(val, self.container.attribute)
)
)
and not isinstance(self.container, Nested)
and not type(self.container) is Raw
else value
)
for idx, val in enumerate(value)
]
Well, yes, it became much longer, but on the pro side my PEP8 linter in the editor won’t complain about bad-continuation anymore. (It still complains about the Redefining built-in ‘format’, but anyway…)
Basically I removed all the hanging indents - now it is much easier to
understand how these conditions interact.
That single or
moved one indentation step further to the right,
so one can clearly see, it has nothing to do with the and
s on the outside.
Then I remembered some talk I watched years ago - If your code is easy to grasp visually, the chance someone else understands it is way higher.
Ok, let’s give it a try - how about some dirty script?
#!/usr/bin/env python3
from sys import stdin, stdout
from string import whitespace
if __name__ == '__main__':
for line in stdin:
stdout.write(''.join(
char if char in whitespace else '#' for char in line
))
stdout.flush()
It replaces everything but whitespace with an #
character.
The first example turns out like this:
### ############ #######
## ################# #####
##### # ###########
###### #
##########################
### ## ################ #####
## #########################
### ############ ###########################
### ### ########################## #######
### ### #################### ## ###
#### ######
### #### ### ## ################
#
And the second one like this:
### ############ #######
## ################# #####
##### # ###########
###### #
######################
####
###
## #
############### #####
## #
########################
### ############ #########################
#
#
### ### ########################## #######
### ### #################### ## ###
#### #####
#
### #### ### ## ################
#
Just by looking at these outputs without comparing it to the original code (don’t scroll up) it is suddenly possible to see the different nesting levels, and how they act together.
In my opinion, the second one shows it more clearly - although it takes up much more horizontal space. But I think this is worth it - scrolling through text on the screen takes much less effort than reading the same code over and over again…
Think of it next time you are trying to write very dense code!
So long!