| Reference | Downloads | Github

PsychoJS loop not breaking


I have a problem with my online PsychoPy experiment. Here is my setup: participants read some instructions, and then undergo a training during which they have to answer 8 questions. I set a nested loop and a treshold that send them back to the beginning of the training if they perform less than 60% (around 5/8 questions). It works fine locally, but when I take it online, we get stuck in the loop. So even if the participant have 8/8, the training starts again.

I tried modifying the JS script manually, and replace the last bit to trials.finished=true; (also tried .finished = true; and currentLoop.finished = true;), as suggested in other discussions, but nothing works. Any ideas ?

Hi There,

I think this could be because you are using .thisN which version of PsychoPy are you using?

Hi Becca !

I’m using v2020.2.10

Aha! OK how far deep into task development are you? You should be able to use thisN in the newest release - which might fix your issue Releases · psychopy/psychopy · GitHub

Alternatively - use a custom trialcounter - add a code component, in the begin experiment tab type trialCounter = 0 then in the end routine tab type trialCounter += 1 then you can use that variable instead of thisN

Hi Becca,

Thank you for your answer. I downloaded the new release. The experiment still works fine locally, but now I get this error message when trying to do it online:

Capture d’écran 2021-07-26 à 09.51.54

With the previous version, I didn’t have this error. The files are stored correctly in the html/resources folder. Don’t know what to do from here…

Alternatively, I tried your suggestion about the custom trial counter, but I may have done something wrong. When trying to launch the experiment locally, I get this error message:

File “/Users/Nadia/Library/Mobile Documents/com~apple~CloudDocs/SISSA/MR/Pilot/”, line 2512, in
if ctrl_training_inner.trialCounter == 0:
AttributeError: ‘TrialHandler’ object has no attribute ‘trialCounter’

Experiment ended.

This are my code components:

Just use trialCounter, not ctrl_training_inner.trialCounter.

Sorry about that. I am very new to this. I did that change:

still have this error:

File “/Users/Nadia/Library/Mobile Documents/com~apple~CloudDocs/SISSA/MR/Pilot/”, line 2725, in
if trialCounter + 1 == trialCounter.nTotal:
AttributeError: ‘int’ object has no attribute ‘nTotal’

Experiment ended.

Thank you for your help !

trialCounter is a simple variable which you are starting at zero and adding 1 to each loop. It therefore doesn’t have and .nTotal method. You need something along the lines of

if trialCounter + 1 == nTrials:


if trialCounter + 1 == 20:

Thank you ! Did what you recommended. Here is the content of my code components.

Now the weirdest thing happens: sometimes it works, sometimes it doesn’t… something must be random in here.

What happens when it doesn’t work?

When it doesn’t work, the outer loop keep repeating over and over again, even when the conditions are filled. So even if I score 5 good answers or above, I keep repeating the training phase instead of moving on with the testing phase.

Try if trialCounter + 1 >= 8:

Alternatively, what should happen if trialCounter + 1 ==8 but number_correct < 5?

It works ! I can’t believe it… I have been stuck on this for weeks ! Thank you !!! Do you know why this solution works now ? I am curious to understand the reason behind it.
if trialCounter + 1 >= 8 but number_correct < 5, the outer loop should start again, and the participant has to undergo the training again.Which now works perfectly.

I suspect that it isn’t actually doing what you want at the moment, it’s just less bad.

I can’t see your flow but what I would normally do in this situation is have an inner loop which shows some practice trials (e.g. 8) and an outer loop which repeats them. A routine in the outer loop can check the number correct and either break the outer loop if the score is high enough or reset the number correct ready for a repeat of the practice trials. It doesn’t need to know how many trials have been presented because it is only seen when the inner loop has finished.

An alternative would be to use a single loop, in which case you would only want to check the score to break the loop if the trialCounter is at the correct number. If the number correct is too low, then both the trialCounter and the number correct would need to be reset.

In your case either the issue is that 8 was the wrong number, or the trial counter was sometimes increasing by more than 1 in between your code being viewed, or it wasn’t being reset if the score was too low and therefore could only end the practice trials if there were more than 4 correct answers in the first batch of 8.

Yes, this is exactly what I did.

Capture d’écran 2021-07-28 à 13.49.34

I tested what you said in your last line and actually there is indeed still something wrong. If I do 4 mistakes and more in the first batch, the outer loop repeats (like it is supposed to) but from the second loop, even if I do more than 4 mistakes, the loop breaks anyway and goes on with the testing phase, instead of repeating it again…

In my flow, CtrlTrainGo would go after the inner loop so the loop can be broken before the repeat starts.

Ok so after many trials, here is the solution:

  • In the CtrlTrainGo routine, add a code component. In the “begin routine” tab, add a counter: number_correct = 0

  • In the CtrlTrial routine, in the “end routine” tab of the code component, do this:
    if CtrlTrainAns.corr:
    number_correct += 1
    if number_correct >= 5:
    ctrl_training_outer.finished = True

That’s it ! Hope it will help someone in the future.