TypeVelo.
← Drills Hub

Python Typing Drill

: _ ( ) [ ] = . ' indentation

Every passage contains: : _ ( ) [ ] = . '

Net 0 wpmGross 0 wpmAcc 100%
def __init__(self, source): print(f'{name}: {count}') total = total + count return [line.strip() for line in f] return sorted(rows, key=lambda r: r[1]) if count > 0: self.source = source def read_rows(path): results = {'name': name, 'count': count} while queue and depth < limit: for key, value in items.items(): while queue and depth < limit: if count > 0: results = {'name': name, 'count': count} total = total + count print(f'{name}: {count}') return sorted(rows, key=lambda r: r[1]) for key, value in items.items(): total = total + count self.source = source values = [x * 2 for x in range(10)] if count > 0: values = [x * 2 for x in range(10)] return sorted(rows, key=lambda r: r[1]) except ValueError as err: return sorted(rows, key=lambda r: r[1]) def __init__(self, source): with open(path) as f: try: total = total + count except ValueError as err: class Reader: self.source = source with open(path) as f: self.source = source def __init__(self, source): total = total + count return [line.strip() for line in f] return [line.strip() for line in f] return [line.strip() for line in f]

QWERTY layout assumed. Backspace corrects; uncorrected errors count against net WPM.

def read_rows(path): ends in a colon, and the line beneath it, with open(path) as f:, is indented four spaces before a single visible character appears. Python's whole block structure runs on that pattern — a colon closing the line that opens a block, then leading whitespace on every line that belongs to it — rather than on the braces the other languages in this batch use. There's no symbol marking where the indentation should stop; a typist has to know, purely from remembering that the previous line ended in a colon, exactly how far to indent the next one.

That indentation compounds. with open(path) as f: is itself a line ending in a colon, so the line under it — return [line.strip() for line in f] — sits a further four spaces in, eight from the margin altogether. Nothing about the file marks that second jump visually until it's already been typed; getting it wrong doesn't just look odd, it changes which block a line belongs to.

Against that, Python's punctuation load is light. This drill's required set is colon, underscore, parentheses, brackets, an equals sign and a single quote — no braces, no semicolons, and no arrows. The one place punctuation gets dense is def __init__(self, source):, where the double underscore either side of init asks the right pinky for two shifted presses, a beat apart, followed later by two more closing out the same word. Several of these characters get a first, lighter introduction in the Symbols for Coders lesson; this drill is where the colon-and-indentation rhythm specific to Python gets the repeated practice a single guided lesson can't provide.

Why This Drill

Because nothing marks the correct indent depth except memory of the line before it, a wrong number of spaces here doesn't produce code that merely looks unusual — it produces code that means something different, or fails outright. That's a different failure mode from a language where a stray or missing brace is what breaks a block; in this passage, the punctuation is already all there and correct, and the error hides in whitespace that never even shows up as a character on screen.

The colon itself does two separate jobs inside this short passage, and telling them apart matters. def read_rows(path):, if count > 0:, for key, value in items.items(): and class Reader: all use it to open an indented block. return sorted(rows, key=lambda r: r[1]) uses the identical key for something else entirely — separating a lambda's arguments from its body — with no indent change following it at all. A typist who treats every colon as "indent the next line" will get this one wrong.

Four consecutive shifted right-pinky presses live inside __init__ alone — two before init, two after — a denser cluster of the same single motion than anywhere else in this short file. Beyond that pair of words, this passage is quieter on the fingers than most of its siblings in this batch: no line here ends in a semicolon, unlike the JavaScript Typing Drill's or the SQL Typing Drill's, where a trailing unshifted press closes out almost every statement. The Code Typing Test mixes several languages together if a broader measure is what's needed rather than one in isolation.

A Colon That Opens a Block, and a Colon That Doesn't

def, if, for, class, try and except all end their lines in a colon that starts a new indented block underneath. key=lambda r: r[1] uses the same key to separate a lambda's parameter from its expression, with no indentation change at all following it. The keystroke is identical either time; only the line's own shape says which job it's doing.

Four Spaces You Can't See Until You've Typed Them

with open(path) as f: sits four spaces in, under a def line ending in a colon. return [line.strip() for line in f] sits eight spaces in, under that with line's own colon. Neither jump is marked by a visible character — the whitespace has to be reproduced correctly from memory of what the line above it did, with no bracket or arrow to confirm the depth is right.

Two Shifted Reaches on Either Side of a Single Word

__init__ opens with two right-pinky presses under Shift, then the four letters of init typed plain, then two more shifted presses to close it out — four uses of the identical key inside one identifier, more than this drill's passage asks of any other single character.

A Line That Simply Stops

Unlike the JavaScript Typing Drill, where a line commonly ends in a semicolon, or the SQL Typing Drill, where nearly every statement does, none of this passage's lines close with a trailing mark at all. The line ends when the last letter or bracket does, and the next line starts wherever its own indentation says it should.

Frequently Asked Questions

Why does Python feel lighter on the fingers but harder to get exactly right?

The punctuation itself is sparse — a colon, some parentheses, an occasional bracket — but the leading whitespace on each line carries real meaning with no visible marker confirming it's correct, which shifts the difficulty from reach to memory.

Does every colon in this passage start a new indented block?

No. Most of them do — after def, if, for, class, try and except — but the colon inside key=lambda r: r[1] separates a lambda's argument from its body and doesn't change the indentation of anything that follows.

Why does __init__ need four separate underscore presses?

Two underscores open the name and two close it, and each underscore is its own Shift-plus-hyphen press on the right pinky, so the identifier packs four uses of that one motion into a single word.

Why doesn't any line in this drill's passage end with a semicolon?

Python doesn't use one to close a statement — the line simply ends. That's a genuine difference from several of this batch's other languages, where a trailing semicolon is part of nearly every line.

Is the indentation in this drill's passage spaces or tabs?

This drill's practice text uses spaces, four per level, which is the more common convention in Python code and the one this passage follows consistently.

Which of this batch's other languages makes the clearest contrast with Python's approach?

The JavaScript Typing Drill is the sharpest one — it marks every block with a brace rather than a colon and indent level, so there's always a visible character confirming where a block starts and ends, which Python's approach never provides.