0

I am trying to build a buzzer system for my office. We have old paddles that act as a keyboard and sends out 1-9. I am looking to take the digit that it puts out and state a name in python. I have it built but I cannot for the life of me find how to create a lockout for the buzzers I tried time.sleep but the consule is still taking keyboard input. Also I cannot find how to make it once a single digit is in the input field it will take that key press without the need to press enter. Any help or point in the correct direction would be great. FYI this is my first time with Python.

while(count != '0'):

  buzz = input("\n Buzzers Ready: ")

  if buzz == '1' and count > '0':
    print(ply1)
    time.sleep(5)
  elif buzz == '2' and count > '1':
    print(ply2)
    time.sleep(5)
  elif buzz == '3' and count > '2':
    print(ply3)
    time.sleep(5)
  elif buzz == '4' and count > '3':
    print(ply4)
    time.sleep(5)
  elif buzz == '5' and count > '4':
    print(ply5)
    time.sleep(5)
  elif buzz == '6' and count > '5':
    print(ply6)
    time.sleep(5)
  elif buzz == '7' and count > '6':
    print(ply7)
    time.sleep(5)
  elif buzz == '8' and count > '7':
    print(ply8)
    time.sleep(5)
  elif buzz == '9' and count > '8':
    print(ply9)
    time.sleep(5)
  elif buzz == 'z':
    break

  else:
    print("Non-Vaild Player.")
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • 1
    `>` and a string is never a good idea. You might want to make it an integer first. And where is `count` actually set? – Klaus D. Sep 30 '19 at 01:38
  • Count is the first question in the program asking how many players there will be. I did not want to put up my full code as it is 290 lines. – John Stilwell Sep 30 '19 at 01:55
  • Why are `count` and `buzz` strings? You should consider using a `for` loop instead of all those if-elifs. – GordonAitchJay Sep 30 '19 at 07:56
  • @GordonAitchJay I am brand new to python and building it the long way. Any help you could provide would be greatly appreciated. – John Stilwell Sep 30 '19 at 14:47

2 Answers2

1

Instead of time.sleep(5), put break, and it will exit the loop and won't accept any more key presses.

if buzz == '1' and count > '0':
    print(ply1)
    time.sleep(5)  <<--- put 'break' here instead everywhere
lenik
  • 23,228
  • 4
  • 34
  • 43
  • I only want the system not to take input for 5 seconds and then go back to buzz input as it is a loop for multiple question buzzer game. – John Stilwell Sep 30 '19 at 01:53
0

I cannot find how to make it once a single digit is in the input field it will take that key press without the need to press enter.

There are a couple different solutions. See this question: raw_input in python without pressing enter

In the past, I have used pynput. (It doesn't require the focus of the window/console to read key presses. This may or may not be an issue for you.)

Install it by entering pip install pynput into your console (cmd.exe on Windows).

Take a look at this. It will read key presses until the Esc key is pressed, printing the player's name if 1-9 is pressed. It will not print a player's name again until 5 seconds has passed (without using time.wait()).

import time
from pynput import keyboard

LOCKOUT_TIME = 5.000 # Seconds
time_last_pressed = 0 # Or time.time() - LOCKOUT_TIME

names = ("Skinny Pete (player 1)",
         "Old Joe (player 2)",
         "Badger (player 3)",
         "Emilio (player 4)",
         "Bogdan (player 5)", 
         "Hector (player 6)",
         "Gale (player 7)",
         "Mike (player 8)",
         "Gus (player 9)")

def on_press(key):
    # Without this global statement, assigning to time_last_pressed will create 
    # a new local variable, which won't exist once the function ends.
    global time_last_pressed

    # Make sure enough time has passed before continuing
    if time.time() - time_last_pressed < LOCKOUT_TIME:
        return

    # The "key" parameter will only have the "char" attribute if a normal 
    # alphanumeric key was pressed. If another key is pressed, such as shift, 
    # an AttributeError exception will be raised which we will catch.
    # key.char will be a string, e.g. "1" if the "1" key is pressed, "a" if the 
    # "a" key is pressed, etc. We want it as an int, so we can use it to index 
    # into the names tuple. int will raise a ValueError if you pass in a string 
    # which cannot be parsed as an int - every time any letter key is pressed.
    try:
        number = int(key.char)
    except (ValueError, AttributeError):
        return

    # Make sure the number is between 1 and 9 before continuing
    # if number < 1 or number > 9: # This would work, too
    if 9 > number < 1:
        return

    # Indexing for lists/tuples is 0-based, so we want a key press of "1" to 
    # actually access element 0, not element 1.
    print(names[number-1])

    # Update this only now - once a valid key press has been processed
    time_last_pressed = time.time() 

def on_release(key):
    if key == keyboard.Key.esc:
        return False # Stop listener

# Collect events until released
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

With the right packages/modules, you could display the player's name on the screen (as opposed to printing it to the console), and play a buzzer sound when a player presses their button.

GordonAitchJay
  • 4,640
  • 1
  • 14
  • 16