Learn Practice Daily golf Reference
Real-world refactors·Lesson 6 of 6·9 min·0/5 exercisesPro

Comments and docs

Launch day: comment markers are a column (Ctrl-v and I to add them, a block and d to cut them), and gqip rewraps a paragraph.

Scene

Saturday, launch day, 8:00 a.m. One job left: the morning report script. The email line and the two below it have to go quiet for launch day (the kitchen's inbox is being moved), the two old lines above them come back for one day, and the README's main paragraph is a single line of 241 characters.

Comment markers are a column. Paragraphs are nouns.

From memory

Warm-up from earlier chapters

Two from earlier chapters, from memory, before the new idea. Two wrong tries show the answer.

Add ,USD to the end of this line and the next, different lengths.
press the keys…9 keys
1 of 2
Add ,USD to the end of this line and the next, different lengths.

Columns and paragraphs

Comment markers at the start of lines are a column, so the highlighter rectangle does them: Ctrl-v, down, I # Esc to add them, and a block two characters wide with d to cut them back out. Long prose is a paragraph, and gq is a verb that rewraps it: gqip wraps the paragraph you're in.

gq wraps at the textwidth setting. With none set, as here, Vim uses the window's width, at most 79 characters; set textwidth in your config (72 is common for commit messages) and gq follows it.

Before
email.send(to, report)
print("sent")
Ctrl-vjI# Esc
# email.send(to, report)
# print("sent")
A block over two lines, # in front of both: commented out.
Before
Short line,
another short line,
and a third.
gqip
Short line, another short line, and a third.
gq on the paragraph: the lines are refilled up to the wrap width (79 here), so these three become one.
Boss round

Stage 1 · Quiet

8:05. The three lines from email.send down go quiet: a block over the three of them and I # . The cursor is on the first one.

Fix the marked spots · 3 left
16import csv
15from collections import Counter
14
13
12def busiest_items(path: str, top: int = 3) -> list[tuple[str, int]]:
11 counts: Counter[str] = Counter()
10 with open(path) as f:
9 for row in csv.DictReader(f):
8 if row["status"] == "delivered":
7 counts[row["item"]] += int(row["qty"])
6 return counts.most_common(top)
5
4
3def send(report: str) -> None:
2# fax.send("305-555-0100", report)
1# pager.page("kitchen", "report sent")
17 email.send("kitchen@byteburrito.test", report)
1 print("sent")
2 log("report", len(report))
NORMALLoading the editor…0.0s17:1

This exercise needs a keyboard. Read on, and play it at your computer.

Boss round

Stage 2 · Back for a day

8:15. The fax and pager lines come back on: their # goes, and nothing else moves. The cursor is on the first one.

Stuck? Show a hint
Pro
The rest of this lesson is in Pro

The first exercise of every lesson is free. Pro unlocks the rest, every track, for good.

See Pro

This exercise needs a keyboard. Read on, and play it at your computer.

Boss round

Stage 3 · Wrapped

8:30. The README's first paragraph, wrapped: gqip from anywhere inside it. Then the paragraph under ## Options is just as long; wrap that one too.

Stuck? Show a hint
Pro
The rest of this lesson is in Pro

The first exercise of every lesson is free. Pro unlocks the rest, every track, for good.

See Pro

This exercise needs a keyboard. Read on, and play it at your computer.

LaunchFinish the exercise above to see it.
From memory

Launch week, from memory

Five tools from this week.

Put # in front of this line and the two below.
scroll here, then press the keys7 keys
1 of 5
Put # in front of this line and the two below.