Psychopy Ending Loop When Unwanted on Pavlovia

Description of the problem:
In my experiment I am trying to end a loop and skip a routine when participants score at least 80% on a quiz.
The layout looks like this:

The goal is to skip the FailedQuiz routine and end the trials_4 loop if they get 80% on LexQuiz.

In order to do this I have put a code component in LexQuiz that says (for JS)
In Each Frame (sets up a variable for counting number correct)
if ((trials_3.thisN === 0)) {
number_correct = 0;
}

In End Routine (adds to variable if correct, and checks at the end of quiz for score, then ends loop)
if ((key_resp_3.corr)) {
number_correct = (number_correct + 1);
}
if ((trials_3.thisN === 24)) {
if (((number_correct / 25) >= 0.8)) {
trials_4.finished = true;
}
}

I have also put a code component in Failed Quiz that says
In Each Frame:
if ((trials_4.finished = true)) {
trials.finished = true;
skipThisTrial = true;
continueRoutine = false;
}

The code is working fine in PsychoPy, but when I try to run the experiment on Pavlovia, it breaks.
When the score on the quiz is below 80, instead of showing the FailedQuiz page and then going back to the beginning of the loop, it skips to the page that says they passed.
I don’t see why it is skipping these pages in the code.

.thisN doesn’t work online

So what would I change those to instead?

You need a loop counter. e.g. loopIdx = -1 in Begin Experiment and loopIdx+=1 in Begin Routine.

The problem with putting a loop counter in the Begin Experiment section, though, is that this loop counter needs to be reset back to 0/-1 whenever the the Quiz is started again. Say for example, they fail the first time, they will be taken back to a previous stage and then will come back to the quiz. This time, however, the counter will still be at wherever it left off the previous time, not reset to 0.

Is there a way to reset the counter without calling .thisN or other broken methods?

Update: I figured out how to deal with resetting the counter. However, fixing the above did not stop the experiment from ending the loop and skipping the routine when it shouldn’t.

What code are you now trying to use to end trials_4 and/or skip which routine?

If the participant scores 80 or higher on LexQuiz then I want to skip FailedQuiz and end the trials_4 loop.
If the participant scores lower than 80 on LexQuiz then I want to play FailedQuiz then go back to the start of the trials_4 loop.
Currently, the program is skipping FailedQuiz and ending the loop even if they don’t score high enough.

Here is what the code looks like now:
In LexQuiz:
Begin Experiment:
//instantiate the variables for counting
loopender = (- 1);
number_correct = 0;

Begin Routine:
//increase the loop counter by 1
loopender += 1;

End Routine:
//increase correct response counter if needed
if (key_resp_3.corr) {
number_correct = (number_correct + 1);
}
//if final trial is finished and score is high enough end trials_4 loop, otherwise reset counters
if ((loopender === 24)) {
if (((number_correct / 25) >= 0.8)) {
trials_4.finished = true;
} else {
loopender = 0;
number_correct = 0;
}
}

In FailedQuiz:
Begin Routine:
//if the trials_4 loop is finished (because they scored high enough) skip FailedQuiz
if ((trials_4.finished = true)) {
continueRoutine = false;
}

If they fail LexQuiz do you want them to be stuck in trials_3 or for that loop to end normally and trials_4 to repeat?

I want trials_3 to finish like normal whether they pass or fail.

Then if they pass LexQuiz, trials_4 should stop and FailedQuiz should be skipped.

If they fail LexQuiz, FailedQuiz should play and the trials_4 loop should not be broken. (I.e. they will be taken back to the beginning and will eventually have to take LexQuiz again)

In that case I recommend

In LexQuiz:
Begin Experiment:
//instantiate the variables for counting

loopender = (- 1);
number_correct = 0;

Begin Routine:
//increase the loop counter by 1
loopender += 1;

End Routine:
//increase correct response counter if needed

if (key_resp_3.corr) {
number_correct = (number_correct + 1);
}

In FailedQuiz:
Begin Routine:

//if final trial is finished and score is high enough end trials_4 loop and skip FailedQuiz, otherwise reset counters
if (((number_correct / 25) >= 0.8)) {
trials_4.finished = true;
continueRoutine = false;
} else {
loopender = 0;
number_correct = 0;
}

Thanks for your help. I changed the code to what you suggested

Now it is showing the FailedQuiz and continuing the loop when they fail, but it is also showing it and continuing the loop when they pass. So, it is not skipping FailedQuiz or breaking trails_4 when it should now.

To check what’s going on add some print statements, e.g. print(‘score’,number_correct) – console.log is the JS auto translation

It might be worth trying

loopender = 0; and number_correct = 0; in Begin Routine but

if (((number_correct / 25) >= 0.8)) {
trials_4.finished = true;
continueRoutine = false;
}

in Each Frame of FailedQuiz

I added the console.log(‘score’,number_correct) to the JS side of BeginRoutine in FailedQuiz and ran the experiment. But I do not know where to find the output to see what the printout was.

I also tried the other above suggestion and that did not have any effect.

Have a look at my crib sheet.

So I got the console.log and it appears to be counting correctly.

Additionally, moving the resetting values code to EachFrame in FailedQuiz caused me to skip the FailedQuiz routine when it should. However, the loop still did not break. One thing I noticed is that I am still in 2020.1 for the platform version, could that be affecting why trials_4.finished is not working? It seems like in your crib sheet I should be using trials.finished instead, but I am not sure.

Yes, if you are still using 2020.1 then you should try trials.finished=true even though your loop is called trials_4

Thank you so much! This was the final thing that needed to be changed it seems as now the experiment seems to be running as it should.

You were such a big help! Thank you again!