4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

100万字のコード解析を解析し、コード入力に最も最適なキーボードを作る

Last updated at Posted at 2021-03-24

#完成形

なぜこのようなトチ狂ったキーボードと配列になったのか、順を追って説明する。
PXL_20210323_070357834.jpg
f76c5e3d-c084-43c3-8fd5-5b8da860xxxxxxxxhhhh6e15_base_resized2.png
文字キーと,.;/みの移動させた場合
stshbo.png

#従来のキーボードの問題点
愛用していたNIZというキーボードだがキーボード界隈を覗くと従来のキーボードにもあてはまる以下の問題があることがわかった。

・キーが不必要に横にずれている
・左右分離ではない
・キーの配列が合理的ではない
・親指を活用できていない

これらの問題点を踏まえてコード入力に最適なキーボードを考えたい。

#レイアウト
###カラムスタッガードか格子配列をすすめる
keyboard-1.png
従来のキーボードに見られるこの横ずれはロウスタッガードとよばれ、タイプライターの名残だ。
そのため人間工学的だから使われているわけではない。
人間の指は斜めに曲がらないので、斜め方向の移動はやりづらく、ご入力の原因になる。
なので個人的に各指の長さに合わせ縦方向にずらした、カラムスタッガードか、キーの密度が最も高い格子配列をすすめる。
カラムスタッガードか、格子配列で親指を活かせるキットが私が確認した時点でergodashしかなかったためそれを買った。
ErgoDash

#キー配置
###コード入力に最適なキー配置
デファクトスタンダードとなっているqwerty配列だが、タイプライター時代に考案されたもので、問題点も多い。
そこで英語入力に最適化することを目指したdvorak配列、
英語入力を考えつつ、qwerty配列からの移行コストを下げた、colemak配列、
ローマ字入力に最適化しつつ、エンジニアに配慮されたEucalyn配列、
など数多の配列が存在するが、コード入力に最適化することを考えた配列があっただろうか。(既出ならごめんなさい)

そこでコード入力に最適化されたキー配置を考えようと思い立った。

###100万字のコード解析
コードにはどのキーが多く使われているのか、私が学習しているgolangのコードを解析してみた。
解析はすべての文字で検証した場合と、多くの場合で保管機能を使いながらコード入力を行うと思うので、単語の先頭の文字のみを検証した場2通りで行った。
検証に使ったgolangのコードとpythonの頻度解析のコードはここ。

結果は以下の通りだ。

####・すべての文字の頻度解析
seahhhborntest.png

[(' ', 106773), ('e', 78523), ('t', 61675), ('\t', 57331), ('r', 53907), ('n', 45941), ('i', 41184), ('s', 40403), ('o', 38814), ('a', 38544), ('\n', 38387), ('l', 26621), ('c', 23970), ('.', 21813), ('u', 21413), ('d', 19440), ('f', 19348), ('p', 18613), ('(', 16213), (')', 16211), ('g', 15618), ('m', 14333), ('"', 13913), (',', 13274), ('/', 13273), ('h', 12101), ('=', 10778), (':', 9037), ('b', 8261), ('v', 7924), ('}', 7465), ('{', 7464), ('y', 6658), ('x', 6345), ('S', 6191), ('w', 4890), ('T', 4566), ('C', 4421), ('k', 4378), ('0', 3868), ('R', 3768), ('E', 3460), ('I', 3305), ('1', 3286), ('-', 3175), ('P', 3169), ('N', 2956), ('A', 2911), ('O', 2794), ('_', 2537), ('B', 2446), ('*', 2419), ('[', 2323), (']', 2321), ('D', 2236), ('F', 2188), ('M', 2115), ('L', 2094), ('U', 1959), ('H', 1695), ('!', 1619), ('V', 1606), ('G', 1497), ('q', 1448), ('6', 1421), ('j', 1381), ('2', 1319), ('`', 1302), ('&', 1286), ('4', 1280), ('%', 1090), ('z', 1063), ('W', 1000), (';', 907), ('+', 781), ('3', 751), ("'", 651), ('8', 602), ('K', 596), ('|', 513), ('9', 502), ('<', 488), ('J', 468), ('>', 430), ('5', 410), ('7', 302), ('\\', 280), ('X', 242), ('Q', 218), ('$', 155), ('Z', 154), ('#', 145), ('Y', 95), ('^', 57), ('?', 32), ('@', 30), ('~', 16), ('•', 5), ('→', 5), ('╺', 4)]

####・各単語の先頭1文字の頻度解析
first_one.png

[('(', 16213), (')', 16211), (',', 13261), ('t', 10013), ('=', 9559), ('s', 9378), ('i', 9349), ('f', 9295), 
("'", 9001), (':', 8964), ('r', 7834), ('}', 7465), ('{', 7464), ('c', 7088), ('`', 6771), ('e', 6687), ('a', 6500), ('n', 5590), ('/', 5182), ('b', 4590), ('.', 4328), ('p', 4297), ('d', 3810), ('m', 3755), ('v', 3610), ('o', 3559), ('g', 3324), ('l', 2526), ('*', 2419), ('[', 2323), (']', 2321), ('w', 2315), ('h', 2125), ('u', 1680), ('!', 1619), ('&', 1286), ('0', 1091), ('%', 1090), ('_', 1019), ('j', 1013), (';', 907), ('-', 794), ('1', 662), ('k', 548), ('<', 488), ('>', 430), ('x', 413), ('+', 394), ('z', 338), ('q', 307), ('|', 269), ('2', 239), ('4', 171), ('$', 155), ('#', 145), ('3', 145), ('i', 124), ('5', 110), ('\\', 102), ('6', 63), ('8', 63), ('7', 63), ('^', 56), ('?', 32), ('@', 30), ('9', 29), ('~', 15), ('•', 5), ('→', 5), ('╺', 4), 
('�👋', 3), ('⦿', 2), ('⇨', 1), ('⊳', 1), ('↔', 1), ('≡', 1)]

####・各単語の先2文字の頻度解析
first_two.png

[("''", 8442), ('re', 5880), ('``', 5473), ('//', 4871), ('er', 3971), ('st', 3245), ('th', 3034), ('if', 2679), ('in', 2479), ('co', 2472), ('fu', 2453), ('de', 1862), ('ni', 1796), ('to', 1551), ('is', 1520), ('se', 
1451), ('ma', 1443), ('fo', 1399), ('ca', 1351), ('pa', 1271), ('fi', 1078), ('go', 1075), ('te', 1031), ('ge', 1016), ('an', 1002), ('lo', 972), ('tr', 959), ('bu', 936), ('no', 931), ('ne', 914), ('ap', 898), ('pr', 
861), ('n.', 844), ('op', 819), ('ex', 802), ('fr', 771), ('va', 770), ('by', 728), ('ty', 717), ('==', 713), ('ht', 713), ('me', 696), ('li', 689), ('bo', 670), ('v0', 662), ('ho', 661), ('en', 656), ('fa', 648), ('be', 648), ('of', 643), ('wi', 630), ('ar', 628), ('on', 601), ('v1', 593), ('na', 560), ('ru', 552), ('gi', 547), ('us', 543), ('ad', 528), ('le', 518), ('it', 503), ('.s', 502), ('t.', 492), ('bl', 482), ('mo', 481), ('..', 473), ('as', 470), ('ro', 464), ('ra', 450), ('pp', 450), ('di', 445), ('wh', 430), ('wa', 430), ('ch', 428), ('ti', 428), ('su', 427), ('fm', 421), ('c1', 414), ('al', 411), ('un', 408), ('c0', 403), ('cl', 397), ('sy', 389), ('s.', 361), ('ta', 360), ('im', 347), ('os', 341), ('s1', 341), ('s0', 340), ('ha', 333), ('ev', 324), ('si', 322), ('so', 319), ('up', 318), ('da', 317), ('ve', 314), ('db', 313), ('jo', 312), ('c.', 311), ('po', 310)]

####・各単語の先頭3文字の頻度解析
three.png

