What I would like to be able to do is ask a user a question using input. For example:
print('some scenario')
prompt = input("You have 10 seconds to choose the correct answer...n")
and then if the time elapses print something like
print('Sorry, times up.')
Any help pointing me in the right direction would be greatly appreciated.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
If it is acceptable to block the main thread when user haven’t provided an answer:
from threading import Timer timeout = 10 t = Timer(timeout, print, ['Sorry, times up']) t.start() prompt = "You have %d seconds to choose the correct answer...n" % timeout answer = input(prompt) t.cancel()
Otherwise, you could use @Alex Martelli’s answer (modified for Python 3) on Windows (not tested):
import msvcrt
import time
class TimeoutExpired(Exception):
pass
def 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 select
import sys
def 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 signal
def alarm_handler(signum, frame):
raise TimeoutExpired
def 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
Method 2
Interesting problem, this seems to work:
import time
from threading import Thread
answer = None
def check():
time.sleep(2)
if answer != None:
return
print("Too Slow")
Thread(target = check).start()
answer = input("Input something: ")
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0