Code works when key pressed but crashes when no key pressed

Hi everyone,

Hope you are well. I would appreciate it if anyone has any insight on this.

I’m trying to create an experiment in which participants are making a decision between two probabilities and two monetary values. They click the key ‘A’ to choose the option on the left and ‘K’ for the option on the right. This is what they see in the ‘Choice’ routine:

image

Based on their response, we’re trying to provide feedback by bolding the options on the left if ‘A’ is clicked and bolding the options on the right if ‘K’ is clicked. In order to do this we created another ‘Highlight’ routine that follows the ‘Choice’ routine which has the same components as the choice routine (i.e., probabilities and monetary values but no key press componenet) but changes font in a way to provide feedback using code that I pasted in the Begin Routine section of the code component:

keyPressed = event.getKeys()[0]
if keyPressed == ‘a’:
P1_2.setFont(‘Arial Black’)
M1_2.setFont(‘Arial Black’)
P2_2.setFont(‘Arial’)
M2_2.setFont(‘Arial’)
Elif keyPressed == ’k’:
P2_2.setFont(‘Arial Black’)
M2_2.setFont(‘Arial Black’)
P1_2.setFont(‘Arial’)
M1_2.setFont(‘Arial’)

While this code works fine in bolding the right or left options when a key is pressed (i.e., either A or K), the program crashes when no key is pressed. My routine is set to a 6 second time deadline, so when no key is pressed after 6 seconds, I’d want to see nothing highlighted as a way to give them no feedback. How would I add that piece of code to what I currently have?

I appreciate the help.

Best,
Aalim

Hello Aalim

