From 8fc4440150ce84c9cc3f5ec13d50beb58a5b65bc Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Sun, 7 Dec 2025 21:58:00 +0200 Subject: Rebuild the generic packs, add shell and sysadmin, fix short race passages The packs were not proper. An audit found 86 of 253 items (33%) carrying an attribution that just restated the category - prose *about* a topic with an invented source, which is the same fault the movies pack had. Six of thirteen packs were mostly that: technology had 15 items and one distinct attribution. - science, technology, history, nature and business are now sourced quotes with real attributions: Feynman, Curie, Hopper, Dijkstra, Lincoln, Carson, Drucker, Goodhart. 82 items, all attributed to a person or a work. - general is original factual prose, so it now carries no attribution at all rather than claiming "General knowledge" as a source. merge_packs no longer invents one from the pack's filename. - Four explanatory passages in philosophy lost their "Philosophy" attribution for the same reason. - One duplicated passage removed. Generic attributions: 86/253 before, 0/349 now. New technical packs - shell: 24 awk, sed and pipeline drills, each explaining what the line does - field splitting, associative arrays, !seen[$0]++, process substitution, xargs -0, strict mode. - sysadmin: 24 operational one-liners across systemd, disk, processes, network, permissions, SSH, backup and containers. - programming grew to 37 and hacking to 30, with git bisect, window functions, EXPLAIN ANALYZE, certificate transparency and capability audits. - All 115 technical drills carry an explanation. Race passage length - Multiplayer drew from the same pool as single player, so a race could land on a 22-character quote and be over before anyone had their hands in position. Races now require 120 characters; the filter is applied when the pool is loaded, not to the packs, since a short quote is fine to type alone. For reference, TypeRacer organises by difficulty and language rather than topic: one default English pool of ~11,900 texts plus per-language universes and specials (accuracy, repeat, easytexts, anime). Their scale comes from user submission with moderation, which is still the feature this does not have. --- data/packs/programming.json | 77 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'data/packs/programming.json') diff --git a/data/packs/programming.json b/data/packs/programming.json index fae99c2..e0bcd72 100644 --- a/data/packs/programming.json +++ b/data/packs/programming.json @@ -180,5 +180,82 @@ "attribution": "Shell", "content": "export PATH=\"$HOME/.local/bin:$PATH\" && command -v rg >/dev/null || echo missing", "explanation": "Prepending puts your own binaries ahead of the system ones. command -v is the portable test for whether something is installed." + }, + { + "category": "programming", + "language": "shell", + "attribution": "Git", + "explanation": "Finds the commit that introduced a bug by bisecting history. Give it a known-good and known-bad commit and it halves the range each step.", + "content": "git bisect start HEAD v1.2.0 && git bisect run ./test.sh" + }, + { + "category": "programming", + "language": "shell", + "attribution": "Git", + "explanation": "Who last touched each line of a range, which is how you find the person to ask rather than the person to blame.", + "content": "git log -L 40,60:src/parser.rs --oneline" + }, + { + "category": "programming", + "language": "shell", + "attribution": "Git", + "explanation": "Recovers commits that are no longer reachable from any branch. A hard reset does not destroy them; it just stops pointing at them.", + "content": "git reflog --date=iso | head -20" + }, + { + "category": "programming", + "language": "python", + "attribution": "Python", + "explanation": "zip pairs two sequences and stops at the shorter one. strict=True makes a length mismatch an error rather than silent truncation.", + "content": "for name, score in zip(names, scores, strict=True): print(f'{name}: {score:>5.1f}')" + }, + { + "category": "programming", + "language": "python", + "attribution": "Python", + "explanation": "defaultdict removes the exists-check before every append, which is the most common shape of a grouping loop.", + "content": "groups = defaultdict(list); [groups[w[0]].append(w) for w in words]" + }, + { + "category": "programming", + "language": "javascript", + "attribution": "JavaScript", + "explanation": "?? falls back only on null or undefined, unlike ||, which also fires on 0 and the empty string.", + "content": "const port = config.port ?? process.env.PORT ?? 8080;" + }, + { + "category": "programming", + "language": "javascript", + "attribution": "JavaScript", + "explanation": "Promise.all runs them concurrently and rejects on the first failure; allSettled waits for every result instead.", + "content": "const [user, posts] = await Promise.all([getUser(id), getPosts(id)]);" + }, + { + "category": "programming", + "language": "rust", + "attribution": "Rust", + "explanation": "The ? operator returns early on Err, converting the error type through From. It is what keeps error handling from nesting.", + "content": "let config: Config = toml::from_str(&fs::read_to_string(path)?)?;" + }, + { + "category": "programming", + "language": "rust", + "attribution": "Rust", + "explanation": "entry().or_insert_with() looks the key up once. The obvious contains_key-then-insert hashes it twice.", + "content": "*counts.entry(word).or_insert(0) += 1;" + }, + { + "category": "programming", + "language": "clike", + "attribution": "SQL", + "explanation": "A window function ranks rows within each partition without collapsing them, which a GROUP BY cannot do.", + "content": "SELECT user_id, wpm, RANK() OVER (PARTITION BY mode ORDER BY wpm DESC) AS rank FROM results;" + }, + { + "category": "programming", + "language": "clike", + "attribution": "SQL", + "explanation": "EXPLAIN ANALYZE runs the query and reports what the planner actually did, not what it guessed it would do.", + "content": "EXPLAIN ANALYZE SELECT * FROM test_results WHERE mode_key = 'time-30' ORDER BY wpm DESC LIMIT 50;" } ] \ No newline at end of file -- cgit v1.2.3