HHKBのタイプ練習のためのPythonスクリプト作りました


# はじめに

- Realforceを使っていたのですが、どうもHybrid勤務になりそうな感じもありますので、持ち運びしやすいHappy Hacking Keyboard Hybrid Type-S　を買いました。

- 矢印キーもそうですが、その他キーもともかく練習したいなあ、簡単に。自分で打つものを決めてサッと練習したいな、という気持ち。

- 作りました。

- このスクリプトが動作するのはmacオンリーのはずです。

# ソースを出せ

はい。かしこまりました。
スクリプト１つ、問題用ファイル１つ、の計2ファイルでございます。

```python:practice.py
# -*- coding: utf-8 -*-
# for mac only
import sys
import termios
import tty

EOT = 3
TAB = 9
ESC = 27

keydict = {
'ESC':ESC,
'Tab':TAB,
'Enter':13,
'↑': 65, '↓': 66,  '→' : 67, '←' : 68,
'Insert':50,
'Del':51,
'End':70,
'Home': 72,
'BS':127,
}

# specialキーのキー番号変換
def convSpecialKey(string):
    if string in keydict:
        return keydict[string]
    else:
        raise Exception('NotExceptedSpecialKey')

# specialキーの場合のキーコード取得
def getch():
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    try:
        tty.setraw(fd)
        return sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old)

def main():
    #同じディレクトリのtarget.txtを1行ずつ読んでそれを打たせます
    with open('target.txt', mode='rt', encoding='utf-8') as f:
        for line in f:
            targetstr = line.strip()
            #print(targetstr)
            correct = False

            while correct == False:
                # コメント行(#ではじまるもの)は無視
                if targetstr.startswith("#"):
                    correct = True
                # specialで始まっていたら特殊文字系
                elif targetstr.startswith("special"):
                    targetstrReplace = targetstr.replace("special","")
                    print(targetstrReplace + "を打ってね")
                    key = ord(getch())
                    targetspecialkey = convSpecialKey(targetstrReplace)

                    if targetstrReplace == "Tab" and key == TAB:
                        print("OK!次だよ!\n")
                        correct = True
                    elif targetstrReplace == "ESC" and key == ESC:
                        print("OK!次だよ!\n")
                        correct = True
                    elif key == ESC:
                        key = ord(getch())
                        
                        if key == 91:
                            key = ord(getch())
                            #print(key)
                            if key == targetspecialkey:
                                print("OK!次だよ!\n")
                                correct = True
                            else:
                                print("NGなのでもう一回!\n")
                    elif key == targetspecialkey:
                        print("OK!次だよ!\n")
                        correct = True
                    # ctrl+cでとりあえず抜けられるようにする
                    elif key == EOT:
                        print("ctrl+c検知なので終わります")
                        sys.exit()
                    else:
                        print("NGなのでもう一回!\n")
                #その他通常の文字や記号
                else:
                    userinputstr = input(targetstr + " を入れてEnter.\n")
                    if userinputstr.strip() == targetstr:
                        print("OK!次だよ!\n")
                        correct = True
                    else:
                        print("NGなのでもう一回!\n")

    print("おわりでーす")

if __name__ == '__main__':
    main()

```

同じ場所に以下を置きます。
内容はただの例ですのでご自由につくってください。
ファイル名は一旦決め打ちです。

```text:target.txt
# this is comment.
test
Test sharp.##
# special、が前についているものが特殊キー用です
specialESC
specialTab
special↓
special↑
special←
special→
specialHome
specialEnd
specialDel
specialInsert
specialBS
specialEnter
Test
:
print();
()
[]
{}
``
\n
=
snake__snake
1+1=2
1*1=1
34+1=35
1/1=1
''
""
```

# 実行

単純に実行してください。

```shell
$ python3 practice.py
```

# 参考、気になるところ

皆様のお力により生きております。
参考とさせていただいた記事です。

https://qiita.com/tortuepin/items/9ede6ca603ddc74f91ba

https://qiita.com/tobesan/items/d9f4bd543c3a85b49bb2

気になるところは、特殊キーのとき何度もキーコードを拾うかんじをなんとかできないのか、もっといい方法がないのかな、というところですね。
あとスクリプトのキーコードマッピングは試してみながら出したものなんですが、
一般的なキーコードと値が違う気がするので、拾い方次第なのかが気になります。

ともかくやりたいのはたいしたことじゃなかったので、ともかく作りました。


# 結果

そうそう、こんなんでいいんだよ、みたいなかんじになったんでよかったです。
ついでにこれを書くために打ってたら練習になったんでよかったです。小並感。
HHKB(・∀・)ｲｲﾈ!!

もっと良くなる感じがあればおしえてください。イエーイ。