psychopy.org | Reference | Downloads | Github

Instantly terminating loop

So we’re setting up an experiment with 3 between-subject conditions, and I’d prefer having them all embedded within the same program. The loop for each is slightly different that the others - each one containing 2 identical routines, and 2 different ones. Based on the condition number assigned to the participant, I want a choice of 2 out of 3 loops bypassed so the participant only sees one.

I know one way to do this: in the frontmost routine throw a code block and if condition is of particular value, then thisloop.finished = True and continueRoutine = False. But this still continues the other routines within the loop once, which I don’t want. I can slap additional code blocks and additional continueRoutine = False onto each subsequent routine, but since 2 of them are the same between conditions, this leads to them always being skipped!

I could remake the two identical ones to each be unique, though they are kinda complicated and I am wondering if there is any alternative solution anyone can think of!

For example, is there a way of setting the nRep for a loop to 0 at the start of the loop? I assume not since all code has to be embedded within a routine and loops are not defined until they actually begin, so I don’t think that I can pre-emptively set them as finished before the first routine in them starts. But maybe I’m missing something here.

Thanks for any tips/thoughts!

I feel like there are more elegant ways but one option would be to have a loop within your loop with nReps set to a variable 1/0 that you set in a code component inside the outer loop but prior to the inside loop. Then you can skip routines without having to add any code to them.

1 Like

Interesting idea, and I’ll definitely try it. Is the code for setting nReps just trials.nReps = X ? I’ve always thought that trials.nReps call was read only.

EDIT: Oh, after thinking about it some more I see what you mean – make nReps a variable that is then set! Very clever.

So I am just leaving a more detailed write-up for those who might encounter this problem in the future and want a detailed description on how to do it:

  • Suppose we have three loops, each called “bwCondition1”, “bwCondition2” and “bwCondition3”. They are arranged one after the other, but you only want the one that has the same number as your condition set in the experiment dialog box.
  • Solution: for each loop, set the “nReps” to be a variable (e.g., “bw1_run”, “bw2_run” and “bw3_run”). No need to add $ because the nReps automatically appends that.
  • Make a routine right before your bwCondition1 loop called something like “conditionPicker”. Inside of it, make a code block.
  • The code is then something like:
if expInfo['condition'] == "1":
bw1_run = 1
bw2_run = 0
bw3_run = 0

if expInfo['condition'] == "2":
bw1_run = 0
bw2_run = 1
bw3_run = 0

if expInfo['condition'] == "3":
bw1_run = 0
bw2_run = 0
bw3_run = 1

(you can make it cleaner if you’d like with the use of else, making condition be numeric, etc.)

This then will make the nReps equal to 0 and will not run the loop at all when it encounters it! To be safe, you might want to initialize the three variables at the start of the Experiment, too, in case you type a value for a condition that’s none of these or something like that.

Thanks to @wakecarter for this – it’s a very clever solution.

1 Like

A minor suggestion which helps with online conversion (and elegance).

bw1_run = 0
bw2_run = 0
bw3_run = 0
if expInfo['condition'] == "1":
     bw1_run = 1
elif expInfo['condition'] == "2":
     bw2_run = 1
elif expInfo['condition'] == "3":
     bw3_run = 1
1 Like