Symbol Typing Test
Operators, punctuation and brackets — plus a reference for every symbol key
Symbols are the keys people type worst and understand least — half of them do not even have an agreed name. This page drills them, documents all thirty-two of them properly, and is honest about the ones this drill cannot produce at all.
What you will actually be typing
Short clusters of punctuation, generated fresh each run. Below is a captured run at each level, exactly as the generator produced it, with what that level measures underneath.
* =! $ & *? !% ?$ ! # # # &* &% #@ !% + = &?
?%; ?-& %*& +== +;& =:$ +#$ %#$ #$! !?! :*# /#- -&/ @;# !+= !=+ ;%: ;#*
!</(! +?:[ ;>?[{& $&&$& &--: <?${# )!{@> =;]= ;<&<># [&<)( ]{[) ]{-{ %]<)[; ]@?([ -(-% :@;>!: (@(![@ {{)/@{
These are not fragments of code and they are not meant to be. They are random draws from a character set, which is the point: with no syntax to recognise, nothing carries you through a cluster and every key has to be found on its own. What that costs you in realism, it buys back in isolating the reach.
Who this test is for
Programmers first, who type more punctuation than prose and pay for every hesitation on a brace. Then anyone whose text is dense with operators or delimiters: people writing spreadsheet formulas, building queries, editing configuration files, working in Markdown, or setting and retyping passwords full of special characters. And anyone who has noticed that their typing speed is respectable right up until a bracket appears.
It suits a specific diagnostic use too. Because it strips out letters and digits entirely, a poor score here is unambiguous — it is a Shift and reach problem, not a vocabulary or rhythm problem, and it points at a small number of keys you can fix directly.
| Durations | 30 seconds, 1 minute, 2 minutes or 5 minutes |
|---|---|
| Content | Generated clusters of operators, punctuation and brackets — no letters, no digits |
| Character set | 22 of the 32 punctuation characters on a US layout — the map below shows which |
| Mode | Word mode only. Each cluster is scored as its own unit |
| Scoring formula | Standard 5-keystroke word. Shift is not counted — a chord scores as the one character it produces |
| Backspace | Available by default. Worth disabling once accuracy holds, since a wrong bracket is rarely noticed |
| Shift load | 90.1% of characters on Easy, 71.4% on Medium, 72.7% on Hard |
| Cluster length | 1–2 characters on Easy, 3 on Medium, 4–6 on Hard |
| Layout assumed | US QWERTY. Other layouts place several of these characters differently |
| Repeat content | None. Clusters are generated fresh on every run |
| Report card | Speed and accuracy as usual, with a heatmap that has only punctuation to attribute errors to |
| Cost | No charge and no sign-in; the scoring never leaves the tab you are reading this in |
The difficulty levels are not a ladder
On every other drill here, each level is a harder version of the one before it. On this one that is not true, and the measurements say so plainly. Two of the three things that make symbols hard actually decrease as you move from Easy to Hard.
| Level | Needs Shift | Rows from home | On the number row | Row change | Length |
|---|---|---|---|---|---|
| Easy | 90.1% | 1.9 | 90% | 18% | 1.6 |
| Medium | 71.4% | 1.57 | 71.5% | 44.9% | 3 |
| Hard | 72.7% | 1.45 | 54.6% | 62.8% | 5 |
The explanation is in what each level draws from. Easy uses a curated list of ten common symbols, nine of which need Shift and nine of which sit on the number row — so it is almost pure Shift-chord practice on a single row, held at arm’s length from home. Medium and Hard draw on wider sets that include unshifted characters like -, =, /, ; and the square brackets, which dilutes the Shift load and, in Hard’s case, pulls characters down onto the top, home and bottom rows.
So Hard is harder in a different currency. Its clusters are longer, and its characters are scattered: the row-change rate between adjacent keystrokes climbs from 18% to 62.8%, the highest of any text on this site. Easy trains the chord. Hard trains the travel. Neither contains the other, and treating Easy as a warm-up for Hard will leave the Shift work under-practised.
Every punctuation key, and what it is for
Symbols are the only part of the keyboard where people genuinely do not agree on the names. The column below gives each character’s normative Unicode name alongside what people actually call it, because the two often differ and the official one is frequently a surprise — the forward slash is a solidus, the underscore is a low line, and the full stop is not called a period by the standard at all.
This assumes a US QWERTY layout. The characters are the same on every layout; the keys that produce them are not. Which Shift to hold is covered on the capitals and punctuation stage, which teaches the habit rather than listing it — the column here is a lookup for when you already know the rule and just need the key.
| Character | Name | Keystroke | Finger | Where it turns up | Slips into |
|---|---|---|---|---|---|
~ | TILDE | Shift + ` | Left pinky, right Shift | Home directory in a shell path, version ranges, bitwise NOT, CSS sibling selector | The backtick underneath it |
` | GRAVE ACCENT Backtick | Unshifted | Left pinky | Template literals, Markdown code spans, shell command substitution | An apostrophe — the single most confused pair on the board |
! | EXCLAMATION MARK Bang | Shift + 1 | Left pinky, right Shift | Logical NOT, not-equal operators, CSS !important | A bare 1 when Shift is released early |
@ | COMMERCIAL AT At sign | Shift + 2 | Left ring, right Shift | Email addresses, Python decorators, npm scopes, CSS at-rules | A 2 — or a quotation mark on a UK layout, where the two swap |
# | NUMBER SIGN Hash, pound, octothorpe | Shift + 3 | Left middle, right Shift | Comments in Python and shell, CSS IDs, hex colours, fragments in URLs | A 3 — and on a UK layout this key is £ instead |
$ | DOLLAR SIGN | Shift + 4 | Left index, right Shift | Currency, shell variables, end-of-string in regex, template interpolation | A 4 |
% | PERCENT SIGN | Shift + 5 | Left index, right Shift | Percentages, modulo, SQL LIKE wildcards, URL encoding, CSS units | A 5 |
^ | CIRCUMFLEX ACCENT Caret, hat | Shift + 6 | Right index, left Shift | Start-of-string in regex, exponent, XOR, caret version ranges | A 6 — the longest index-finger reach on the row, and the most missed |
& | AMPERSAND | Shift + 7 | Right index, left Shift | Logical AND, URL query separators, HTML entities, references in C++ | A 7 |
* | ASTERISK Star, splat | Shift + 8 | Right middle, left Shift | Multiplication, wildcards, pointers, Markdown emphasis, SQL select-all | An 8 |
( | LEFT PARENTHESIS Open paren, round bracket | Shift + 9 | Right ring, left Shift | Function calls and definitions, grouping in expressions and regex | A 9, or its closing partner |
) | RIGHT PARENTHESIS Close paren | Shift + 0 | Right pinky, left Shift | Closing a call or a group | A 0 — and left unbalanced more often than any other character |
- | HYPHEN-MINUS Hyphen, dash, minus | Unshifted | Right pinky | Subtraction, kebab-case names, command-line flags, date separators | An underscore, which shares the key |
_ | LOW LINE Underscore | Shift + - | Right pinky, left Shift | snake_case names, private members, SQL single-character wildcard | A hyphen when Shift does not land |
= | EQUALS SIGN | Unshifted | Right pinky | Assignment, comparison operators, HTML attributes, query strings | A hyphen, one key to its left |
+ | PLUS SIGN | Shift + = | Right pinky, left Shift | Addition, string concatenation, one-or-more in regex, CSS adjacent selector | An equals sign |
| Character | Name | Keystroke | Finger | Where it turns up | Slips into |
|---|---|---|---|---|---|
[ | LEFT SQUARE BRACKET Open bracket | Unshifted | Right pinky | Array indexing, list literals, optional parts in documentation | A brace, which shares the key |
] | RIGHT SQUARE BRACKET | Unshifted | Right pinky | Closing an index or a list | The opening bracket, when the pair is typed too fast |
{ | LEFT CURLY BRACKET Open brace | Shift + [ | Right pinky, left Shift | Code blocks, object literals, CSS rules, template placeholders | A square bracket when Shift is missed |
} | RIGHT CURLY BRACKET Close brace | Shift + ] | Right pinky, left Shift | Closing a block or an object | A square bracket, or the wrong one of the pair |
\ | REVERSE SOLIDUS Backslash | Unshifted | Right pinky | Escape sequences, Windows file paths, regex character classes | A forward slash — the two are constantly transposed |
| | VERTICAL LINE Pipe, bar | Shift + \ | Right pinky, left Shift | Logical OR, shell pipes, union types, Markdown tables | A backslash, or the letter l |
| Character | Name | Keystroke | Finger | Where it turns up | Slips into |
|---|---|---|---|---|---|
; | SEMICOLON | Unshifted | Right pinky (home key) | Statement terminator, CSS declaration separator | A colon — same key, and the meaning is usually incompatible |
: | COLON | Shift + ; | Right pinky, left Shift | Python block openers, object keys, CSS properties, type annotations, time | A semicolon when Shift does not land |
' | APOSTROPHE Single quote, tick | Unshifted | Right pinky | String literals, possessives and contractions | A backtick, or a smart quote inserted by a word processor |
" | QUOTATION MARK Double quote | Shift + ' | Right pinky, left Shift | String literals, JSON keys and values, HTML attribute values | A single quote — valid in some languages, fatal in JSON |
| Character | Name | Keystroke | Finger | Where it turns up | Slips into |
|---|---|---|---|---|---|
, | COMMA Comma | Unshifted | Right middle | Argument and list separators, thousands grouping, CSV fields | A full stop, one key to the right |
< | LESS-THAN SIGN Left angle bracket | Shift + , | Right middle, left Shift | Comparison, HTML and XML tags, generic type parameters | A comma, or its mirror image |
. | FULL STOP Period, dot, point | Unshifted | Right ring | Decimals, member access, file extensions, sentence endings | A comma |
> | GREATER-THAN SIGN Right angle bracket | Shift + . | Right ring, left Shift | Comparison, closing tags, CSS child combinator, shell redirection | A full stop, or the opening angle bracket |
/ | SOLIDUS Forward slash, stroke | Unshifted | Right pinky | Division, file and URL paths, closing HTML tags, regex delimiters, dates | A backslash |
? | QUESTION MARK | Shift + / | Right pinky, left Shift | Ternary operators, optional types, URL query strings, single-character wildcards | A forward slash when Shift is released early |
Read down the “slips into” column and a pattern emerges: almost every common symbol error is a Shift failure on a key you found correctly. You hit the right key and released Shift a fraction early, so ! came out as 1, : as ;, ? as /. That is a timing problem rather than a location problem, and it responds to slowing down by a few percent rather than to more repetition. The exceptions are the genuinely confused pairs — backtick against apostrophe, backslash against forward slash — where the fix is knowing which is which.
What this drill leaves out
The generator draws from a fixed list of 22 characters, which means ten of the thirty-two punctuation keys never appear. That is worth stating rather than hiding, because the omissions are not random and several of them matter a great deal.
We can put a figure on it. Measured across every coding corpus on this site — 320,341 characters of real source, which runs 17.69 punctuation marks per 100 characters — the symbols this drill can produce account for 69.5% of the punctuation that code is actually made of. The rest is missing here.
| Character | Name | Share of code punctuation | Where you would meet it |
|---|---|---|---|
" | Double quote | 9.3% | String literals, JSON keys and values, HTML attribute values |
. | Period, dot, point | 6% | Decimals, member access, file extensions, sentence endings |
, | Comma | 5.3% | Argument and list separators, thousands grouping, CSV fields |
_ | Underscore | 4.5% | snake_case names, private members, SQL single-character wildcard |
' | Single quote, tick | 3.9% | String literals, possessives and contractions |
| | Pipe, bar | 0.9% | Logical OR, shell pipes, union types, Markdown tables |
Together those characters carry 29.9% of the punctuation in that corpus, and the double quote alone is one of its most common characters of any kind. A drill that never produces a quotation mark is not a complete preparation for typing code, and we would rather say so here than let you find out later.
The gap runs the other way too
Several symbols this drill leans on barely exist in real code. In our corpus the percent sign does not appear once, and the at sign, the ampersand, the hash and the exclamation mark together account for well under one percent of punctuation — yet all five are in the ten-character Easy set. They are not useless characters; they are email, shell and password characters rather than code characters. If you are here for programming, Easy is the least relevant level on the page.
One limit on all of this: the corpus being measured is our own, eight languages of passages written for this site, and it leans towards markup and typed JavaScript. That is why the angle brackets rank so highly. It describes the code we wrote, not all code — but it is real code, measured rather than guessed, and the omissions it exposes would show up against any corpus.
How this is scored
The site formula applies unchanged: five keystrokes make a standard word, and a cluster earns credit only if every character in it is right. Two things about symbol text interact with that in ways worth knowing.
First, Shift is free. The score counts characters produced, not keys pressed, so a shifted symbol costs you two key presses and earns you one character. On Easy, where 90.1% of characters are shifted, you are doing close to twice the physical work per credited character that a prose test asks for. That alone explains much of the gap between your symbol speed and your normal speed, and it is not something to correct for — every typing assessment scores this way.
Second, the clusters are short. An Easy cluster averages 1.6 characters, so with the space that commits it, one attempt is 2.6 keystrokes against the five in a standard word — which makes a wrong cluster cost more than it contributed. That arithmetic is set out in detail over on the alpha-numeric drill, which runs into the same wall; the upshot here is that an Easy score is dominated by accuracy and tells you very little about pace.
Where to go next
This drill is narrow on purpose. It fixes individual keys, and it is deliberately not the place to build the patterns those keys appear in.
| Weak spot | Better drill for it | Reason |
|---|---|---|
| Quotes, commas, underscores — the ones missing above | Coding typing tests | Real source code, where those characters appear in the syntax that actually uses them |
| Symbols attached to digits, not on their own | Numbers test | Currency, decimals and date separators in context, with the hand parked on the number row |
| Shift on letters rather than on punctuation | Alpha-numeric test | Uppercase reference codes hold Shift across letters, which is a different coordination |
| You do not yet know which finger owns which symbol | Numbers and symbols stage | Teaches the assignments from scratch, with an on-screen keyboard, before you drill speed |
| Shift itself is the problem, on any key | Capitals and punctuation stage | Covers the opposite-hand Shift habit properly — this page assumes it rather than teaching it |
| Steady practice is not producing gains | How to type faster | Deals with how to structure practice at all, kept in one place rather than repeated here |
If you only do one thing after a run, read the heatmap and check whether your worst characters are shifted ones. If they are, the problem is the chord timing and Easy is where to work on it. If they are unshifted characters like the brackets and the slashes, it is location, and Hard is the level that drills it.
Frequently asked questions
Why is Easy the most Shift-heavy level?
Because of what each level draws from. Easy uses a hand-picked set of ten common symbols, and nine of them need Shift — so 90.1% of Easy characters are shifted, the highest figure of any drill on this site. Medium and Hard draw from wider sets that include unshifted characters like the hyphen, the equals sign, the forward slash and the square brackets, which pulls their Shift load down to 71.4% and 72.7%. It is not a mistake, but it does mean the levels are not a simple ladder, and the section above sets out what each one actually trains.
Which level should I actually use?
Pick by the problem rather than by the label. If Shift coordination is what slows you down, Easy loads it hardest and keeps everything on one row, so you drill the chord and nothing else. If you lose time hunting for brackets, use Hard — it is the only level that reaches the top and bottom rows in quantity, and the travel between rows is the thing it trains. Medium sits between the two and is the closest to a general test. Working upwards through all three in one session is reasonable; assuming Hard is simply a harder version of Easy is not.
Why does this drill never produce quotes, commas or underscores?
An honest answer: because the generator was built from a fixed list of symbols and those characters were not on it. We would rather show you the gap than quietly leave it. Measured against our own coding corpus, the characters this drill can produce account for 69.5% of the punctuation in real code, and the double quote alone — which never appears here — is one of the most common punctuation characters in that corpus. If you need those keys, the coding tests are where they occur in genuine syntax rather than as loose clusters.
Is this a good drill for programming?
Partly, and the measurement is worth knowing before you rely on it. Brackets, braces, angle brackets, the colon, the semicolon, the equals sign and the slash are all here, and between them they carry a large share of what code is made of. But the Easy set in particular is built from characters that barely appear in code at all — in our corpus the at sign, the ampersand and the percent sign are close to absent, and the percent sign does not occur even once. Those are password, shell and email characters. For code specifically, Hard is the level worth your time, and the coding tests are better still.
My keyboard is not a US layout and the symbols are somewhere else.
Then the reference table above is only partly right for you, and it says so at the top. The characters themselves are identical everywhere — a colon is a colon — but which key produces them, and whether Shift or AltGr is involved, varies by layout. On a UK layout the at sign and the double quote swap places, and the hash key is replaced by the pound sign. Several European layouts put the braces and the backslash behind AltGr entirely, which makes them a genuinely two-handed reach rather than a Shift chord. The drill is still useful; the finger column is what needs translating.
Does the test count Shift as a keystroke?
No. Scoring counts the characters that arrive, so Shift plus 4 registers as one character — the dollar sign — exactly as it would in any document. That is the same convention every typing assessment uses, and it is worth understanding because it means symbol text is scored as though it were half as much work as it really is: you press two keys and are credited with one. It is one reason symbol speed reads so much lower than plain-text speed.
Why is my symbol speed so far below my normal typing speed?
Three costs stack up, and none of them apply to letters. Nearly every character is a two-key chord instead of one press, and the score credits you for one. The keys are far out — Easy averages 1.9 rows away from the resting position, where prose averages 0.68. And there is no momentum: fluent typing depends on your fingers running slightly ahead of your eyes, which only works when the next character is guessable, and in a random cluster it never is. A large gap between this score and your prose score is expected, not a sign of bad technique.
Should I practise brackets as pairs?
For real work, yes — typing an opening bracket and its closing partner together and then moving the cursor back is how most fluent programmers avoid unbalanced pairs, and most editors will do it for you. This drill deliberately does not let you, because its tokens are random clusters rather than valid syntax, so the pairs it produces are frequently mismatched. What you can usefully drill here is the individual reach to each of the six bracket characters. The pairing habit belongs in an editor, on real code.
How is this different from the numbers and alpha-numeric drills?
They stress different mechanics even though they look related. The numbers drill parks the hand on one row and barely uses Shift at all. The alpha-numeric drill alternates between letters and digits, so the hand crosses rows constantly. This drill loads Shift above everything else, and at Hard it also spreads characters across all four rows — its row-change rate reaches 62.8%, the highest of the three. If you have taken all three and one felt far worse than the others, that tells you which mechanic to work on.
The tokens look like nothing I would ever type. Is that a problem?
It is a real trade-off and worth being clear about. Random clusters strip away every clue — no syntax, no muscle memory for a familiar sequence, no way to guess what comes next — which isolates the reach and the Shift chord better than realistic text ever could. What they cannot train is the rhythm of punctuation in context, where symbols come in familiar shapes and your hands learn whole patterns rather than single keys. Use this drill to fix the individual keys, and a coding or general test to put them back into something that reads like real work.
Sources and method
The character names in the reference table are the normative Unicode names, read directly from the Unicode Character Database rather than from any secondary list. Where a character has a widely used everyday name that differs, both are given — the standard is authoritative about what a character is, not about what people call it in conversation.
The keystroke and finger columns describe a US QWERTY layout and the finger assignments conventionally taught for it. No standards body publishes those assignments, and other layouts place several of these characters elsewhere, so treat that pair of columns as a well-established convention rather than a specification. Uses and common slips are drawn from where these characters appear in programming, markup and everyday text; they are editorial judgements, not measurements, and are presented as such.
Everything numeric is measured. The drill’s Shift load, cluster length, row placement and row-change rates come from scripts/token-stats.mjs, which reproduces the engine’s generator and samples 500,000 clusters per level from a fixed seed at build time. The coverage figures compare that character set against punctuation counted across our own coding corpora — 320,341 characters of source we wrote for this site. That corpus is ours and leans towards markup and typed JavaScript, which is stated in the section itself rather than buried here.
- Unicode Character Database — UnicodeData.txt, the normative character names for U+0021 to U+007EThe Unicode Consortium · link checked 4 Sept 2026