Hello,
I am trying to create a task where participants execute either a forced-choice or a free-choice response. Responses are either the double-press of the f key or the double press of the k key.
In forced-choice conditions, if they see a H they are to press the f key twice as fast as possible, if they see an X they are to press the k key twice as fast as possible.
In free-choice conditions an O appears which requires either a speeded double press of the f key or the k key.
I am having trouble figuring out how to log a correct response in free-choice conditions where the response could be âffâ or âkkâ.
So far I created a variable âbcorrâ which I list as the Correct Answer in builder and I created the following if statements to identify correct response for free-choice and forced-choice conditions, but this is not working. Wondering if anyone has any solutions for recording correct responses for free-choice conditions.
My code:
In the âBegin Experimentâ tab I declare the new variable Bcorr =
In the âBegin Routineâ tab I have the following if statements
if forced_free == âfreeâ and Bresp1.keys == correctAnsB21 or correctAnsB22:
bcorr = 1
elif forced_free == âforcedâ and Bresp1.keys == correctAnsB21:
bcorr = 1
else:
bcorr = 0
if bcorr == 1:
Bresp1.corr = 1
else:
Bresp1.corr = 0
Attached are screenshots of my design as well.


Hello
there are some posts in the forum about multiple correct answers. You might want to look there
https://discourse.psychopy.org/search?q=multiple%20correct%20answers
is incorrect. The syntax is as follows:
if forced_free == âfreeâ and Bresp1.keys == correctAnsB21 or Bresp1.keys == correctAnsB22:
Best wishes Jens
1 Like
Danke fĂźr den Vorschlag Jens! Strangely the code works when it is written as follows and the correct answer is set to bcorr:
if forced_free == âforcedâ and Bresp1 == correctAnsB21:
bcorr = 1
elif forced_free == âfreeâ and Bresp1 == correctAnsB21 or correctAnsB22:
bcorr = 1
else:
bcorr = 0
But the code does not work when wrote as you suggested.
I added another if statement that should record the response as correct (Bresp1.corr == 1) when bcorr == 1, but this second if statement is not working, so although the feedback reports the response as correct and shows the RT, the data file column for Bresp1.corr is all 0s.
Second if statement that does not work is:
if bcorr == 1:
Bresp1.corr = 1
else:
Bresp1.corr = 0
Any thoughts on why this second if statement is not coding Bresp1.corr as 1?
Vielen dank!

