Provide feedback for randomized stimuli within a trial

Hi all,

I am setting up an experiment where participants will have to select one of two stimuli (in this case, two different pictures: Rome or Paris). The thing that I would like to do is for my code to determine randomly a “correct” answer on every trial (either Paris or Rome) and then provide participants with feedback based on their keyboard answers (keys: R = Rome; P = Paris)

I’ve used the following code as a model: https://www.psychopy.org/recipes/builderFeedback.html#feedback-after-a-trial

So basically what I’ve done is that I’ve added this piece of code at the very beginning of the experiment:

msg='doh!'#if this comes up we forgot to update the msg!

And then added this at the prepare routine “Feedback” part:

if not key_resp.keys :
    msg="Failed to respond"
elif resp.corr:#stored on last run routine
    msg="Correct!
else:
    msg="Oops! That was wrong"

And created a ‘conditions.xls’ file with a column for cities (Rome and Paris) and CorrAns (R and P, respectively).

Unfortunately, and regardless of what key I press on every trial, I always get the “doh!”, which means that my code is not updating the message. Maybe because it simply doesn’t know what the correct answer is, so it cannot update it?

This is the part of the code where I define the two “correct” answers P and R:

if key_resp.status == STARTED:
            theseKeys = key_resp.getKeys(keyList=['p','r'], waitRelease=False) 
            if len(theseKeys):
                theseKeys = theseKeys[0]  # at least one key was pressed

# check for quit:
if "escape" == theseKeys:
    endExpNow = True
key_resp.keys.append(theseKeys.name)  # storing all keys
key_resp.rt.append(theseKeys.rt)

# was this 'correct'?
if (key_resp.keys == str(corrAns)) or (key_resp.keys == corrAns):
    key_resp.corr = 1
else:
    key_resp.corr = 0

Thanks in advance!

We don’t need to see the code from the generated script, just the custom code you have in your code components, as well as the settings of your stimulus components.

In the absence of the latter, I’m going to guess the issue is simply that you have the text field of your text stimulus component set to be “constant” rather than to “set every repeat”, so that it never gets updated from the initial value. NB the code component also needs to be above the text stimulus, so that it gets the latest calculated value of msg, current as for this trial.

Hi Michael,

Thanks! You were right. I’ve now changed the text stimulus component from “constant” to “set every repeat”, and I’m now getting the msg doh! only during the first iteration (which makes sense, since the code can only be updated with a value from the last routine), but then, in all the trials that follow, I get the message Oops! That was wrong!, which means that there’s still something missing in my code.
I guess that I still need to somehow specify the correct or wrong answer for every trial. However, I’m precisely struggling with that, since I want my code to randomly set a “correct” answer (either Paris or Rome) on every trial.
Any help with this will be appreciated!

You’re currently referring to a variable called corrAns for that purpose. Presumably this comes form a conditions file. That would be the normal way of doing this.

But also note that in your custom code, you are referring to two different objects (key_resp and resp) when you test the response. That is going to be causing issues…

I’ve created a conditions.xlsx (22.3 KB) file, where I have two columns: “cities” with two elements: paris and rome, and “corrAns” with two elements (keys): p and r (p corresponds to the correct answer for paris, r the correct answer for rome)
What I would like to do is for my code to randomly set one of these two cities (rome or paris) as the correct answer for a trial, so that if the correct answer for trial 1 is paris and you press r, you get the msg = Oops! That was wrong!, but if your press p you’d get the msg = Correct!

And yes, you’re right. I’ve copied the code component from the documentation. The one I’ve actually written is the following one:

    
if not key_resp.keys :
     msg="Failed to respond"
elif key_resp.corr: #stored on last run routine
     msg="Correct!"
else:
     msg="Oops! That was wrong"

Your conditions file and the loop settings should express your design. I don’t know what function the “cities” column provides, as I think you show stimuli for both cities on each trial. But in essence, each row of the file should correspond to the information you need to specify a given trial. For example, for a typical design, your file could look like this:

left_image    right_image     corrAns
rome.jpg      paris.jpg       r
rome.jpg      paris.jpg       p
paris.jpg     rome.jpg        r
paris.jpg     rome.jpg        p

i.e. here we have crossed two possible stimulus locations with the two possible correct answers to get all four possible conditions. You then set an nReps value in the loop dialog to get the number of trials you want (e.g. an nReps of 5 would yield 20 trials). And then set the loop type to be “full random” to get a randomised order.

To get a grip on these basics of using PsychoPy, you should probably watch Jon Peirce’s Stroop task tutorial:

Thanks a lot Michael. This was very helpful. Now I understand that I need to specify each possible combination of stimuli location with correct answer in the excel file.
The thing I’m not sure how to do is how to tell my code that the heading of the the column in the excel file, i.e. left_image, corresponds to the picture of the city on the left for that particular trial, and that right_image corresponds to the picture on the right.
Thanks again!

I’ve tried two solutions for the problem I’m now facing (reminder: I want participants to see two pictures on every trial and randomize which of the two is the correct one. Also, participants will receive immediate feedback after selecting one of the pictures)

1st solution: I’ve followed Michael’s advice and created an excel file (see post above) where every row corresponds to one condition, like this:
image

This however doesn’t seem to work. Regardless of whether I press “p” or “r”, I always get the feedback message Oops! That was wrong!

2nd solution: I’ve followed cnhstreet’s advice …

Randomly displaying an image within a loop - #4 by cnhstreet

…where he first suggests to create a list with both images, so that’s what I did:
city_list=['images/paris2.png','images/rome2.png']

Then I changed the image stimuli so that they refer to one of the two elements in city_list:

city1 = visual.ImageStim(win=win,image= city_list[0]) #0 first element in city_list
city2 = visual.ImageStim(win=win,image= city_list[1]) #1 second element in city_list

And also changed the excel file, so now it looks like this:
image

But again, whenever I run the code, and regardless of the answer (p or r) I only get the message Oops! That was wrong!

Any idea of what’s wrong? Most of the tutorials I’ve seen use different words and color, where you can easily use variables to tell your code what to look for in the excel file. For some reason this doesn’t seem to be working when displaying two images…

Thanks!

I managed to find the solution. The reason why both solutions were not working was because I was storing “all keys”. But in order for the feedback to work, the code needs to have a single answer. I modified this, so that my code only stores the last key pressed, and it’s working perfectly:

#check for quit:
if "escape" == theseKeys:
    endExpNow = True
key_resp_1.keys = theseKeys.name  # just the last key pressed
key_resp_1.rt = theseKeys.rt

Just a note that everything described above is able to be achieved in the Builder graphical interface, with no custom code whatsoever. These days, even experienced PsychoPy users will often user Builder do most things and only add small snippets of custom code via graphical “code components” if required.