psychopy.org | Reference | Downloads | Github

Multiple Correct Response Types Per Trial

I am trying to find a way to code multiple correct response choices for a single trial of a reaction task and I realized that this is something that cannot be done in Builder. I have my code currently set up to call from a column (i.e., corrAns) in an excel file to get the correct response. However, only a single answer can register as a correct response. For example, when the letter “A” appears on the screen, the subject is supposed to press “q.” If the row in the “corrAns” column for the particular column has “q”, then the trial results in a correct response. I would like to program the script where the “q” key as well as the surrounding keys (i.e., capslock, tab, `, 1, 2, w, s, a) would also register as correct. I assume that the following code is what I need to alter:

if probe_resp.keys in ['', [], None]:  # No response was made
        probe_resp.keys=None
        # was no response the correct answer?!
        if str(corrAns).lower() == 'none':
           probe_resp.corr = 1  # correct non-response
        else:
           probe_resp.corr = 0  # failed to respond (incorrectly)

Basically, I want any of those nine key presses to register as “1” in the “probe_resp.corr” column. I have tried inputting the keys as a list (i.e., “[‘q’,‘capslock’,‘tab’,‘grave’,‘1’,‘2’,‘w’,‘s’,‘a’]”) in each row of the “corrAns” column, but that results in a response of “0” in the “probe_resp.corr” column. Please advise with any input you may have.

Thanks!

  • Tatsushi

Please edit your question and format the code properly so that it is legible. Put three backticks (```) on the line before and the line after your code.

Your corrAns variable will be read in as a string:
"['q','capslock','tab','grave','1','2','w','s','a']"

You need to convert it into a Python list object like this:

corrAns = eval(corrAns)

Then you can test whether the key pressed was in that list.

Hi Michael,

Thank you for your response. I realized that I had shared an example of a correct non-response, instead of code a key press response. In any case, I took your advice and converted the “corrAns” as follows:

                if probe_resp.keys == []:  # then this was the first keypress
                    probe_resp.keys = theseKeys[0]  # just the first key pressed
                    probe_resp.rt = probe_resp.clock.getTime()
                    # was this 'correct'?
                    #if (probe_resp.keys == str(corrAns_probe)) or (probe_resp.keys == corrAns_probe):
                    corrAns_probe = str(corrAns_probe)
                    corrAns_probe = eval(corrAns_probe)
                    if probe_resp.keys == corrAns_probe:
                        probe_resp.corr = 1
                    else:
                        probe_resp.corr = 0

Under the section “# was this ‘correct’?” I commented out what was there before, defined corrAns_probe first as a string (because otherwise I got an error stating “TypeError: eval() arg 1 must be a string or code object”). Then I converted it into a Python list object using eval(). However, all key responses, regardless if they were correct, register as “0” in the “probe_resp.corr” column of the output file.

I have attached my script and the excel file with the conditions:
axcpt_prac_trials.psyexp (24.4 KB)
axcpt_practice.xlsx (39.7 KB)
Please let me know if you know what I’m doing wrong.

Thank you very much.

In situations like this, it is useful to find out explicitly what type your variables are. i.e. before changing the type of corrAns_probe, do this:

print(corrAns_probe)
print(type(corrAns_probe)) 

Anyway, assuming corrAns_probe eventually ends up as a Python list object, and that probe_resp.keys is just a single key, it doesn’t make sense to test whether probe_resp.keys == corrAns_probe, because a single string object can never be equal to a list of string objects. Instead, you should check like this:

if probe_resp.keys in corrAns_probe:

Having said that, I’m not really sure of the logic in the code above:

if probe_resp.keys == []:  # ??? if no keys were pushed (i.e. an empty list) ???
                    probe_resp.keys = theseKeys[0]  # make it equal to the first entry in some other list??

but I guess I’m just seeing it in isolation.

Hi Michael,

Thanks for your suggestions, I figured it out! theseKeys was initially set to a list of allowed keys, so I changed that to get any key that was pressed:

theseKeys = event.getKeys()

corrAns_probe was initially in unicode, so I converted it to a python object:

corrAns_probe = eval(str(corrAns_probe))

Then I took your advice and incorporated it as follows:

if len(theseKeys) > 0:  # at least one key was pressed
   probe_resp.keys = theseKeys[0]  # just the first key pressed
   probe_resp.rt = probe_resp.clock.getTime()
   # was this 'correct'?
   if probe_resp.keys in corrAns_probe:
       probe_resp.corr = 1
   else:
       probe_resp.corr = 0

This seems to do the trick. Thanks for your help!