| Reference | Downloads | Github

Learning to criterion - consecutively correct trials

Hi everyone, I am creating a task in which participants must learn associations between symbols and sounds. It is a criterion learning task consisting of 10 trials with 3 items each: the experiment ends when participants score full marks on 3 consecutive trials OR when they reach the maximum of 10 trials. I have attached a screenshot of the workflow.


I must state that I’m new to Python, and I’m sure there are more efficient ways of achieving what I want, so any advice is appreciated!

(Straight away before I get into it, I think there might be an issue with the way I’ve set up the inner and outer loops, because the first trial seems to behave differently from subsequent trials when I’m tinkering around)

How I’ve tried to do it: in a code block in ‘trial’, I have the following:

Begin Experiment:
number_correct = 0

End Routine:

if response.corr:
    number_correct += 1
    number_correct = 0

So number_correct will increase by 1 if the answer is correct. Otherwise, it will go back to 0.

That’s fine, and number_correct is displayed in ‘score’ after each repeat so I can keep an eye on it. However, the problem is that number_correct also needs to go back down to zero if a participant doesn’t get full marks in a trial (in other words, if they score 1, I don’t want that 1 to be carried over to the next trial).

I’ve tried to do this below, in End Routine (but as hinted at above, it doesn’t seem to work for the first trial):

if innerLoop.thisN == 2 & number_correct < 2:
    number_correct = 0
    number_correct = number_correct

I.e. if the score in the 3rd item of a trial (innerLoop.thisN == 2) is less than full marks (number_correct < 2), then the score reverts to zero.

That also seems to work.

Now the final piece of code, in End Routine:

if number_correct >= 8:
    outerLoop.finished = True
    outerLoop.finished = False 

The problem: the experiment finishes after 3 trials, regardless of the value of number_correct.

I have tried many different things and searched on this forum, but I have hit a brick wall. Any help sorely appreciated.


This is a little more complicated than it looks. So each “trial” is actually three responses, and what you’re trying to do is check if the score is equal to or greater than than 9 after three trials. Am I right in interpeting this as saying you see the score after every response, and you’re pretty sure that the score is increasing and decreasing when you expect it to? As in, you have run tests where you can see that number_correct is less than 9 and it still ends the outer loop?

Assuming I’m getting all that correctly, then the issue is most likely something in the settings of outerLoop. More specifically, my guess is that your final piece of code here, that controls the outerLoop ‘finished’ status, is being overridden. What are the settings of outerLoop? Repetitions?

Hi Jonathan,
Thanks for your reply. You were right in that the score wasn’t resetting when I expected it to. I’ve managed to make it work, and I thought I’d post the code here in case it helps anybody out.

I have two criteria for ending the experiment:
(1) Scoring full marks (3/3) on 3 consecutive trials, OR
(2) Reaching 10 trials without fulfilling (1)

So I have counters in the ‘Begin Experiment’ box of ‘trials’ to count up these two things:

myTrials = 0

number_correct = 0

Each subsequent trial should add 1 to myTrials, but it should only add 1 to number_correct if the score is correct. So in the ‘End Routine’ box of trials, I have the following code:

if response.corr:
    number_correct = number_correct + 1
    number_correct = 0

So as the experiment goes on, it keeps track of the total number of loops attempted (3 in a trial), as well as the total number of correctly answered items.

Crucially, this code puts number_correct back to zero if full marks aren’t achieved in a trial (of 3 loops):

if innerLoop.thisN == 2 and number_correct < 3:
    number_correct = 0

This is super important for me, because otherwise a score of 2/3 correct in one trial would carry over to the next trial - I don’t want this: instead, I want the score to drop back down to zero if it isn’t 3/3 by the end of a trial. This code seems to do the job.

Now I also have the following if-elif-else statement in ‘End Routine’ which tells PsychoPy when to end the routine:

if number_correct >= 9:
    outerLoop.finished = True 
elif myTrials >= 30:
    outerLoop.finished = True 
    outerLoop.finished = False

Like I say, this seems to work for me!