繁体   English   中英

如何在 python 反应计时器中停止“输入垃圾邮件”

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM