def mouseMoved(self, info):
point = info["point"]
text = u"%.0f %.0f" % (point.x, point.y)
self.set(text) def mouseMoved(self, info):
point = info["point"]
text = u"%.0f %.0f" % (point.x, point.y)
self.set(text) def mouseMoved(self, info):
point = info["point"]
text = u"%.0f %.0f" % (point.x, point.y)
self.set(text)
Is that any less readable?Urgent request! We need two new variables for some debugging: distance and relative_velocity. Going back to the vertically aligned format, we will add them like this:
def mouseMoved(self, info):
point = info["point"]
text = u"%.0f %.0f" % (point.x, point.y)
distance = self.calculate_distance(info)
relative_velocity = self.calculate_velocity(distance, info)
log_move(point, text, distance, relative_velocity)
self.set(text)
We had to add whitespace to the previous assignments to match the new ones. Now, with all that horizontal whitespace, my eyes have trouble tracking what is assigned to what. And the version control history will have unnecessary formatting diffs.If you forgo the column alignment, those problems go away:
def mouseMoved(self, info):
point = info["point"]
text = u"%.0f %.0f" % (point.x, point.y)
distance = self.calculate_distance(info)
relative_velocity = self.calculate_velocity(distance, info)
log_move(point, text, distance, relative_velocity)
self.set(text)If it's not aligned I have trouble identifying exactly what I need because it's so chaotic. When everything's aligned it's a bit like a table and my brain immediately knows where the right-hand side is no matter which line I want to read.
Now I don't do that everywhere, often it just doesn't bring any benefit. But generally I often find it helpful and it's one of the quickest ways I can make some code blocks more readable, as it takes just a few keypresses.
def mouseMoved(self, info):
point = info["point"]
text = u"%.0f %.0f" % (point.x, point.y)
distance = self.calculate_distance(info)
relative_velocity = self.calculate_velocity(distance, info)
log_move(point, text, distance, relative_velocity)
# Update overlay label
self.set(text)
I find that a much more readable style. Instead of stuff on the left - assigned to stuff on the right, its now a story made up of steps: First we're figuring getting some variables for text labels, and distances. Then logging that out. Then after that we're updating the label on the overlay. Each step in the story has a little breath (the newline). And if needed, a comment.Here's a random work-in-progress example from some real code I'm working on this week. Its not beautiful or overly fancy. Just steady, confident and readable (assuming you know the context):
https://github.com/josephg/diamond-types/blob/2e807298a70382...
I guess it's different between people, I personally find it noticeably slower and more difficult to read like that. Blank lines inbetween don't help because it's about horizontal alignment.
Both approaches emphasise different narratives about the code. The aligned block style emphasises the similarity between the assignments. My space-between-lines style emphasises the difference between each block of code, as if each block is a paragraph it’s own separate intent.
If the assignments were actually similar, I would find the other approach more compelling. Some sibling comments have given better examples where this makes sense. But for this code in particular, the assignments are more different than similar (in both goal and subject). I’d use spacing to make that difference obvious.
const style = {
x : 3,
y : 2,
width : 0,
height : 0,
backgroundColor : 'white',
color : 'black',
fontWeight : 'normal',
shadowStyle : 'none',
borderStyle : 'round'
paddingX : 2,
paddingY : 1,
}Please don't take offense! What works for me doesn't have to be what works for you, OK? :-)
But the insight - if I dare call it that - is that one style leads me to read across each line, where the other style leads me to read down the columns.
In your example, my eyes see an x, a y, a width, a height, a backgroundColor, a color, and so on. And then I see a 3, a 2, a 0, another 0, a 'white', a 'black', etc.
As you can tell, I am reading down the first column, and then reading down the second column. And by then I'm losing track of which thing goes with which.
It's not that I mean to do that, it's just how my eyes are drawn when I see something arranged in columns.
If we reformat this without the column alignment, it looks like this:
const style = {
x: 3,
y: 2,
width: 0,
height: 0,
backgroundColor: 'white',
color: 'black',
fontWeight: 'normal',
shadowStyle: 'none',
borderStyle: 'round'
paddingX: 2,
paddingY: 1,
}
It's definitely not as nice looking this way! But now I read it completely differently:We have an x of 3, a y of 2, a width of 0, a height of 0, a backgroundColor of 'white', a color of 'black', etc.
This style leads me to read across each line instead of down each column. I think that may be why it is easier for me to understand.
And to repeat myself, I am truly grateful to you for posting this example. It helped me get some understanding of what goes on in my eyes and brain.
I use this style also in expressions: often when coding graphics you have similar operations or variables and ordering it in “column fashion” allows quick skimming and error spotting.
Another (real) example:
const neighbors =
get(x - 1, y - 1, w, h, prev) +
get(x, y - 1, w, h, prev) +
get(x + 1, y - 1, w, h, prev) +
get(x - 1, y, w, h, prev) +
get(x + 1, y, w, h, prev) +
get(x - 1, y + 1, w, h, prev) +
get(x, y + 1, w, h, prev) +
get(x + 1, y + 1, w, h, prev)My only suggestion is to be more generous with whitespace inside the parentheses:
const neighbors =
get( x - 1, y - 1, w, h, prev ) +
get( x, y - 1, w, h, prev ) +
get( x + 1, y - 1, w, h, prev ) +
get( x - 1, y, w, h, prev ) +
get( x + 1, y, w, h, prev ) +
get( x - 1, y + 1, w, h, prev ) +
get( x, y + 1, w, h, prev ) +
get( x + 1, y + 1, w, h, prev )
I don't quite understand why, but most modern coding styles prohibit ever putting a space inside the parens. I think the common philosophy is to follow the same conventions you would when writing English prose. But we're not writing prose, we're writing code! To me it is more readable if we allow a little breathing room inside the parens.This looks better in monochrome text but usually the editor colors allow a fast distinction of the parentheses, variables and literals so the extra space is not needed for me.
const neighbors = get(x - 1, y - 1, w, h, prev) + get(x, y - 1, w, h, prev) +
get(x + 1, y - 1, w, h, prev) + get(x - 1, y, w, h, prev) +
get(x + 1, y, w, h, prev) + get(x - 1, y + 1, w, h, prev) +
get(x, y + 1, w, h, prev) + get(x + 1, y + 1, w, h, prev)
In the past, I've resorted to things like adding no-op `+ 0` for alignment and empty comments to force it to preserve line breaks while still allowing it to autoformat the rest: const neighbors = get(x - 1, y - 1, w, h, prev) + //
get(x + 0, y - 1, w, h, prev) + //
get(x + 1, y - 1, w, h, prev) + //
get(x - 1, y + 0, w, h, prev) + //
get(x + 1, y + 0, w, h, prev) + //
get(x - 1, y + 1, w, h, prev) + //
get(x + 0, y + 1, w, h, prev) + //
get(x + 1, y + 1, w, h, prev)
I really wish that autoformatters had the smarts to understand that if more than X% of the non-whitespace columns within a block repeat the same character from top to bottom, then the lines are probably intentionally aligned that way and that it should try very hard to preserve that alignment. That would eliminate my one real objection to autoformatters. (Bonus points for detecting parallel structure in the code and exposing it through alignment in the first place, but that's a much harder generalization of the problem. I'd settle for just leaving that to me and then not destroying it.)Bonus internet points for you today sir.
I do. I like being able to visually spot oddness in statements, and having a sequence of assignments, comparisons, etc lined up makes it easy to spot the lines that do something different.
I don't, and if I tried to, the code formatter would get rid of it anyway.