Timed user input in Python

2.3k Views Asked by At

I am trying to take user input in Python with a timer. I want the user to only have 10 seconds to enter something. However when 10 seconds is over the message "Time up!" is printed but the script does not stop.

import pygame
from threading import Thread

clock = pygame.time.Clock()
timee = 0
UIn=None

def func1():
    global timee
    global clock
    global UIn
    while True:
        milli = clock.tick()
        seconds = milli/1000

        timee=timee+seconds
        if(int(timee)==10):
            print("Time is over")
            quit()
        

def func2():
    global UIn
    print("Working")
    input("Press key:\t")


Thread(target=func1).start()
Thread(target=func2).start()
UIn=input("Press key:\t")
2

There are 2 best solutions below

7
Maximilian Freitag On BEST ANSWER

You can use the Timer class for this purpose

from threading import Timer

timeout = 10
t = Timer(timeout, print, ['Sorry, times up!'])
t.start()
prompt = "You have %d seconds to answer the question. What color do cherries have?...\n" % timeout
answer = input(prompt)
t.cancel()

Output:

You have 10 seconds to answer the question. What color do cherries have?
(After 10 seconds)
Sorry, times up!
1
mnikley On

After giving it some thought and thanks to @Rabbid76 you probably want something like this (modified after the code from this great post):

import msvcrt
import time
import sys

class TimeoutExpired(Exception):
    pass

def input_with_timeout(prompt, timeout, timer=time.monotonic):
    """Timed input function, taken from https://stackoverflow.com/a/15533404/12892026"""
    sys.stdout.write(prompt)
    sys.stdout.flush()
    endtime = timer() + timeout
    result = []
    while timer() < endtime:
        if msvcrt.kbhit():
            result.append(msvcrt.getwche()) #XXX can it block on multibyte characters?
            if result[-1] == '\r':
                return ''.join(result[:-1])
        time.sleep(0.04) # just to yield to other processes/threads
    raise TimeoutExpired

# create a timed input object
try:
    answer = input_with_timeout("Give me an answer: ", 10)
except TimeoutExpired:
    print('\nSorry, times up')
else:
    print(f'\nYour answer was: {answer}')

# continue with code and verify the input
if answer:
    if answer == "yes":
        print("OK")