Time-Limited Input? [duplicate]
If it is acceptable to block the main thread when user haven't provided an answer:
from threading import Timertimeout = 10t = Timer(timeout, print, ['Sorry, times up'])t.start()prompt = "You have %d seconds to choose the correct answer...\n" % timeoutanswer = input(prompt)t.cancel()
Otherwise, you could use @Alex Martelli's answer (modified for Python 3) on Windows (not tested):
import msvcrtimport timeclass TimeoutExpired(Exception): passdef input_with_timeout(prompt, timeout, timer=time.monotonic): 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
Usage:
try: answer = input_with_timeout(prompt, 10)except TimeoutExpired: print('Sorry, times up')else: print('Got %r' % answer)
On Unix you could try:
import selectimport sysdef input_with_timeout(prompt, timeout): sys.stdout.write(prompt) sys.stdout.flush() ready, _, _ = select.select([sys.stdin], [],[], timeout) if ready: return sys.stdin.readline().rstrip('\n') # expect stdin to be line-buffered raise TimeoutExpired
Or:
import signaldef alarm_handler(signum, frame): raise TimeoutExpireddef input_with_timeout(prompt, timeout): # set signal handler signal.signal(signal.SIGALRM, alarm_handler) signal.alarm(timeout) # produce SIGALRM in `timeout` seconds try: return input(prompt) finally: signal.alarm(0) # cancel alarm
Interesting problem, this seems to work:
import timefrom threading import Threadanswer = Nonedef check(): time.sleep(2) if answer != None: return print("Too Slow")Thread(target = check).start()answer = input("Input something: ")