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

Extract the numbers

Launch week, Wednesday: magic numbers into one CONFIG. Ranged slips that skip the config line, patterns that match a number only where it stands on its own, and qaq then :g/note:/d A to move lines into an emptied jar.

Scene

Wednesday of launch week, 9:00 a.m. The tax rate, the rush fee and the delivery radius are typed straight into the pricing code, again and again: 0.0875, 1.5, 8. Burrito 2.0 opens in a second city next month, with different numbers, so they go into one CONFIG object today.

The trick is changing every copy of a number except the one in the config itself.

From memory

Warm-up from earlier chapters

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

To the next match of your search, and repeat the last change there.
press the keys…2 keys
1 of 2
To the next match of your search, and repeat the last change there.

Everywhere but the first line

Write the config on line 1, then send the replacements with a range that starts below it: :2,$s/0\.0875/CONFIG.tax/g. The dot needs its backslash (it's a pattern), and \< \> keep 8 from matching inside 18 or 0.0875. One careful slip per number.

Before
const CONFIG = { tax: 0.0875 };
return amount * 0.0875;
const tax = subtotal * 0.0875;
:2,$s/0\.0875/CONFIG.tax/g↵
const CONFIG = { tax: 0.0875 };
return amount * CONFIG.tax;
const tax = subtotal * CONFIG.tax;
From line 2 to the end: the config line keeps its number, every copy below gets the name.
Check yourself

The whole file?

1const CONFIG = { tax: 0.0875, rushFee: 1.5, maxKm: 8 };
1
2if (km > 8) throw new Error("too far");
NORMAL
Keys pressed: :%s/\<8\>/CONFIG.maxKm/g↵

The config line is written. You send the radius slip to the whole file, %, instead of 2,$. What does line 1 say now?

Pick an answer (or press its number), then watch the engine prove it.
Boss round

Stage 1 · The config line

9:10. Open a line above the first and write the config, followed by a blank line: const CONFIG = { tax: 0.0875, rushFee: 1.5, maxKm: 8 };

Fix the marked spots · 2 left
+const CONFIG = { tax: 0.0875, rushFee: 1.5, maxKm: 8 };
+
1// note: tax is the city's sales tax
1export function taxFor(amount: number) {
2 return amount * 0.0875;
3}
4
5// note: no deliveries past the radius
6export function deliveryFee(km: number, rush: boolean) {
7 if (km > 8) throw new Error("too far");
8 return (km > 2 ? (km - 2) * 0.4 : 0) + (rush ? 1.5 : 0);
9}
10
11// note: the rush fee applies from noon to two
12export function quote(subtotal: number, km: number, rush: boolean) {
13 const tax = subtotal * 0.0875;
14 const fee = km > 8 ? 0 : deliveryFee(km, rush);
15 const etaMin = 18 + km * 3;
16 return { total: subtotal + tax + fee, rushFee: rush ? 1.5 : 0, etaMin };
17}
NORMALLoading the editor…0.0s1:1

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

Boss round

Stage 2 · Names instead of numbers

9:30. Below the config, every 0.0875 becomes CONFIG.tax, every 1.5 CONFIG.rushFee, and every 8 CONFIG.maxKm. The config line keeps its numbers, and the kitchen's 18 minutes in etaMin isn't the radius: it stays.

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 · The notes under the config

10:00. The // note: lines above the functions belong with the numbers, right under the config line. Jar a isn't empty: it still holds the config line you copied into it at 9:10 for the team chat. Empty it with qaq (a recording of nothing), move the notes into it in one slip, :g/note:/d A (a capital label adds each line to the jar, and d takes it out of the code), then pour the jar under the config line. A jar emptied with qaq pours a blank line first: that's the gap under the config.

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.

From memory

Extracting, from memory

Press the keys.

Replace every order with ticket from line 2 to the end.
scroll here, then press the keys21 keys
1 of 3
Replace every order with ticket from line 2 to the end.