# ⌨️ [Dygma Defy](https://dygma.com/pages/defy) w/ [Kailh speed copper switches]([https://www.kailh.net/products/kailh-speed-switch-set?variant=43775890555122](https://dygma.com/products/switches?variant=43658510270702)) and [dashed keys](https://dygma.com/products/keycaps?variant=43658946314478) The [reasoning behind my choice of keyboard](https://snarky.ca/the-many-shapes-and-sizes-of-keyboards/). # Layout - I'm using [Colemak Mod-DH](https://colemakmods.github.io/mod-dh/) for alpha keys - Motivation is ergonomics - Choice based on perceived popularity (alt keyboard layouts are all so much better than QWERTY that the benefits between them is miniscule; [validated for myself](https://github.com/brettcannon/defy-layout-scorer)) ## To try - [Canary](https://github.com/Apsu/Canary) - [Gallium](https://github.com/GalileoBlues/Gallium) ``` # - ) ] ! : _ ( [ = * \ / < > ``` # Alternatives - Traditional - [Raise 2](https://dygma.com/pages/dygma-raise-2) - [Matias Ergo Pro](https://matias.store/products/fk403qpc-p) - Columnar - [Moonlander](https://www.zsa.io/moonlander) - Concave - [Advantage 360 Pro](https://kinesis-ergo.com/shop/adv360pro/) # Symbol frequency | Python | Rust | Gleam | | ------ | ---- | ----- | | _ | _ | / | | . | / | ) | | ( | : | ( | | ) | ( | , | | , | ) | " | | ' | , | . | | " | . | _ | | = | " | `` | | : | = | = | | - | { | > | | # | } | - | | \ | ; | : | | [ | ? | [ | | ] | - | { | | > | ` | } | | * | [ | ] | | / | ] | # | | { | # | < | | } | < | \| | | + | ! | \ | | 2x | 1.5x | 1.0x | | ----- | ---- | ----- | | ( | ( | ==)== | | ) | ) | ==(== | | _ | _ | _ | | , | , | , | | . | . | . | | " | " | " | | : | : | : | | = | = | = | | ' | ' | ==`== | | - | - | ==>== | | > | > | =='== | | ` | ` | ==-== | | ==#== | { | { | | ==[== | } | } | | ==]== | [ | [ | | =={== | ] | ] | | ==}== | # | # | | ; | ; | ; | | ==\== | < | < | | < | \ | \ | 1. ( 2. ) 3. \_/- 4. : 5. =/+ 6. \[/{ 7. ]/} 8. # 9. \` 10. \ ### 2x multiplier ``` Symbol Importance Ranking (Python multiplier: 2.0) ================================================================================ 1. '(' - Total: 6.7370 2. ')' - Total: 6.7360 3. '_' - Total: 6.6910 4. ',' - Total: 5.9660 5. '.' - Total: 5.6040 6. '"' - Total: 3.8880 7. ':' - Total: 3.3460 8. '=' - Total: 2.9150 9. ''' - Total: 2.5420 10. '0' - Total: 2.0410 11. '1' - Total: 1.8620 12. '-' - Total: 1.7170 13. '>' - Total: 1.5290 14. '`' - Total: 1.4270 15. '2' - Total: 1.3920 16. '#' - Total: 1.2460 17. '[' - Total: 1.2230 18. ']' - Total: 1.2180 19. '{' - Total: 1.1800 20. '}' - Total: 1.1800 21. '3' - Total: 0.8040 22. '4' - Total: 0.6480 23. ';' - Total: 0.5960 24. '\\' - Total: 0.5850 25. '<' - Total: 0.5580 26. '5' - Total: 0.5320 27. '6' - Total: 0.5230 28. '8' - Total: 0.4530 29. '/' - Total: 0.4320 30. '*' - Total: 0.3530 31. '|' - Total: 0.3030 32. '9' - Total: 0.2860 33. '!' - Total: 0.2800 34. '7' - Total: 0.2680 35. '&' - Total: 0.2540 36. '+' - Total: 0.2110 37. '@' - Total: 0.1810 38. '%' - Total: 0.1210 39. '?' - Total: 0.0910 40. '^' - Total: 0.0650 41. ' - Total: 0.0600 42. '~' - Total: 0.0580 ``` ### 1.5x multiplier ``` Symbol Importance Ranking (Python multiplier: 1.5) ================================================================================ 1. '(' - Total: 5.9570 2. ')' - Total: 5.9565 3. '_' - Total: 5.8435 4. ',' - Total: 5.2955 5. '.' - Total: 4.8090 6. '"' - Total: 3.4860 7. ':' - Total: 2.9925 8. '=' - Total: 2.5490 9. ''' - Total: 1.9625 10. '0' - Total: 1.7455 11. '1' - Total: 1.6725 12. '-' - Total: 1.5370 13. '>' - Total: 1.4570 14. '`' - Total: 1.4180 15. '2' - Total: 1.2545 16. '{' - Total: 1.1430 17. '}' - Total: 1.1430 18. '[' - Total: 1.1210 19. ']' - Total: 1.1165 20. '#' - Total: 0.9345 21. '3' - Total: 0.7300 22. '4' - Total: 0.5855 23. ';' - Total: 0.5815 24. '<' - Total: 0.5345 25. '\\' - Total: 0.4805 26. '6' - Total: 0.4790 27. '5' - Total: 0.4770 28. '8' - Total: 0.4080 29. '|' - Total: 0.2915 30. '*' - Total: 0.2885 31. '!' - Total: 0.2700 32. '&' - Total: 0.2500 33. '9' - Total: 0.2470 34. '/' - Total: 0.2430 35. '7' - Total: 0.2365 36. '+' - Total: 0.1755 37. '@' - Total: 0.1650 38. '%' - Total: 0.0955 39. '?' - Total: 0.0810 40. '^' - Total: 0.0610 41. ' - Total: 0.0575 42. '~' - Total: 0.0550 ``` ### 1.0x multiplier ``` Symbol Importance Ranking (Python multiplier: 1.0) ================================================================================ 1. ')' - Total: 5.1770 2. '(' - Total: 5.1770 3. '_' - Total: 4.9960 4. ',' - Total: 4.6250 5. '.' - Total: 4.0140 6. '"' - Total: 3.0840 7. ':' - Total: 2.6390 8. '=' - Total: 2.1830 9. '1' - Total: 1.4830 10. '0' - Total: 1.4500 11. '`' - Total: 1.4090 12. '>' - Total: 1.3850 13. ''' - Total: 1.3830 14. '-' - Total: 1.3570 15. '2' - Total: 1.1170 16. '{' - Total: 1.1060 17. '}' - Total: 1.1060 18. '[' - Total: 1.0190 19. ']' - Total: 1.0150 20. '3' - Total: 0.6560 21. '#' - Total: 0.6230 22. ';' - Total: 0.5670 23. '4' - Total: 0.5230 24. '<' - Total: 0.5110 25. '6' - Total: 0.4350 26. '5' - Total: 0.4220 27. '\\' - Total: 0.3760 28. '8' - Total: 0.3630 29. '|' - Total: 0.2800 30. '!' - Total: 0.2600 31. '&' - Total: 0.2460 32. '*' - Total: 0.2240 33. '9' - Total: 0.2080 34. '7' - Total: 0.2050 35. '@' - Total: 0.1490 36. '+' - Total: 0.1400 37. '/' - Total: 0.1080 38. '?' - Total: 0.0710 39. '%' - Total: 0.0700 40. '^' - Total: 0.0570 41. ' - Total: 0.0550 42. '~' - Total: 0.0520 ``` # N-grams `assert` is consistently one of the top n-grams. - ... - `) -> ` (0.7K + 31.9K)* - `/// // -> ` (0.5K) - `) => {` (9.8K) - a - `assert` - `assert ` - b - Brett* - c - `class ` (4K) - `case ` (0.2K) - `crate::` (7.8K)* - d - `def __init__(self` (1.4K) - `def ` (21K)* - `#[derive(` (5.4K)~ - e - `except ` (3.4K) - `@external(` (0.2) - `Error` (0.3K) - `} else {` (7.5K)* - f - `feature =` (5.2K)~ - `for ` (13K + 27K)* - g - `gleam` (0.8K)* - h - i - `__init__(` (1.4K) - `isinstance(` (2.2K) - `is not None` (2.3K) - `import ` (6.3K)* - ` is not ` (3.5K) - j - k - `Kind::` (21K) - l - `List(` (0.4K) - `let Some(` (6.4K) - `let mut ` (9.1K) - `let ` (63.4K)* - m - `match `* - n - `None` (16K)* - `NULL` (38K) - o - `Option<` (7.6K) - p - `pub fn ` (0.4K + 10.5K) - `pub ` (21.3K) - `PyObject *` (30.9K) - `PyObject` (38K) - Python* - q - r: - `return self` (3K) - `return ` (21K + 8.7K + 43K)* - `Result` (9.6K) - s - ` = self.` (7K +10.3K) - `self.` (48K + 54.4K)~ - `self` (66K + 95K)* - `string` (0.5K) - `String` (0.3K) - `self) ->` (8.6K) - `&mut self` (8.5K) - t - `type ` - `True` - `true` - u - `use crate::` (5.3K)~ - `use ` (28.8K)* - v - ValueError (1.8K) - w - `with ` - `while ` - x - y - `yield `* - z ## Python ``` ➲ py n-grams.py ~/Repositories/python/cpython/**/*.py Top 20 4-grams: 'self': 66,304 'elf.': 47,675 'the ': 27,312 'tion': 25,604 'name': 24,709 'turn': 23,794 'etur': 23,731 'retu': 21,322 '(sel': 21,247 'def ': 21,156 'urn ': 20,002 'lf._': 16,869 'None': 16,393 'ing ': 14,435 'file': 13,902 'for ': 13,183 'not ': 12,882 'rror': 12,475 'line': 12,294 'and ': 11,775 Top 20 5-grams: 'self.': 47,661 'eturn': 23,702 'retur': 21,322 '(self': 21,208 'turn ': 19,975 'elf._': 16,869 'self,': 9,605 'elf, ': 9,397 'Error': 8,843 'ction': 8,793 'value': 8,738 'class': 8,130 'mport': 7,798 'port ': 7,279 'impor': 7,264 'self)': 7,263 '= sel': 7,083 'def _': 7,024 'ation': 6,973 'tion ': 6,973 Top 20 6-grams: 'return': 21,322 'eturn ': 19,934 'self._': 16,867 'self, ': 9,387 '(self,': 9,218 'import': 7,264 '= self': 7,010 '(self)': 6,934 'mport ': 6,324 'self):': 5,302 'except': 5,257 'string': 5,154 'raise ': 5,025 '(self.': 4,988 'n self': 4,352 'eError': 4,282 'module': 4,268 'class ': 4,258 'object': 4,225 's not ': 4,152 Top 20 7-grams: 'return ': 18,235 '(self, ': 9,135 '= self.': 6,850 'import ': 6,296 '(self):': 5,286 'n self.': 3,942 'eturn s': 3,928 'default': 3,879 'if not ': 3,877 'nstance': 3,623 'if self': 3,603 'instanc': 3,526 'f self.': 3,526 '__(self': 3,495 'is not ': 3,492 'except ': 3,442 'ilename': 3,361 'filenam': 3,330 'turn se': 3,165 'urn sel': 3,115 Top 20 8-grams: 'return s': 3,889 'instance': 3,526 'if self.': 3,494 'filename': 3,330 'eturn se': 3,165 'turn sel': 3,115 'urn self': 3,093 '.append(': 2,859 'rn self.': 2,805 'argument': 2,643 'function': 2,614 'xception': 2,466 'not None': 2,312 'is not N': 2,297 's not No': 2,295 'nstance(': 2,273 '__(self,': 2,273 '_(self, ': 2,250 'isinstan': 2,234 'sinstanc': 2,234 Top 20 9-grams: 'return se': 3,147 'eturn sel': 3,115 'turn self': 3,093 'urn self.': 2,805 'is not No': 2,294 's not Non': 2,290 '__(self, ': 2,243 'instance(': 2,240 'isinstanc': 2,234 'sinstance': 2,234 '__init__(': 1,869 'ValueErro': 1,862 'alueError': 1,862 'not None:': 1,677 'it__(self': 1,657 '_init__(s': 1,576 'init__(se': 1,573 'nit__(sel': 1,570 'exception': 1,565 't__(self,': 1,555 Top 20 10-grams: 'return sel': 3,103 'eturn self': 3,093 'turn self.': 2,805 's not None': 2,290 'is not Non': 2,289 'isinstance': 2,234 'sinstance(': 2,208 'ValueError': 1,862 '_init__(se': 1,573 'init__(sel': 1,570 'nit__(self': 1,569 '__init__(s': 1,554 't__(self, ': 1,528 'self.asser': 1,490 'elf.assert': 1,490 'it__(self,': 1,460 'urn self._': 1,452 'def __init': 1,356 'ef __init_': 1,355 'f __init__': 1,347 ``` ## Gleam ``` ➲ py n-grams.py data/gleam-1.13.0/**/*.gleam data/gleam_stdlib-0.67.0/**/*.gleam Top 20 4-grams: 'ring': 877 'trin': 864 'leam': 832 'glea': 803 ') ->': 724 'list': 669 'code': 605 'tion': 580 'ist(': 528 'stri': 525 'pub ': 518 '/ ->': 518 'ing ': 505 'ecod': 489 'ub f': 452 'b fn': 452 'List': 447 'rror': 407 'deco': 367 'Stri': 352 Top 20 5-grams: 'tring': 864 'gleam': 803 'strin': 512 'ecode': 475 'pub f': 452 'ub fn': 452 'List(': 442 'decod': 367 'Strin': 352 'first': 314 'esult': 306 'value': 294 'case ': 286 'Error': 274 'mples': 269 'terna': 244 ': Lis': 240 'eturn': 237 'tion ': 234 'ernal': 233 Top 20 6-grams: 'string': 512 'pub fn': 452 'ub fn ': 452 'decode': 355 'String': 352 ': List': 240 'ternal': 233 'extern': 230 'xterna': 230 '@exter': 229 'ernal(': 229 '_loop(': 228 'ecoder': 222 'List(a': 218 'ist(a)': 215 'Error(': 201 'ynamic': 179 '_strin': 176 'gleam_': 161 'leam_s': 161 Top 20 7-grams: 'pub fn ': 452 ': List(': 240 'externa': 230 'xternal': 230 '@extern': 229 'ternal(': 229 'List(a)': 215 '_string': 176 'gleam_s': 161 'leam_st': 161 'eam_std': 161 'am_stdl': 161 'm_stdli': 161 '_stdlib': 161 ': Strin': 151 'decoder': 146 'eturns ': 135 'decode.': 135 '(erlang': 132 'rlang, ': 129 Top 20 8-grams: 'external': 230 '@externa': 229 'xternal(': 229 'gleam_st': 161 'leam_std': 161 'eam_stdl': 161 'am_stdli': 161 'm_stdlib': 161 ': String': 151 'ternal(e': 127 'ernal(er': 127 'rnal(erl': 127 'nal(erla': 127 'al(erlan': 127 'l(erlang': 127 '(erlang,': 127 'erlang, ': 127 'rlang, "': 127 ': List(a': 122 '(javascr': 107 Top 20 9-grams: '@external': 229 'external(': 229 'gleam_std': 161 'leam_stdl': 161 'eam_stdli': 161 'am_stdlib': 161 'xternal(e': 127 'ternal(er': 127 'ernal(erl': 127 'rnal(erla': 127 'nal(erlan': 127 'al(erlang': 127 'l(erlang,': 127 '(erlang, ': 127 'erlang, "': 127 ': List(a)': 121 '(javascri': 107 'javascrip': 107 'avascript': 107 'xternal(j': 102 Top 20 10-grams: '@external(': 229 'gleam_stdl': 161 'leam_stdli': 161 'eam_stdlib': 161 'external(e': 127 'xternal(er': 127 'ternal(erl': 127 'ernal(erla': 127 'rnal(erlan': 127 'nal(erlang': 127 'al(erlang,': 127 'l(erlang, ': 127 '(erlang, "': 127 '(javascrip': 107 'javascript': 107 'external(j': 102 'xternal(ja': 102 'ternal(jav': 102 'ernal(java': 102 'rnal(javas': 102 ``` ## Rust ``` ➲ py n-grams.py data/rust-1.91.1/compiler/**/*.rs data/rust-1.91.1/library/std/**/*.rs Top 20 4-grams: 'self': 95,111 'tion': 72,013 'let ': 68,391 'the ': 62,205 'elf.': 54,411 'span': 40,429 'able': 32,859 'mut ': 31,999 ') ->': 31,980 'type': 30,070 'ing ': 29,861 'atio': 28,828 'use ': 28,815 'pub ': 28,308 "'tcx": 27,593 'onst': 27,556 'rate': 27,459 'Kind': 25,713 'for ': 25,685 'impl': 24,313 Top 20 5-grams: 'self.': 54,399 'ation': 28,813 "'tcx>": 23,147 "<'tcx": 23,089 'ind::': 21,145 'Kind:': 21,068 'crate': 20,599 'Some(': 20,167 'self,': 20,126 'const': 19,450 '&mut ': 19,223 'table': 17,733 'eturn': 17,491 'match': 17,346 'arget': 17,263 'elf, ': 16,048 'def_i': 15,547 'ef_id': 15,504 '&self': 15,387 'ction': 15,343 Top 20 6-grams: 'Kind::': 21,059 "<'tcx>": 20,595 'self, ': 15,646 'def_id': 15,459 'return': 14,483 'rustc_': 13,662 'struct': 13,344 'target': 12,563 'match ': 12,199 '(&self': 12,044 'eature': 11,312 '= self': 11,049 'featur': 10,609 '" => "': 10,521 'pub fn': 10,495 'ub fn ': 10,470 'eneric': 10,164 'assert': 10,041 ') => {': 9,824 'Result': 9,625 Top 20 7-grams: 'feature': 10,609 '" => "_': 10,490 'pub fn ': 10,470 '= self.': 10,302 'let mut': 9,189 'et mut ': 9,111 '} else ': 9,040 'e rustc': 8,960 'se rust': 8,817 'use rus': 8,812 'lf) -> ': 8,811 'elf) ->': 8,809 'return ': 8,698 'mut sel': 8,670 'ut self': 8,662 'self) -': 8,571 '&mut se': 8,479 "<'tcx>,": 8,067 'crate::': 7,773 'Option<': 7,626 Top 20 8-grams: 'let mut ': 9,111 'e rustc_': 8,865 'use rust': 8,812 'se rustc': 8,811 'elf) -> ': 8,808 'mut self': 8,658 'self) ->': 8,567 '&mut sel': 8,454 '} else {': 7,543 'pub(crat': 7,390 'ub(crate': 7,390 'b(crate)': 7,390 '(crate) ': 7,376 'redicate': 7,045 'ut self,': 6,496 'let Some': 6,396 'et Some(': 6,395 '(&mut se': 6,360 '(&self) ': 6,004 'agnostic': 5,996 Top 20 9-grams: 'use rustc': 8,807 'se rustc_': 8,804 'self) -> ': 8,566 '&mut self': 8,451 'pub(crate': 7,390 'ub(crate)': 7,390 'b(crate) ': 7,376 'mut self,': 6,496 'let Some(': 6,395 '(&mut sel': 6,348 'iagnostic': 5,981 'bligation': 5,943 '(&self) -': 5,822 '&self) ->': 5,822 '#[derive(': 5,434 'use crate': 5,304 'se crate:': 5,302 'e crate::': 5,302 'feature =': 5,194 'eature = ': 5,182 Top 20 10-grams: 'use rustc_': 8,804 'pub(crate)': 7,390 'ub(crate) ': 7,376 '&mut self,': 6,394 '(&mut self': 6,347 '(&self) ->': 5,822 '&self) -> ': 5,821 'use crate:': 5,302 'se crate::': 5,302 'feature = ': 5,182 'eature = "': 5,165 'assert_eq!': 5,030 'ssert_eq!(': 5,028 '(feature =': 5,019 'mut self, ': 4,699 'stable(fea': 4,631 'table(feat': 4,631 'able(featu': 4,631 'ble(featur': 4,631 'le(feature': 4,631 ``` ## C ``` ➲ py n-grams.py ~/Repositories/python/cpython/**/*.c Top 20 4-grams: 'ject': 57,183 'bjec': 57,106 'if (': 51,627 'Obje': 48,476 'turn': 47,444 'etur': 47,400 'retu': 45,547 'urn ': 44,361 'stat': 43,257 'ect ': 41,282 'yObj': 38,817 'ct *': 38,800 'NULL': 38,708 'PyOb': 38,525 'tate': 26,820 'size': 25,487 'code': 25,163 'tion': 22,497 'the ': 20,716 'tati': 20,542 Top 20 5-grams: 'bject': 57,106 'Objec': 48,474 'eturn': 47,400 'retur': 45,544 'turn ': 44,356 'ject ': 40,744 'yObje': 38,810 'ect *': 38,637 'PyObj': 38,525 'state': 21,007 '= NUL': 19,361 'tatic': 17,479 'stati': 17,429 'atic ': 16,970 'NULL;': 16,687 'NULL)': 14,188 'error': 11,965 'urn N': 11,831 'n NUL': 11,789 'rn NU': 11,780 Top 20 6-grams: 'Object': 48,474 'return': 45,544 'eturn ': 44,334 'bject ': 40,719 'yObjec': 38,808 'ject *': 38,624 'PyObje': 38,520 '= NULL': 19,361 'static': 17,359 'tatic ': 16,942 'turn N': 11,831 'n NULL': 11,789 'urn NU': 11,780 'rn NUL': 11,780 '== NUL': 10,545 'size_t': 10,365 '(PyObj': 10,056 'PyErr_': 9,695 'result': 9,096 'DECREF': 9,016 Top 20 7-grams: 'return ': 43,002 'yObject': 38,808 'bject *': 38,621 'PyObjec': 38,518 'Object ': 37,607 'static ': 16,932 '= NULL)': 12,301 'eturn N': 11,831 'turn NU': 11,780 'urn NUL': 11,780 'rn NULL': 11,780 'n NULL;': 11,709 '== NULL': 10,545 '(PyObje': 10,056 'DECREF(': 8,864 'clinic ': 8,391 '[clinic': 8,379 'size_t ': 8,279 'NULL) {': 8,071 'tatic P': 8,021 Top 20 8-grams: 'PyObject': 38,518 'Object *': 37,196 'yObject ': 31,104 'return N': 11,801 'eturn NU': 11,780 'turn NUL': 11,780 'urn NULL': 11,780 'rn NULL;': 11,709 '(PyObjec': 10,056 '== NULL)': 9,215 '= NULL) ': 8,561 '[clinic ': 8,379 'static P': 8,021 'tatic Py': 7,978 'Py_DECRE': 7,240 'y_DECREF': 7,240 '_DECREF(': 7,199 '_ssize_t': 6,807 'return -': 6,616 'eturn -1': 6,574 Top 20 9-grams: 'yObject *': 31,060 'PyObject ': 30,896 'eturn NUL': 11,780 'turn NULL': 11,780 'return NU': 11,761 'urn NULL;': 11,709 '(PyObject': 10,056 '= NULL) {': 8,054 'static Py': 7,978 'Py_DECREF': 7,240 'y_DECREF(': 7,189 '== NULL) ': 6,835 'y_ssize_t': 6,541 'Py_ssize_': 6,539 'return -1': 6,538 'eturn -1;': 6,455 ', PyObjec': 6,263 'PyUnicode': 6,041 'tatic PyO': 6,009 'atic PyOb': 6,008 Top 20 10-grams: 'PyObject *': 30,854 'eturn NULL': 11,780 'return NUL': 11,761 'turn NULL;': 11,709 '(PyObject ': 8,616 'Py_DECREF(': 7,189 'Py_ssize_t': 6,539 'return -1;': 6,455 '== NULL) {': 6,414 ', PyObject': 6,263 'static PyO': 6,009 'tatic PyOb': 6,008 'atic PyObj': 6,008 'tic PyObje': 6,008 'ic PyObjec': 6,008 'c PyObject': 6,008 'generated ': 5,728 'y_ssize_t ': 5,685 'enerated c': 5,669 'nerated co': 5,669 ```