math quiz with a time limit (simultaneous functions) - advanced python

穿精又带淫゛_ 提交于 2019-12-23 02:32:12

问题


So I would like to run two programs, a timer and a math question. But always the input seems to be stopping the timer funtion or not even run at all. Is there any ways for it to get around that? I'll keep the example simple.

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

So recap i would like the player to answer the question in less than 3 seconds.

after the 3 seconds the game will print wrong and exit

if the player answer within three seconds the timer would be 'terminated' or stopped before it triggers 'wrong' and quit

hope you understand, and really appreciate your help


回答1:


On Windows you can use the msvcrt module's kbhit and getch functions (I modernized this code example a little bit):

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

I'm not sure what exactly you have to do on other operating systems (research termios, tty, select).

Another possibility would be the curses module which has a getch function as well and you can set it to nodelay(1) (non-blocking), but for Windows you first have to download curses from Christopher Gohlke's website.

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)


来源:https://stackoverflow.com/questions/42885887/math-quiz-with-a-time-limit-simultaneous-functions-advanced-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!