psychopy.org | Reference | Downloads | Github

Breaking simple non trial loop conditionally online

Hi there,

I have a very simple problem I think but I can’t seem to figure it out…

I have a practice loop of 10 trials (trial loop) where I count the correct answers (e.g. name: pracLoop, loopType: sequential, is trials: ticked, csv file used to load conditions). I have an outer loop surrounding this that has no conditions (name: Practice_rounds, loopType: sequential, is trials: not ticked, no parameters set).

I want a participant to complete the practice trials until they get at least 6 correct answers, or if the loop has repeated 3 times, so then break the Practice_rounds loop. In Python this is all working fine with the following code:

In begin experiment:
‘’’
PLoopTally = 0
PCorrs = 0
‘’’
In begin routine:
‘’’
if PLoopTally >= 3:
Practice_rounds.finished = True
msg = “Well done!”
elif PCorrs >= 6:
Practice_rounds.finished = True
msg = “Well done!”
else:
PLoopTally = PLoopTally + 1
PCorrs = 0
msg = “Let’s try that one more time!”
‘’’

I tried to code this in Javascript as follows:

In begin experiment:
‘’’
PLoopTally = 0;
PCorrs = 0;
‘’’
Tried in both Begin routine and End routine:
‘’’
if (PLoopTally >= 3) {
trials.finished = true;
continueRoutine = false;
msg = “Well done!”;
} else if (PCorrs >= 4) {
trials.finished = true;
continueRoutine = false;
} else {
PLoopTally = PLoopTally + 1;
PCorrs = 0;
}
‘’’

I have tried loopname.finished in JS, trials.finished and continueRoutine = false, but none of them seem to exit the loop.

Could anybody give me any tips on how I might be able to conditionally break out of the Practice rounds loop?

Just replying to myself; i was being silly and forgot that I reset the loop counter in an earlier routine.

Anyways, just in case anyone is confused, in Python, you can break the loop by yourloopname.finished = True, in JS, you just use trials.finished = true, for any type of loop. It was confusing because the loop I tried to break didn’t have any trials, I just set the loop to run for 3 iterations unless broken before that.

Hi Claire,

I have been working on a similar experiment. I used the same method and the JS code as you described here in a routine named ‘repeat’. This is how my experiment looks like.

The code in JS in the ‘‘repeat’’ routine is:
Begin experiment:
‘"
PLoopTally = 0;
PCorrs = 0;
varmsg = ‘’
‘’’

Begin routine
‘’’
if (PLoopTally >= 3) {
trials.finished = true;
continueRoutine = false;
varmsg = “Well done!”;
} else if (PCorrs >= 8) {
trials.finished = true;
continueRoutine = false;
msg = “Well done!”;
} else {
PLoopTally = PLoopTally + 1;
PCorrs = 0;
varmsg = “Let’s try it again!”;
}
‘’’
However, the outer loop (practice-rounds) doesn’t run because there are no conditions/ parameters set, and hence, the experiment doesn’t initialize.
Could you please help me in making it work?

When you say “doesn’t run” do you mean you get an error message?

It doesn’t run beyond the instruction routine and shows an error.

What do you have in the nReps field for your loop?

nReps= 1, for pracLoop (inner loop)
nReps is blank for practice_rounds (outer loop).

You should definitely set nReps to a value (or variable name). If you want it to keep going until it’s broken by a code component put 1000 (for example).

I tried that by putting nResp=10, but then it keeps going for 10 cycles without breaking.

How many cycles do you want?

I want a single cycle of 12 trials at first. However, if the participant has equal to or more than 8 correct responses, he should be able to end the loop and if not, he should enter the practice loop again. The practice loop should run for a maximum of 3 times.

nReps = 3

If you call “practice_rounds” “trials” then you’ll be able to use Auto translate Python code which will be easier to debug.

in my experiment,
i am defining a variable as

rept in begin experiment section.
then updating this variable after one block

but this update value is not goinf in
nResp space… i have mentioned “rept” variable here without $

nResp = rept in outer loop… updating of rept variable in innere loop… similar to above mentioned experiment…

Any suggestion