Hello,
ok, I still donât think that the code
elif forced_free == 'free' and Bresp1 == correctAnsB21 or correctAns ...
works. This is syntactically wrong. You could add print-statements to the if-elif-condition to check whether the condition was met.
...
elif forced_free == 'free' and Bresp1 = correctAnsB21 or correctAns ...
bcorr = 1
print("elif is true")
Anyway, with regard to the second question. Simply add
Bresp1.corr = 1
to the respective if/elif-statement.
if forced_free == 'forced' and Bresp1 == correctAnsB21:
bcorr = 1
Bresp.corr = 1
....
Best wishes Jens
1 Like
Thank you for the advice Jens.
I meant to mention before, I am running MacOS Catalina 10.15.7, and PsychoPy v2023.2.3.
I rewrote my code as you suggested and it does seem to be coding free-choice responses accurately for the most part. I also added a statement in the End Routine tab to record the coded variable bcorr into the data to show when the responses was coded as correct.
However I am still having some strange issues with responses being coded wrong. I have not been able to find a solution for the following issues:
1.) Every first response is coded incorrect.
2.) Some responses I know are correct are coded incorrect (see data sheet attached).
3.) In the data sheet, bcorr is coded correct sometimes when one responses is given (should be incorrect because two presses are required).
4.) The if statement is not updating the Bresp.corr variable.
Any tips on how to resolve these issues would be greatly appreciated.
Thanks very much!
Hello
Do you mind posting code surrounded by triple ` instead of screenshots? How do you end a trial? Canât key-press.
BTW, the error-checking routine has to follow the reaction. So it has to go in the End Routine tab, not the Bgin Routine tab.
Best wishes Jens
Hello @richar3636
Ok, place a code-element at the bottom of your respective routine. In the Begin Experiment tab of the code-element add a line to initialise your variable.
correct = 0
In the End Routine tab, add the following code
if Bresp1.keys:
if len(Bresp1.keys) > 1:
if cond == "forcedX":
if Bresp1.keys == ['k','k']:
correct = 1
else:
correct = 0
elif cond == "forcedH":
if Bresp1.keys == ['f','f']:
correct = 1
else:
correct = 0
elif cond == "free":
if Bresp1.keys == ['f','f'] or Bresp1.keys == ['k','k']:
correct = 1
else:
correct = 0
else:
correct = 0
thisExp.addData('correct',correct)
Notice, I differentiate between the condition forcedX, the condition forcedH and the condition free. I coded the conditions in an Excel-file in a column named cond. I did not code the correct answers in the condition-file as this would require two columns.
loopDoubleKey.xlsx (18.0 KB)
I have found this to be simpler and you may want to analyse the X, H and O conditions anyway.
Best wishes Jens
1 Like
Wow this code works great! Thanks so much Jens!
I added len(Bresp1.keys)
to limit button presses to 2.
Regarding ending trials. Currently I have it set to a 1.5 second time limit but I would like to end the routine as soon as the second press of the response is made. I added continueRoutine = False
to the if statements, but this does not seem to be effective. I have also read in other posts folks having issues with continueRoutine(). Is there a way to end a routine as soon as the second button press is made?
My code now adjusted to be consistent with your suggestions is as follows (located in the End Routine tab):
if Bresp1.keys:
if len(Bresp1.keys) > 1:
if forced_free == "forcedX":
if Bresp1.keys == ['k','k'] and len(Bresp1.keys) < 3:
Bcorrect2 = 1
Bresp1.corr = 1
continueRoutine = False
else:
Bcorrect2 = 0
Bresp1.corr = 0
continueRoutine = True
elif forced_free == "forcedH":
if Bresp1.keys == ['f','f'] and len(Bresp1.keys) < 3:
Bcorrect2 = 1
Bresp1.corr = 1
continueRoutine = False
else:
Bcorrect2 = 0
Bresp1.corr = 0
continueRoutine = True
elif forced_free == "free":
if len(Bresp1.keys) < 3 and Bresp1.keys == ['f','f'] or Bresp1.keys == ['k','k']:
Bcorrect2 = 1
Bresp1.corr = 1
continueRoutine = False
else:
Bcorrect2 = 0
Bresp1.corr = 0
continueRoutine = True
else:
Bcorrect2 = 0
Bresp1.corr = 0
continueRoutine = True
thisExp.addData('Bcorrect2',Bcorrect2)
Thanks very much!
Hello
you could add the following code to the Each frame-tab.
if Bresp1.keys:
if len(Bresp1.keys) == 2:
continueRoutine = False
Note that with this approach, the routine will only end after two key presses, unless you add an additional constraint, such as a time limit. Without a time limit, the routine would not end with just one key press.
The condition len(Bresp1.keys) < 3 becomes obsolete with this approach.
You donât need continueRoutine = True as this is always true unless you set it to False.
Best wishes Jens
2 Likes
Thanks for your help Jens. It seems that if I apply the continueRoutine == False
code, it still takes a brief period to end the routine before allowing the next response (another key sequence the participant was remembering) and it seems to count a response correct if more than two presses were made.
If I comment out the continueRoutine == False
code and retain the len(Bresp1.keys) < 3
code in the if statement in the End of Routine tab, this correctly marks responses greater than 2 keypresses incorrect, but participants have to wait for the routine to end (whatâs left of the 1 second response time window).
Is there a way to ensure only responses of two key presses are counted correct (responses > 2 key presses should be incorrect) and the routine ends immediately after the second key press is made so the next response can be made? Ideally the double key press response and the next response should be made almost as if they are one large key sequence.
Greatly appreciate your help!
Hello
please open a new thread when you have a new question as this has been marked as solved. It appears to me that this a an additional requirement given that the experiment is running as expected, am I correct?
Best wishes Jens
2 Likes
Hello,
Yes no problem. The experiment is running smoothly. I will make a new post for the continueRoutine issue if I am unable to resolve it myself. Thanks very much for the assistance!