it is better to surround your code by triple ` because then it is properly formatted. I doubt that the code you pasted above runs because there is a typo: Elif ... instead of elif .... BTW you only need to update the parts that you intend to change.

Could check whether no key was pressed either by checking the length of keyPressed, should be 0. If ‘a’ and ‘k’ are the only keys you allow, simply add an else: ... to your if-construction.

Best wishes Jens

3 Likes

Thanks for the reply @JensBoelte and for the suggestions.

I ended up wrapping this bit of code in a try/catch because I was getting some errors related to Cannot read property of length of undefined. (Pasted below).

This is what I have right now but it skips the highlighting routine entirely however my data and reaction time of keys pressed is collected.

try {
	keyPressed = event.getKeys()[0];
	if (keyPressed.length > 0) {
		if ((keyPressed === "a")) {
			P1_2.setFont("Arial Black");
			M1_2.setFont("Arial Black");
			P2_2.setFont("Arial");
			M2_2.setFont("Arial");
		} else if ((keyPressed === "k")) {
			P2_2.setFont("Arial Black");
			M2_2.setFont("Arial Black");
			P1_2.setFont("Arial");
			M1_2.setFont("Arial");
		}
	}
} catch (e) {}

I’m not sure why it’s skipping this routine when I do press keys.

Best,
Aalim

Hello Aalim

try something along the following lines (Python):

if key_resp.cor:
    if 'a' in key_resp.keys:
        P1_2.setFont("Arial Black")
        M1_2.setFont("Arial Black")
    elif 'k' in key_resp.keys:
        P2_2.setFont("Arial Black")
        M2_2.setFont("Arial Black")
else:
    continueRoutine = False

You might need to replace key_resp with the name of your keyboard-component.

Best wishes Jens

Hi Jens,

Thanks for your help with this code. I really appreciate it.

I edited the code a bit and used this by pasting it in the Begin Routine section of the code component:

if key_resp.keys:
    if 'a' in key_resp.keys:
        P1_2.setFont("Arial Black")
        M1_2.setFont("Arial Black")
        P2_2.setFont("Arial")
        M2_2.setFont("Arial")
        
    elif 'k' in key_resp.keys:
        P2_2.setFont("Arial Black")
        M2_2.setFont("Arial Black")
        P1_2.setFont("Arial")
        M1_2.setFont("Arial")
else:
    continueRoutine = False

While this works perfectly fine locally on my computer, when I run it in local debug mode or after syncing it on pavlovia (basically in the browser) – it works when no keys are pressed but for some reason will use the response of the previous trial on a following trial if no key is pressed on the following trial. So if I pressed ‘a’ on trial one and nothing on trial two then the feedback for trial two and the following trials is ‘a’ when nothing is pressed until ‘k’ is pressed.

Note: Data is collect only for the keypresses but not for the trials where the feedback is provided without a key being pressed (eg - the following trials in the example above). So it seems like on pavlovia when no response is given, it uses the previous response to highlight the answer.

I set it the code to Auto → JS in the code component since I’m trying to have this working on Pavlovia.

Here is the link to the study. I would appreciate your guidance on this.

https://run.pavlovia.org/MADlab/test

Best,
Aalim

EDIT: fixed formatting. Code used in PsychoPy was the correct one.

Hello Aalim

there is an error in the code you pasted. M2_2.setFont(“Arial”) is followed by ‘’’ which it should not. Also, the indentation is incorrect. Check the difference in formatting of your code and my code.

I can replicate the behavior you describe following your link. A look in your code/program is more helpful :wink:

You could extend the else:-branch and specify the desired formatting there:

else:
    P1_2.setFont("Arial")
    M1_2.setFont("Arial")
    P2_2.setFont("Arial")
    M2_2.setFont("Arial")

You could also test explicitly for trials in which no response is given

elif key_resp.keys is None:
....

Best wishes Jens

1 Like

Hi Jens,

Thanks for your message. That was an error on my part when I pasted it here, however, it was pasted correctly in PsychoPy.

I tried both of the the suggestions with the else and the elif code. These are the two codes that I tried:

if key_resp.keys:
    if 'a' in key_resp.keys:
        P1_2.setFont("Arial Black")
        M1_2.setFont("Arial Black")
        P2_2.setFont("Arial")
        M2_2.setFont("Arial")
    elif 'k' in key_resp.keys:
        P2_2.setFont("Arial Black")
        M2_2.setFont("Arial Black")
        P1_2.setFont("Arial")
        M1_2.setFont("Arial")
    else:
        P1_2.setFont("Arial")
        M1_2.setFont("Arial")
        P2_2.setFont("Arial")
        M2_2.setFont("Arial")
else:
    continueRoutine = False
if key_resp.keys:
    if 'a' in key_resp.keys:
        P1_2.setFont("Arial Black")
        M1_2.setFont("Arial Black")
        P2_2.setFont("Arial")
        M2_2.setFont("Arial")
    elif 'k' in key_resp.keys:
        P2_2.setFont("Arial Black")
        M2_2.setFont("Arial Black")
        P1_2.setFont("Arial")
        M1_2.setFont("Arial")
    elif key_resp.keys is None:
        P1_2.setFont("Arial")
        M1_2.setFont("Arial")
        P2_2.setFont("Arial")
        M2_2.setFont("Arial")
else:
    continueRoutine = False

I tried both of these separately in PsychoPy. Both of these codes work perfectly fine and don’t glitch as mentioned earlier when run locally but on Pavlovia it selects an option even when there is no key press on trial that follows one with a key press. I checked the console as well to check that the code was updating every time I synced it with Pavlovia.

I set the code type to Auto → JS as well as Python when syncing with Pavlovia but neither of this fixes it. I’m not sure why this is happening because I think the code logically makes sense and that’s why it runs locally on PsychoPy.

I appreciate your time and help.

Best,
Aalim

Hello Aalim

do you mind uploading the relevant *psyexp (including .xlsx/.csv-files) or give access to your repository?

Best wishes Jens

1 Like

Hi Jens,

Thank you, I have sent you a message with the required files.

Best,
Aalim

In this code:

if key_resp.keys:
    if 'a' in key_resp.keys:
        P1_2.setFont("Arial Black")
        M1_2.setFont("Arial Black")
        P2_2.setFont("Arial")
        M2_2.setFont("Arial")
    elif 'k' in key_resp.keys:
        P2_2.setFont("Arial Black")
        M2_2.setFont("Arial Black")
        P1_2.setFont("Arial")
        M1_2.setFont("Arial")
    else:
        P1_2.setFont("Arial")
        M1_2.setFont("Arial")
        P2_2.setFont("Arial")
        M2_2.setFont("Arial")
else:
    continueRoutine = False

The first line if key_resp.keys: checks if any key is pressed. If the only possible keys are ‘a’ or ‘k’, then the else: part that resets the font will never run.

To get rid of that if key_resp.keys: part, just switch to using ‘==’ instead of ‘in’:

if key_resp.keys == 'a':
    P1_2.setFont("Arial Black")
    M1_2.setFont("Arial Black")
    P2_2.setFont("Arial")
    M2_2.setFont("Arial")
elif key_resp.keys == 'k':
    P2_2.setFont("Arial Black")
    M2_2.setFont("Arial Black")
    P1_2.setFont("Arial")
    M1_2.setFont("Arial")
else:
    P1_2.setFont("Arial")
    M1_2.setFont("Arial")
    P2_2.setFont("Arial")
    M2_2.setFont("Arial")

This way the font is reset if no key is pressed, or if a different key is allowed. Also, continueRoutine = False doesn’t do anything here, so just remove it.

I think Python tolerated this logic because the font is automatically reset there, but not in Javascript, which might be a bug in PsychoJS, not sure.

1 Like

Hi Arnon,

Thank you so much for the solution. This solves the issue that we were facing and the feedback is provided correctly on Pavlovia.

Best,
Aalim