I’m pretty sure you can’t edit nReps once the loop has started. You can only end it early (using trials.finished=true; in JS)

use of any variable for nResp would not work?

any suggestion (relevant question) from forum would be really helpful.

Tried suggestion from this thread… i think they have used a variable for nResp

this is not working for me somehow.
:frowning:

You can use a variable for nReps but changing it once the loop has started has no effect.

may be i am wrong here but it seems this person is using similar concept in the given link

I solved my problem using the following:

  1. Inserting a check routine with a code component:

Begin Experiment:
score=0

Begin Routine:
if score/training_loop.nTotal > 0.90:
repeat_training_loop.finished = True
else:
score = 0

  1. Adding a code component in the probe routine

End Routine:
if trainingresp.corr:
score=score+1

Thank you for your help.

Is there any other option to solve such issue, please let me know, that would be really helpful.

Thank You

That code should work except that for online use you need to refer to the loop as trials, I.e. trials.finished=true; as per one of my previous posts

this code is not working offline for me…

trials.finished=true;
is this code for repeat loop?

suppose is condition got fulfilled that accuracy less than 80% then inner loop would repeat. is this correct?

and

trials.finished=false;
for getting out off outer loop

what is “trials” here name of loop or routine here in this case.

Thanks for helping.

Hi Surabhi,

I’m not sure why your experiment doesn’t run, but I think there’s two things, 1) the code to break out of a loop offline and online aren’t the same, 2) you shouldn’t need to set conditions or parameters for the outer loop.

I’m confident you should be able to get this loop to work for your code since I’ve applied it in multiple online experiments now.

This is what should work:

for the outer ‘practice_rounds’ loop:

  • looptype = sequential
  • untick ‘Is trials’
  • nReps = 3
  • everything else left blank, it should say ‘no parameters set’

then for your inner loop:

  • I have looptype as random (think you should be able to use other types, but maybe use this to start)
  • ‘Is trials’ is ticked
  • nReps = 1
  • conditions = a .csv file with your conditions and corrAns (which you need to break the loop, if you want to base this on correct answers). It should say you have x conditions with x parameters.

This is what my loop looks like (it’s big so the beginning is cut off):

So in the last box inside the inner pracLoop (called Ptrials_feedback), I have a code segment where I keep track of correct answers from the trials. In this code segment, in the ‘begin experiment’ part, for both the Python and the JS code I have PCorrs = 0

Then in the ‘begin Routine’ code segment I have:

for Python:

if key_resp.corr == 1:
feedbackCol = [0,1,0]
PCorrs = PCorrs + 1

For JS:

if (key_resp.corr == 1) {
PCorrs = PCorrs + 1;
}

Then in the outer loop, the single green box titled ‘BreakPLoop’ I display some text to say whether they will need to repeat the practice or not, and a code segment to break the outer loop. In this code segment, for ‘Begin experiment’, for both Python and JS code I have: ‘PLoopTally = 0’

Then in the ‘begin routine’ part I have:

For Python:
if PLoopTally >= 3:
Practice_rounds.finished = True
msg = “Well done!”
elif PCorrs >= 6:
Practice_rounds.finished = True
msg = “Well done!”
else:
PLoopTally = PLoopTally + 1
PCorrs = 0
msg = “Let’s try that one more time!”

So this will quit the loop automatically if the outer loop has been repeated more than 3 times, or it will quit the loop immediately if at least 6 correct answers were given during the practice trials. the text after ‘msg’ is just what I display with this screen for 2 seconds.

For JS I have:

if (PLoopTally >= 3) {
msg = “Well done!”;
trials.finished = true;
} else if (PCorrs >= 6) {
msg = “Well done!”;
trials.finished = true;
} else {
trials.finished = false;
PLoopTally = PLoopTally + 1;
PCorrs = 0;
msg = “Let’s try that one more time!”;
}

So I guess maybe just check in your code that you use trials in your inner loop, that you use the correct break commands to get out of your loops, and then it should work!

Also just one more thing, if you get issues with JS not being able to initialise, check if there are quotation marks in your .csv file you use for trials. JS won’t initialise if you have any quotation marks in there.

1 Like