diff --git a/scripts/superkey/interface.py b/scripts/superkey/interface.py index 5895cb4..687c193 100644 --- a/scripts/superkey/interface.py +++ b/scripts/superkey/interface.py @@ -148,7 +148,7 @@ def autokey_quick_msg(self, index: int): self.__send_packet(MessageID.REQUEST_AUTOKEY_QUICK_MSG, struct.pack(' int: + """ + Returns the start index in the sorted list for words with the specified length. + """ + if length < self.min_length: + return 0 + elif length > self.max_length: + return len(self) + else: + return self.words_by_length_indices[length] + + def random(self, min_length: int = None, max_length: int = None): + """ + Returns a randomly selected word from this word list. + """ + # Sanity check range + if min_length is None or min_length < self.min_length: + min_length = self.min_length + if max_length is None or max_length > self.max_length: + max_length = self.max_length + + # Get indices in the sorted list for the requested lengths + start_idx = self._start_idx(min_length) + end_idx = self._start_idx(max_length + 1) + return self.words_by_length[random.randrange(start_idx, end_idx)] diff --git a/scripts/wordcopy.py b/scripts/wordcopy.py new file mode 100644 index 0000000..010436a --- /dev/null +++ b/scripts/wordcopy.py @@ -0,0 +1,109 @@ +# +# @file scripts/wordcopy.py +# @brief Trainer script for copying English words. +# +# @author Chris Vig (chris@invictus.so) +# @date 2025-09-10 +# @cpyrt © 2025 by Chris Vig. Licensed under the GNU General Public License v3 (GPLv3). +# + +# ------------------------------------------------------ IMPORTS ------------------------------------------------------- + +import argparse +import time + +from superkey import * +from utility import wordlist + +# ----------------------------------------------------- CONSTANTS ------------------------------------------------------ + +DEFAULT_COUNT = 20 +DEFAULT_DELAY = 3. +DEFAULT_WPM = 20. +DEFAULT_MINLEN = 2 +DEFAULT_MAXLEN = 8 + +# ----------------------------------------------------- PROCEDURES ----------------------------------------------------- + +def _parse_args(): + """ + Parses the command line arguments. + """ + parser = argparse.ArgumentParser(description='Word Copy Trainer') + parser.add_argument('--port', type=str, default=SUPERKEY_DEFAULT_PORT, help='Serial port to connect to.') + parser.add_argument('--baudrate', type=int, default=SUPERKEY_DEFAULT_BAUDRATE, help='Serial port baud rate.') + parser.add_argument('--timeout', type=float, default=SUPERKEY_DEFAULT_TIMEOUT, help='Serial port timeout (s).') + parser.add_argument('--count', type=int, default=DEFAULT_COUNT, help='Number of words to key.') + parser.add_argument('--delay', type=float, default=DEFAULT_DELAY, help='Seconds to delay between each word.') + parser.add_argument('--wpm', type=float, default=DEFAULT_WPM, help='Words per minute.') + parser.add_argument('--minlen', type=int, default=DEFAULT_MINLEN, help='Minimum word length.') + parser.add_argument('--maxlen', type=int, default=DEFAULT_MAXLEN, help='Maximum word length.') + return parser.parse_args() + +def _main(port: str, + baudrate: int, + timeout: float, + count: int, + delay: float, + wpm: float, + minlen: int, + maxlen: int): + """ + Runs the trainer. + """ + # Build word list + wl = wordlist.WordList() + + # Open SuperKey interface + with Interface(port = port, baudrate = baudrate, timeout = timeout) as intf: + + try: + + # Get initial settings + initial_wpm = intf.get_wpm() + initial_trainer_mode = intf.get_trainer_mode() + + # Override settings + intf.set_wpm(wpm) + intf.set_trainer_mode(True) + + # Run as many times as commanded + for _ in range(count): + + # Get a random word and key it + word = wl.random(min_length=minlen, max_length=maxlen).upper() + intf.autokey(word, block=True) + + # Print the word after a delay + time.sleep(delay) + print(word) + time.sleep(delay * .5) + + except KeyboardInterrupt: + + # Cancel autokey + intf.panic() + + finally: + + # Restore initial settings + intf.set_wpm(initial_wpm) + intf.set_trainer_mode(initial_trainer_mode) + + +# -------------------------------------------------- IMPORT PROCEDURE -------------------------------------------------- + +if __name__ == '__main__': + + # Parse arguments + args = _parse_args() + + # Run main procedure + _main(port = args.port, + baudrate = args.baudrate, + timeout = args.timeout, + count = args.count, + delay = args.delay, + wpm = args.wpm, + minlen = args.minlen, + maxlen = args.maxlen)