带有时间限制的数学测验(同时功能) - 高级python

时间:2017-03-19 11:13:03

标签: python math timer simultaneous

所以我想运行两个程序,一个计时器和一个数学问题。但总是输入似乎停止计时器功能或根本不运行。它有什么方法可以解决这个问题吗? 我会保持这个例子的简单。

import time

start_time = time.time()
timer=0
correct = answer
answer = input("9 + 9 = ") 
#technically a math question here
#so here until i enter the input prevents computer reading the code
while True:
    timer = time.time() - start_time
    if timer > 3:
#3 seconds is the limit
    print('Wrong!')
quit()

因此,我希望玩家能在不到3秒的时间内回答这个问题。

3秒后游戏将打印错误并退出

如果玩家在三秒钟内回答,计时器将被“终止”或在其触发“错误”之前停止并退出

希望您理解并非常感谢您的帮助

2 个答案:

答案 0 :(得分:0)

在Windows上,您可以使用msvcrt模块的kbhitgetch功能(我对此code example进行了一些现代化改造):

import sys
import time
import msvcrt


def read_input(caption, timeout=5):
    start_time = time.time()
    print(caption)
    inpt = ''
    while True:
        if msvcrt.kbhit():  # Check if a key press is waiting.
            # Check which key was pressed and turn it into a unicode string.
            char = msvcrt.getche().decode(encoding='utf-8')
            # If enter was pressed, return the inpt.
            if char in ('\n', '\r'): # enter key
                return inpt
            # If another key was pressed, concatenate with previous chars.
            elif char >= ' ': # Keys greater or equal to space key.
                inpt += char
        # If time is up, return the inpt.
        if time.time()-start_time > timeout:
            print('\nTime is up.')
            return inpt

# and some examples of usage
ans = read_input('Please type a name', timeout=4)
print('The name is {}'.format(ans))
ans = read_input('Please enter a number', timeout=3)
print('The number is {}'.format(ans))

我不确定您在其他操作系统上究竟需要做什么(研究termios,tty,select)。

另一种可能性是具有getch功能的curses模块,您可以将其设置为nodelay(1)(非阻塞),但对于Windows,您首先必须从{{{}下载curses。 3}}。

import time
import curses


def main(stdscr):
    curses.noecho()  # Now curses doesn't display the pressed key anymore.
    stdscr.nodelay(1)  # Makes the `getch` method non-blocking.
    stdscr.scrollok(True)  # When bottom of screen is reached scroll the window.
    # We use `addstr` instead of `print`.
    stdscr.addstr('Press "q" to exit...\n')
    # Tuples of question and answer.
    question_list = [('4 + 5 = ', '9'), ('7 - 4 = ', '3')]
    question_index = 0
    # Unpack the first question-answer tuple.
    question, correct_answer = question_list[question_index]
    stdscr.addstr(question)  # Display the question.

    answer = ''  # Here we store the current answer of the user.
    # A set of numbers to check if the user has entered a number.
    # We have to convert the number strings to ordinals, because
    # that's what `getch` returns.
    numbers = {ord(str(n)) for n in range(10)}

    start_time = time.time()  # Start the timer.

    while True:
        timer = time.time() - start_time

        inpt = stdscr.getch()  # Here we get the pressed key.
        if inpt == ord('q'):  # 'q' quits the game.
            break
        if inpt in numbers:
            answer += chr(inpt)
            stdscr.addstr(chr(inpt), curses.A_BOLD)
        if inpt in (ord('\n'), ord('\r')):  # Enter pressed.
            if answer == correct_answer:
                stdscr.addstr('\nCorrect\n', curses.A_BOLD)
            else:
                stdscr.addstr('\nWrong\n', curses.A_BOLD)

        if timer > 3:
            stdscr.addstr('\nToo late. Next question.\n')

        if timer > 3 or inpt in (ord('\n'), ord('\r')):
            # Time is up or enter was pressed; reset and show next question.
            answer = ''
            start_time = time.time()  # Reset the timer.
            question_index += 1
            # Keep question index in the correct range.
            question_index %= len(question_list)
            question, correct_answer = question_list[question_index]
            stdscr.addstr(question)

# We use wrapper to start the program.
# It handles exceptions and resets the terminal after the game.
curses.wrapper(main)

答案 1 :(得分:0)

使用time.time(),它返回纪元时间(即自 1970 年 1 月 1 日 UNIX 时间以来的秒数)。您可以将其与开始时间进行比较以获取秒数:

start = time.time()
while time.time() - start < 60:
    # stuff

您可以让计时器在任何时候(即使用户正在输入信息)通过信号将您从代码中拉出来,但这有点复杂。一种方法是使用信号库:

import signal
def timeout_handler(signal, frame):
    raise Exception('Time is up!')
signal.signal(signal.SIGALRM, timeout_handler)

这里定义了一个引发异常并在超时发生时调用的函数。现在您可以将 while 循环放入 try catch 块中并设置计时器:

signal.alarm.timeout(60)
try:
    while lives > 0
        # stuff
except:
    # print score