psychopy.org | Reference | Downloads | Github

Conditional looping

Hello,

I am trying to figure out how to set a counter for the number of correct responses within a given set of trials. At the end of the loop, the participant needs to have passed at least 70% of the trials. How can I achieve this end?

1 Like

Keeping track of the the number of correct responses is quite simple (just a couple of lines of code in a code component). But to give a full answer, we need to know what action you want to take on the basis of that score.

i.e. at the end of the loop, what should happen if the score is >= 70%, and what should happen if the score is <70%?

1 Like

Yeah, that much I gathered just by tinkering with the script. To better explain what I’m doing; the participant is going to complete 12 practice rounds. Each round they will be presented with a color and they must press the first letter of that color using the keyboard. Following the conclusion of the 12th round, I want the program to perform an accuracy check–if the participant scores less than 70% correct, they will be rerouted to the instruction routine. If the participant passes, then they will proceed to the baseline assessment.

To better explain the flow, I was going to present the instruction screen just before the series of trials in the following loop.

OK. You need something like this:

  1. Two routines: one for the instructions, followed by one for the practice task.
  2. Two loops: an inner one that surrounds just the second routine, and an outer one that encompasses both routines (so that the inner loop is nested within it).

The inner loop will be connected to a .csv or .xlsx conditions file which contains the colour and first letter details, and will have 12 rows (one for each trial). It should probably be set to random (so each repletion of the practice task is presented in a different order, and have an nReps of 1 (so just 12 trials will be presented each time).

The outer loop will not be connected to a conditions file, and will be set to have a very large nReps value (e.g. 999), so it will effectively keep repeating the instruction and practice phase indefinitely until told to stop.

Insert a code component on the practice routine. In its Begin routine tab, put something like this (replacing with your actual loop name):

    ''' reset the counter at the beginning of each practice loop:'''
    if inner_loop_name.thisN == 0:
        number_correct = 0

Then in the End routine tab, put something like this:

    ''' update the number correct:'''
    if your_keyboard_component_name.corr:
        number_correct = number_correct + 1

    ''' if this is the final repetition, check the proportion correct.
        (am avoiding hard coding the value '12' for flexibility):'''
    if inner_loop_name.thisN == inner_loop_name.nTotal:
        if number_correct/(inner_loop_name.nTotal + 1) >= 0.70:
            ''' terminate the outer loop so no more practice happens:'''
            outer_loop_name.finished = True

Bear in mind that most things in Python are zero-based, which is why (I think) we need to add 1 to the total number of repetitions in the inner loop to calculate the proportion correctly. If things don’t seem to work correctly, check for possible such off-by-one errors.

4 Likes

Thank you! I appreciate the feedback. I’m gonna give that a shot. I’ll let you know how it goes. Thanks again. I’m new to coding; so, I’ll take any advice I can get.

So, I managed to get the looping to work properly, however, there’s a routine that I don’t want to play at the conclusion of the practice rounds. Basically, in between each round, just after a the participant is given feedback, there’s a screen that reads “Let’s try another.”

Then in that routine, insert a code component and in its Begin routine tab, insert a check which means that the routine will only run if some condition is met.

At a guess, something like:

# don't run this routine if the outer loop is not set
# to have another iteration:
if outer_loop_name.finished:
    continueRoutine = False
1 Like

That does work, however, it stops presenting that routine after 8 correct responses. To resolve that issue, I’ve been trying to do something like:

if practiceTrials.thisN == 12:
    continueRoutine = False

Yes, that is the better, more direct way to do it (using the inner rather than outer loop: I think I misunderstood the situation).

But remember that Python is zero-based, so you should be testing if practiceTrials.thisN == 11: rather than 12, if you want to catch the final trial.

Hope that helps

1 Like

Yeah, that worked. But apparently, the PI on our study wants it to record only the first response (To ensure that the participant isn’t mashing buttons, while also familiarizing them with the study before they do the baseline assessment). Any suggestions? And by the way, I appreciate the help; all of this is new to me.

-Drew

That is an option that can be selected in the Keyboard component.

1 Like

I am aware of that. However, I want all responses to be recorded, but only the correct response should end the routine. The latter is not an issue. The first response should be the only response that counts toward the accuracy score.

I don’t think the keyboard component can do this. You’d probably need to delete it and do all the keyboard checking in code to implement this non-standard logic.

But before that, you might want to seriously consider whether this approach is wise. I’m not sure what the participant will learn if they have to eventually press the correct response to end every practice trial, yet are scored and given feedback on the first response. It could just encourage random key pressing and actually slow the rate of learning, as feedback is no longer tightly linked to the latest response.

1 Like

I think there’s a bit of a misunderstanding. All key presses are recorded, but only correct ones end the routine. Prior to the practice round, participants are presented with a list of instructions; in other words, it’s explicitly stated that they press only the correct keys. And if I have to go into the coder to do this, that’s fine; I just need to know what I have to do. This is probably the last thing I need to do to finalize this task. I apologize for my persistence, but I have given myself a deadline and I have a full workload on top of it.

-Drew

Also, I forgot to mention that they are only given feedback after a correct response has been made (I.e., the reaction time displayed indicates the time it took for them to press the correct key). This is not for the participant as much as it is for us. We are trying to prevent keyboard mashing.

This was addressed in a previous topic:

1 Like