-
-
Save seankmartin/f660eff4787b586f94d5f678932bcd27 to your computer and use it in GitHub Desktop.
@echo off | |
python -m PyInstaller ^ | |
--noconfirm --log-level WARN ^ | |
--onefile --nowindow ^ | |
--name KeyTime ^ | |
cli.py |
from keyboardpress import main | |
if __name__ == "__main__": | |
main() |
import pygame | |
import datetime | |
import time | |
def text_to_screen( | |
screen, text, x, y, size=50, color=(000, 000, 000), font_type="Comic Sans MS" | |
): | |
try: | |
text = str(text) | |
font = pygame.font.SysFont(font_type, 12) | |
text = font.render(text, True, color) | |
screen.blit(text, (x, y)) | |
except Exception as e: | |
print("Font Error, saw it coming") | |
raise e | |
def print_info(screen, keys, key_strs, times): | |
for i, (key, e_time, key_str) in enumerate(zip(keys, times, key_strs)): | |
print_str = "Time {}, key {}:".format(i + 1, key_str) | |
text_to_screen(screen, print_str, 20, 20 * (i + 1)) | |
print_str = "Elapsed time(s) {:.2f}".format(e_time) | |
text_to_screen(screen, print_str, 140, 20 * (i + 1)) | |
text_to_screen(screen, "Press End to reset", 20, 20 * (len(keys) + 2)) | |
def save_times(times, key_strs, ctrs, filename=None): | |
now = datetime.datetime.now() | |
whole_time = now.strftime("%Y-%m-%d--%H-%M-%S") | |
filename = f"pytimer_count_{whole_time}.csv" | |
print("Saving current times to {}".format(filename)) | |
with open(filename, "w") as f: | |
f.write("Number,Key,Time(s)\n") | |
for i, (e_time, key_str) in enumerate(zip(times, key_strs)): | |
f.write("{},{},{:.4f}\n".format(i + 1, key_str, e_time)) | |
filename = f"pytimer_timestamps_{whole_time}.csv" | |
print("Saving timestamps to {}".format(filename)) | |
with open(filename, "w") as f: | |
f.write("Number,Key,Time(ms)\n") | |
for i, (key_str, e_time) in enumerate(ctrs): | |
f.write("{},{},{:.4f}\n".format(i + 1, key_str, e_time)) | |
def main(): | |
background_colour = (255, 255, 255) | |
(width, height) = (300, 200) | |
pygame.init() | |
screen = pygame.display.set_mode((width, height)) | |
pygame.display.set_caption("Keypress Timers") | |
screen.fill(background_colour) | |
pygame.display.flip() | |
running = True | |
clock = pygame.time.Clock() | |
key_strs = ["A", "S", "D", "Left", "Down", "Right"] | |
keys = [ | |
pygame.K_a, | |
pygame.K_s, | |
pygame.K_d, | |
pygame.K_LEFT, | |
pygame.K_DOWN, | |
pygame.K_RIGHT, | |
] | |
times = [0 for _ in keys] | |
counters = [0 for _ in keys] | |
time_log = [] | |
start_time = time.time() | |
while running: | |
for event in pygame.event.get(): | |
if event.type == pygame.QUIT: | |
running = False | |
pygame.quit() | |
break | |
if event.type == pygame.KEYDOWN: | |
for i, key in enumerate(keys): | |
if event.key == key: | |
counters[i] = time.time() | |
ctr_adj = counters[i] - start_time | |
ctr_adj_ms = ctr_adj * 1000 | |
time_log.append((key_strs[i], ctr_adj_ms)) | |
print(f"Pressed key {key_strs[i]} at time {ctr_adj_ms:.0f}ms") | |
if event.key == pygame.K_END: | |
save_times(times, key_strs, time_log, None) | |
times = [0 for _ in keys] | |
counters = [0 for _ in keys] | |
start_time = time.time() | |
if event.type == pygame.KEYUP: | |
for i, key in enumerate(keys): | |
if event.key == key: | |
counters[i] = time.time() - counters[i] | |
times[i] += counters[i] | |
ms_counter = 1000 * counters[i] | |
print(f"Held key {key_strs[i]} for {ms_counter:.0f}ms") | |
screen.fill(background_colour) | |
print_info(screen, keys, key_strs, times) | |
pygame.display.update() | |
clock.tick(60) | |
save_times(times, key_strs, time_log, None) | |
if __name__ == "__main__": | |
main() |
# This small python script with build script times the length of keypresses |
Hi, I have updated the gist so it should do what you are looking for. You can set the beginning of the experiment by pressing End (a button which can be rebound on line 86 pygame.K_END
).
If you are specifically looking to use keys 1, 2, 3, 4, and space - you just need to rebind them in the lists on lines 59 and 60, like so:
key_strs = ["1", "2", "3", "4", "Space"]
keys = [pygame.K_1, pygame.K_2, pygame.K_3, pygame.K_4, pygame.K_SPACE]
Thanks for your reply. I tried this earlier. The experiment ran, but I am still unable to access the timeline corresponding to keypresses. Under which heading (variable name) the keypress timeline is supposed to appear in the output CSV file?
There should be two separate output files that are named pytimer_count_{current-time}.csv and pytimer_timestamps_{current-time}.csv
The timeline of keypresses should be in the latter file (heading Time (ms))
I am running this script as an inline python script (titled "KeypressTimeline") in OpenSesame.
Oh I understand now sorry, I missed that
It didn't generate any separate output file other than the main experiment CSV file where it logs all data related to the experiment.
I'm not very familiar with opensesame, so I'm not sure if it can run a pygame based python script inside of it? Because this uses pygame to record the keypresses.
If you run this script by itself outside of opensesame using just python you should see a window pop up, I don't know if this window pops up in opensesame and the window is needed!
Most likely (?) keyboard capturing from opensesame would need to be used instead
There is no such pop-up window appearing. And even if it will, it will create disturbance during the experiment administration (for the participant). I think I should figure it out some other way.
Thank you for giving your time!
No worries at all, best of luck!
Hi, do you know the code for getting a timeline for each keypress (1, 2, 3, 4, space)? For example, key 1 pressed at 12223ms, key 3 at 15452ms, key 1 again at 19112ms. I need to keep track of all these keypresses (11223ms, 15452ms, 19112ms, etc.) from the beginning of the experiment in OpenSesame/Psychopy, which runs on python.