event.waitKey() only returns second pressed key

OS (e.g. Win10):
PsychoPy version 2020.2.10
Standard Standalone? (y/n) yes
What are you trying to achieve?:
I’m trying to make an experiment where the participant sees an equation who’s answer will always be between 0 and 9. The participant then needs to press a number on the keypad and if the correct/incorrect response is given, the participant receives specific feedback.

I APOLOGISE IN ADVANCE FOR THE HORRIBLE FORMATTING, I CAN’T UPLOAD MORE THAN 2 PICTURES AS A NEW USER. I COULD BRUSH UP (hehe) ON MY PAINT SKILLS HOWEVER, WHICH IS NICE

What did you try to make it work?:
I built the following very basic experiment (see fig. 1):

with the following conditions file (see fig. 2):

which loads correctly (see fig. 3):

The first slide shows the equation, this works correctly (see fig. 4 and 5):

and a keyboard object is also present with the following settings (see fig. 6):

The second routine in the loop has the following components (see fig. 7):

So basicly a code object which will check if the pressed key is the same as the “answers” in the conditons file. and a text object which will show the message that is created in the code block. The code is the following (see fig. 8):

What specifically went wrong when you tried that?:

This experiment does not crash, but I need to press 2 keys before the feedback is triggered. I know this happens because when I look at the generated data file i see that two key presses are registered. An example where I press the same key twice (Fig. 9):

And an example where I first press the wrong key and afterwards the correct key (see Fig1 10):

results in the program thinking that the correct response has been pressed. What am I doing wrong and how can I make sure that the first pressed key is the one that will be evaluated?

THINGS I TRIED:

  • place the code in the “each frame” part → CRASH

Many thanks in advance, wonderful product you guys made!

Alright, I solved it myself. The problem is in the coding part of the feedback slide (fig. 8).

The line “key= event.waitKeys()” does not look for the key that has been pressed in the previous routine but will register the first one that is pressed after the previous routine has been ended (which is done by the first keypress). The correct solution instead is the following line:

key = keyboard_resp.keys[0]
keynumber = key[-1] #get only the number

and then use keynumber for further logic.

I’ll leave this up so that it may help somebody in the future.

1 Like

You should never use event.waitKeys() in a Builder experiment. It is only intended for use by people coding their own experiments from scratch, and who understand the implications of suspending execution until a response is made. Builder scripts inherently assume that the screen is being actively drawn to, and that responses are being checked for, on every screen refresh (typically 60 times per second). By calling this function, you are interrupting that active drawing cycle for an indeterminate period of time, which could result in many unintended consequences with regards to timing and performance.

Simply use Builder’s own Keyboard component (which has better performance than the deprecated event module anyway), which also works online (where the event module doesn’t exist).

I haven’t yet had a report of the new keyboard class working in a code component online. event.getKeys() does work if you define event in code_JS as per my crib sheet.

Just to be sure, my correction is the right way to go then?

You may need keynumber = int(key[-1]) if you want to treat the response as a number rather than a string ( == 1 as opposed to == '1' )

Hence why I suggested using the Builder component, and not using code. Builder will generate the appropriate code for each platform.

The OP is using .waitKeys().

1 Like

The response is being read from an .csv file, so I have no clue if it is being read as a string or as an integer. It currently works with the code I’m using, but I’ll check it with int(key[-1]), thanks for the tip!