Restarting loop from beginning if either condition met

MasOS
PsychoPy 1.90.3

I’m trying to force my loop to restart if a participant either:
1) Fails to enter text into the text input; or
2) Reaches the end of the loop without acquiring enough (15) correct answers (‘y’)

I’ve tried the following code:

Begin Experiment

cue_input = ""
bazooka = 0

Begin Routine

theseKeys=""

Each Frame

n= len(theseKeys)
i = 0

while i < n:
    if theseKeys[i] == 'return':
        continueRoutine = False
        break

    elif theseKeys[i] == 'backspace':
        cue_input = cue_input[:-1]
        i = i + 1

    elif len(theseKeys[i]) == 1:
        cue_input += theseKeys[i]
        if theseKeys[i] == 'y':
            bazooka = bazooka + 1
            if bazooka == 15:
                list.finished = True
                break
            continueRoutine = False
            break
        elif theseKeys[i] == 'n':
            continueRoutine = False
        else:
            theseKeys = ""
        i = i + 1

Right now, even when I press ‘return’ with the length of theseKeys being 0 (empty), the routine moves on to the next row in the loop. I’ve tried similar logic with the second condition (restarting the loop if 15 'y’s are not achieved) but haven’t been able to figure it out either.

Any help with this would be greatly appreciated!

That’s exactly what your code tells it to do (i.e. when you stop the current routine, if it is the last one in the loop, the next iteration of the loop will occur).

If you actually want to restart a loop from the beginning, you need to nest that loop itself inside of another loop. Then as well as setting continueRoutine to False you need to set name_of_your_inner_loop.finished = True. Then the next repetition of the outer loop will occur, causing the inner loop to restart.

To break out of this if the conditions are met, you will also need to set name_of_your_outer_loop.finished = True as required.

1 Like

Thank you Michael for this tip,

I had to put the latter code after the inner loop, I don’t know why.


I then added a code component with the following code in Feedback (begin routine):

if key_resp.keys.lower() == 's':
    PVRtrials.finished = True
if key_resp.keys.lower() == 'r':
    PVRtrials.finished = True

‘s’ will skip the block and ‘r’ will repeat.
Now if I add

if key_resp.keys.lower() == 's':
    repeat.finished = True

to the begin routine in the Feedback-routine it will not break out of the repeat-loop. I had to add that to the CheckForRepeat-routine outside of the PVRtrials-loop. Now the skip and repeat buttons work but if the PVRtrials ends the natural way, the repeat-loop kicked in which I didn’t want it to. So I added the following to the code in the CheckForRepeat (begin routine):

if key_resp.keys.lower() == 'right' or key_resp.keys.lower() == 'left' or key_resp.keys.lower() == 'down':
    repeat.finished = True

This is how the repeat-loop is configured:
image

Thank you for your patience and willingness to share!

Regards,
Martin