[('err', 3955), ('ret', 2766), ('fun', 2400), ('str', 2392), ('the', 2304), ('nil', 1796), ('con', 1431), ('for', 1274), ('app', 824), ('cas', 810), ('tes', 768), ('fil', 760), ('int', 755), ('log', 727), ('typ', 688), ('ref', 688), ('htt', 658), ('gen', 649), ('bui', 636), ('hos', 596), ('des', 583), ('sta', 582), ('def', 578), ('pro', 551), ('nam', 543), ('byt', 543), ('not', 528), ('tru', 522), ('opt', 513), ('and', 510), ('res', 505), ('fra', 483), ('req', 462), ('use', 462), ('git', 446), ('ser', 446), ('.se', 445), ('run', 445), ('...', 437), ('com', 427), ('ppu', 425), ('fmt', 421), ('add', 421), ('blt', 406), ('n.e', 404), ('new', 398), ('fal', 398), ('boo', 386), ('val', 386), ('var', 383), ('tim', 383), ('len', 373), ('pat', 371), ('exp', 370), ('arg', 364), ('ran', 361), ('get', 359), ('rep', 356), ('tha', 351), ('wit', 346), ('thi', 340), ('ins', 328), ('imp', 320), ('lin', 303), ('map', 297), ('mes', 293), ('par', 289), ('met', 287), ('job', 287), ('out', 286), ('nex', 285), ('pac', 284), ('dat', 277), ('els', 276), ('mak', 275), ('eve', 272), ('os.', 262), ('can', 258), ('swi', 254), ('set', 248), ('ctx', 246), ('t.f', 242), ('mod', 239), ('rea', 235), ('syn', 235), ('sho', 234), ('jso', 228), ('whe', 224), ('key', 219), ('dis', 217), ('fro', 217), ('tne', 216), ('rou', 212), ('ass', 212), ('tar', 206), ('ver', 206), ('per', 206), ('cre', 202), ('fla', 198), ('env', 198)]

###考察
・space、tab、改行などインデントを整えるキーが多かった。
・英文と比較して、rが上位に入ってきた。
・func、if、forなど多くの文法で使われる、fも上位に来た。
・下手な文字より、記号のほうが多く使われている。

###出来上がったキー配置
####以下をコーディング配列(go_1)と名付けます。
f76c5e3d-c084-43c3-8fd5-5b8da860xxxxxxxxhhhh6e15_base_resized2.png
・私は日本語は薙刀式という入力方式を使うのでローマ字入力を考えずに配置。
・親指キーは連続打ちできるため、er、if、inなど頻出を配置。
・ショートカットは別でキーを用意するため、ショートカットでよく使うキーも無視。
・同じ指で連続してうたないように配置。

文字キーと,.;/みの移動させた場合
####以下をコーディング配列(go_2)と名付けます。
stshbo.png
・文字キーのみのものはあまり自信がないためよければご意見をください。

#スイッチ
###最も早く快適に打てるキースイッチは銀軸
ここでは長時間入力するのに適した、なで打ちというアクチュエーションギリギリを打つ打ち方をする前提で話を進める。
なで打ちと聞くと多くの人は黒軸を想像するかと思うが、私からは銀軸を勧めたい。
あくまで私の場合だが、半分押し込めば反応する黒軸より、すぐ反応する銀軸のほうが加減がしやすく、打ちやすかった。
銀軸で文字入力していて、誤爆も聞いていたより少なく感じる。
PXL_20210323_055833525 (2).jpg

#キーキャップ
###設計思想が素晴らしい薙刀式キーキャップ
指の曲線とキーボードに置かれる指の向きを考えて、設計された薙刀式キーキャップの設計思想に共感し、それを選択。
良ければ大岡さんのブログの方もご覧ください。
商品ページ

###小指の付け根で押す
小指の付け根で押すように高いSAプロファイルのキーキャップもつける。
PXL_20210323_064355449.jpg

#まとめ
ここまでたどり着くのにかなりの時間を使ってしまったが、とても楽しかった。
今回初めてpythonで文字解析をしてみたが、想像以上に簡単で驚いた。
今回はgolangでやってみたが、各言語ごとにやってみて傾向を調べても面白いと思う。

apexというゲームでこのキーボードを使ってみたが、やりづらかった。
普通のキーボードに戻した途端にキルリーダーになれた。
慣れもあるだろうが、このキーボードだと小指が動かしづらかった。
ぽんと一瞬押せばいい文字入力と、押し続けなければいけないゲームでは違うのだなと思った。
いつか最強のゲーミングキーボードも作ってみたい。

ここまでご高覧賜りありがとうございました。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?