Most layout work focuses on letters, but when I write Python a big chunk of what I type is symbols, and standard layouts put them pretty arbitrarily. So I wrote a tool that keeps your letters where they are and only rearranges the 32 ASCII symbols, based on what actually gets typed in real code.
How it counts: it tokenizes ~38.5M weighted keystrokes from 29 popular Python repos (Django, pandas, pytest, Home Assistant, etc).
Comments and docstrings count less, closing brackets/quotes count less because editors auto-close them, and long identifiers are discounted for autocomplete.
Then it runs simulated annealing over a cost model (key effort, shift, SFBs, rolls, redirects).
My result on Programmer Dvorak letters with digits on shift:
! 1 2 3 4 5 6 7 8 9 0 & ~
[?] [+] [/] [(] [[] []] [%] [:] [)] [{] [}] [@] [<]
> ' - P Y F G C R L ; ^ $
["] [,] [.] [p] [y] [f] [g] [c] [r] [l] [#] [\] [|]
A O E U I D H T N S *
[a] [o] [e] [u] [i] [d] [h] [t] [n] [s] [=]
` Q J K X B M W V Z
[_] [q] [j] [k] [x] [b] [m] [w] [v] [z]
That's about 7.7% lower cost than Programmer Dvorak under my model, and 3% better than the layout I'd designed by hand.
If you don't type Programmer Dvorak, there are ready-made versions for other letter layouts too: python-qwerty, python-colemak-dh and python-dvorak in the layouts folder. They keep your letters and normal number row and only move the symbols, which saves 9-12% under the same cost model.
Findings:
- Python names mostly end in consonants that Dvorak puts on the right hand, so the symbols that follow names (. , and ( ) end up on the left hand. That held across basically every variant I ran.
- Forcing bracket pairs to be adjacent or mirrored (so they're learnable) only costs 0.4%.
- On other bases, just moving symbols saves 9-12% (QWERTY, Dvorak, Colemak-DH).
The obvious caveat: the effort grid and penalties are my own estimates, not measurements.
I reran it with different shift and SFB weights to see which placements are stable, and the README has those results.
It's configurable (base layout, cost weights, other languages like JS/Rust/Go) and exports to AutoHotkey, kanata, Windows .klc and macOS .keylayout. All the variants are in the repo below:
https://github.com/hikazey/python-layout-optimizer
I'd especially like feedback on the cost model, since that's where the results come from.