web-dev-qa-db-ja.com

Python 3時限入力

私ができることは、入力を使用してユーザーに質問することです。例えば:

print('some scenario')
Prompt = input("You have 10 seconds to choose the correct answer...\n")

そして時間が経過すると、次のようなものが印刷されます

print('Sorry, times up.')

私を正しい方向に向ける助けがあれば、大歓迎です。

25
cloud311

興味深い問題、これはうまくいくようです:

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 = raw_input("Input something: ")
12
mediocrity

ユーザーが回答を提供していないときにメインスレッドをブロックすることが許容できる場合:

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()

それ以外の場合は、Windowsで @ Alex Martelliの回答 (Python 3に変更)を使用できます(テストされていません):

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] == '\n':   #XXX check what Windows returns here
                return ''.join(result[:-1])
        time.sleep(0.04) # just to yield to other processes/threads
    raise TimeoutExpired

使用法:

try:
    answer = input_with_timeout(Prompt, 10)
except TimeoutExpired:
    print('Sorry, times up')
else:
    print('Got %r' % answer)

Unixでは、次のことを試すことができます。

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

または:

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
19
jfs