2017-03-19 1 views
1

Donc, je voudrais exécuter deux programmes, une minuterie et une question de mathématiques. Mais toujours l'entrée semble arrêter le fonctionnement de la minuterie ou même ne pas fonctionner du tout. Y a-t-il des moyens de contourner cela? Je vais garder l'exemple simple.quiz mathématiques avec une limite de temps (fonctions simultanées) - python avancé

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

Donc, je voudrais que le lecteur réponde à la question en moins de 3 secondes.

après les 3 secondes, le jeu affichera mal et la sortie

si la réponse du joueur dans les trois secondes, la minuterie sera « terminée » ou arrêté avant qu'il ne déclenche « mauvais » et quitter

espère que vous comprenez , et vraiment apprécier votre aide

+2

Avez-vous fait des recherches? Par exemple: http://stackoverflow.com/q/1335507/3001761 – jonrsharpe

+0

Je ne suis pas un programmeur python mais il semblerait que cela nécessite une simultanéité/plusieurs threads. – ostrichofevil

+0

Utilisez-vous Windows, Linux ou un autre système d'exploitation? – skrx

Répondre

0

Sous Windows, vous pouvez utiliser kbhit et getch du module msvcrt fonctions (je code example ce modernisés un peu):

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

Je ne sais pas exactement ce que vous devez faire sur d'autres systèmes d'exploitation (recherche termios, tty, select).

Une autre possibilité serait le module curses qui a une fonction getch aussi bien et vous pouvez le mettre à nodelay(1) (non-blocage), mais pour Windows vous devez d'abord télécharger malédictions de 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) 
+0

Il n'y a pas d'entrée et même quand j'ai mis un nom, le code ignore l'entrée et continue à fonctionner –

+0

L'exécutez-vous à partir de la ligne de commande ou d'un IDE comme IDLE ou PyCharm? Et utilisez-vous Windows? Vous devez utiliser la ligne de commande Windows. – skrx

+0

@Yo LEE laissez-moi savoir si cela fonctionne. Je vais ajouter un exemple qui utilise des malédictions plus tard. – skrx