I'm really new to programming and I'm trying to create a maths quiz for young children. They have to answer as many questions as they can in 60 seconds. I have a timer and a question generator
The problem is however, I cant get them to run at the same time, for example, the program waits for 1 second, asks a question, waits until the user has answered it, then carries on with the timer etc. I want the timer to keep going and not stop whilst the questions are being answered!
This is my timer:
timer = 5
time.sleep(1)
timer -= 1
And my questions are generated by by defining a variable (I've shortened it down to addition):
def questions():
first_number = random.randint(1, 50)
second_number = random.randint(1, 50)
print("What is", first_number, "+", second_number,"?")
answer = int(input("Answer: "))
if answer == first_number + second_number:
print("Correct!")
addition_score += 1
else:
print("Wrong!")
It's harder than it should be to interrupt an input(). Let's first focus on a simpler task: you want to call questions() repeatedly, until the total elapsed time is 60 seconds or more. You can do that by measuring the time with time.time(), which returns a number of seconds since... some random "time zero" --- it doesn't matter. Code:
start_time = time.time() # "now" at the start
while time.time() < start_time + 60: # "not 60 seconds later"
questions()
The trick is not to use time.sleep(): in technical terms, the input() call is already "blocking", and you can only have one blocking function running at the same time (unless you introduce threads or multiple processes, which is completely overkill here).
The last question, if answered correctly, will count as +1, even though it was answered after more than 60 seconds. It's possible to change this logic by having questions() return either True or False, and doing the score += 1 part only if it returned True and if there is still time left.
If you want to get really interrupted after exactly 60 seconds, it's slightly harder. Try for example signal.alarm(60) (not on Windows). It will deliver the signal "Alarm clock" after the given number of seconds. By default it kills the process; if you want to catch it and do something else, try to do in addition: signal.signal(signal.SIGALRM, signal.default_int_handler). It will simulate a Ctrl-C after 60 seconds, which you can catch using:
try:
while True: # infinite loop, until interrupted
questions()
except KeyboardInterrupt:
pass # interrupted, now we're out of the loop
(No need for time.time() any more in this version.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With