3

I'm making a typing speed test game and trying to make it so that when a user is typing into a python input(), it can be submitted by them pressing space rather than just enter, on Windows. My code is similar to the following:

score = 0
start_time = int(time.time())
characters = 0
words = 0
current_word = random.choice(WORDS)
next_word = random.choice(WORDS)
while (int(time.time()) - start_time) <= TIME_LIMIT:
    os.system('cls')
    print(f"Your word is {current_word}")
    print(f"The next word will be {next_word}")
    print(f"Your current score is {score}")
    attempt = input("> ")
    if attempt.lower() == current_word.lower():
        score = score + 1
        words = words + 1
        characters = characters + len(current_word)
    current_word = next_word
    next_word = random.choice(WORDS)

Is there any way for this to work or is it best to maybe create my own input function?

cs95
  • 379,657
  • 97
  • 704
  • 746
Mark Price
  • 75
  • 1
  • 1
  • 11
  • Are you sure you want to do that? Wouldn't you want to check the type speed of sentences too in your game? Typing training apps even give complete texts for the users to type. I mean, you'll need the space key for that. – progmatico Dec 23 '17 at 18:09

2 Answers2

1

Solved this by creating my own input function as below:

def custom_input(prefix=""):
    """Custom string input that submits with space rather than enter"""
    concatenated_string = ""
    sys.stdout.write(prefix)
    sys.stdout.flush()
    while True:
        key = ord(getch())
        # If the key is enter or space
        if key == 32 or key == 13:
            break
        concatenated_string = concatenated_string + chr(key)
        # Print the characters as they're entered
        sys.stdout.write(chr(key))
        sys.stdout.flush()
    return concatenated_string
Mark Price
  • 75
  • 1
  • 1
  • 11
  • Your answer needs to import sys and getch? – Tai Dec 23 '17 at 19:34
  • Admittedly not the best, but it functions okay for my use case – Mark Price Dec 24 '17 at 12:26
  • Hey, your answer is clean. I mentioned it because if other people use your answer, they can more get to it more quickly. Also, there seems to have 2 libraries, py-getch and getch, that have getch(). It would be useful to see which library you use. – Tai Dec 24 '17 at 15:10
1

The following code is modified from the answer How to code autocompletion in python? given by @gandi.

It can get input from user in real time. Backspace will move back cursor for a character.

Some other good references

Python read a single character from the user

import termios, os, sys

def flush_to_stdout(c):
    if c == b'\x7f':
        sys.stdout.write("\b \b")
    else:
        sys.stdout.write(c.decode("utf-8"))
        sys.stdout.flush()

def getkey():
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
    new[6][termios.VMIN] = 1
    new[6][termios.VTIME] = 0
    termios.tcsetattr(fd, termios.TCSANOW, new)
    c = None
    try:
        c = os.read(fd, 1)       
        flush_to_stdout(c)
    finally:
        termios.tcsetattr(fd, termios.TCSAFLUSH, old)
    if c == b'\x7f': # Backspace/delete is hit
        return "delete"
    return c.decode("utf-8")

def get_word():
    s = ""
    while True:
        a = getkey()
        # if ENTER or SPACE is hit
        if a == " " or a == "\n": 
            return s
        elif a == "delete":
            s = s[:-1]
        else:
            s += a


if __name__ == "__main__":
    while True:
        print(get_word())
Tai
  • 7,684
  • 3
  • 29
  • 49