[英]How to stop 'enter spamming' in a python reaction timer
我一直在尝试为一个项目制作一个反应计时器来测试反应时间。 它使用“perf_counter”来记录输入前后的时间,以测试按下回车键所需的时间。 问题是回车键可能会被发送垃圾邮件,这使得他们的反应时间似乎为 0.000001 秒。 我制作了一个禁用键盘并在需要时启用它的类。 即使在这种情况下,人们也可以在禁用和启用之间潜入额外的输入按键。 我附上了下面的代码。 任何想法如何防止输入垃圾邮件?
import time, random, msvcrt
from math import log10, floor
def round_sig(x, sig=5):
return round(x, sig-int(floor(log10(abs(x))))-1)
class keyboardDisable():
def start(self):
self.on = True
def stop(self):
self.on = False
def __call__(self):
while self.on:
msvcrt.getwch()
def __init__(self):
self.on = False
import msvcrt
disable = keyboardDisable()
disable.start()
print('When I say __GO__ you hit ENTER! This will happen 3 times. Got it?')
time.sleep(2)
print('Ready')
time.sleep(1)
print('Steady')
time.sleep(random.randint(2,5))
print('#####__GO__######')
disable.stop()
tic = time.perf_counter()
a = input()
toc = time.perf_counter()
if msvcrt.kbhit():
disable.start()
timeSpent = toc-tic
print('Your first time was '+str(timeSpent) + ' seconds')
time.sleep(1)
print('The next one is coming up.')
time.sleep(1)
print('Ready')
time.sleep(1)
print('Steady')
time.sleep(random.randint(2,5))
print('#####__GO__######')
disable.stop()
tic2 = time.perf_counter()
b = input()
toc2 = time.perf_counter()
if msvcrt.kbhit():
disable.start()
timeSpent2 = toc2-tic2
print('Your second time was '+str(timeSpent2) + ' seconds')
time.sleep(1)
print('The last one is coming up.')
time.sleep(1)
print('Ready')
time.sleep(1)
print('Steady')
time.sleep(random.randint(2,5))
print('#####__GO__######')
disable.stop()
tic3 = time.perf_counter()
c = input()
toc3 = time.perf_counter()
timeSpent3 = toc3-tic3
print('Your last time was '+str(timeSpent3) + ' seconds')
average = (timeSpent + timeSpent2 + timeSpent3)/3
numAverage = round_sig(average)
print('Your average time is '+str(numAverage) + ' seconds')
键盘禁用代码从未真正运行。
这是您的程序的简化,它使用一个函数来捕获一个反应时间并调用它三次。
clear_keyboard_buffer()
函数(应该消耗所有未完成的击键)是从https://stackoverflow.com/a/2521054/51685借来的。
import time, random, msvcrt, math
def round_sig(x, sig=5):
return round(x, sig - int(math.floor(math.log10(abs(x)))) - 1)
def clear_keyboard_buffer():
while msvcrt.kbhit():
msvcrt.getwch()
def get_reaction_time():
print("Ready")
time.sleep(1)
print("Steady")
time.sleep(random.randint(2, 5))
print("#####__GO__######")
clear_keyboard_buffer()
tic = time.perf_counter()
a = input()
toc = time.perf_counter()
return toc - tic
print("When I say __GO__ you hit ENTER! This will happen 3 times. Got it?")
time1 = get_reaction_time()
print(f"Your first time was {time1} seconds")
time.sleep(1)
print("The next one is coming up.")
time2 = get_reaction_time()
print(f"Your first time was {time2} seconds")
time.sleep(1)
print("The last one is coming up.")
time3 = get_reaction_time()
print(f"Your first time was {time3} seconds")
average = (time1 + time2 + time3) / 3
print(f"Your average time is {round_sig(average)} seconds")
该方案使用一个线程来启动定时器,而主线程一直在等待输入。 这样,就有可能捕捉到早期的按键按下:
from threading import Thread
import random
import time
def start():
global started
started = None
time.sleep(random.randint(2,5))
print("#### GO ####")
started = time.time()
t = Thread(target=start)
print("ready...")
# start the thread and directly wait for input:
t.start()
input()
end = time.time()
if not started:
print("Fail")
else:
print(end-started)
t.join()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.