Skipping routine based on variables in conditions file

Hi all,

Using the Builder and v 1.84.2, I’m building a task where there are three routines within a loop:

  1. A trial block (block1), where the participant hears a sentence and must perform a lexical decision task;
  2. A question block, where the participant must respond to a question based on the sentence in (1);
  3. A ‘ready’ block, where the participant presses a key to go to the next trial.

The flow is as follows:

What I want is for not all trials to contain a question block - i.e. I want to skip the trial_q block for some trials, as I don’t want to ask a question after every sentence. I thought to do this based on a variable in the conditions file, namely “question”, which would be set to TRUE/FALSE.

I’ve tried putting

if question=="FALSE":
   continueRoutine=False

in the ‘Begin Routine’ tab of a code component in the trial_q routine, but no luck: the routine is not skipped.

Any advice would be greatly appreciated,

Thanks!
Rob

2 Likes

(1) PsychoPy sometimes does some clever things with interpreting the values in variables (e.g. the characters “None” can be interpreted as the Python object None rather than the string of four characters "None"). Maybe it does the same with "False" being interpreted as the boolean value False?

Try it without the quotes, and/or insert something like this to debug:

print(question)
print(type(question))

(2) This technique didn’t work until 1.84.x. It is possible that this version needs to be updated. Try the debugging above, but if you can upgrade to the latest version before starting your experiment, that is probably wise.

Hi Michael,

Thanks for your quick response and suggestions!

I’ve tried both (1) and (2); in (1), I changed TRUE/FALSE to “yes”/“no” and I’m now using v 1.85.2. However, I still get the following error when I run the experiment:

comp_q.setText(q)
AttributeError: 'NoneType' object has no attribute 'setText'
portaudio error in Pa_AbortStream: Unanticipated host error
Exception TypeError: "'NoneType' object is not callable" in <bound method Server.__del__ of <pyolib.server.Server object at 0x1B0D9EF0>> ignored

The error arises at line 702 - the relevant code from the compiled script is as follows (from line 696 to 710):

    # ------Prepare to start Routine "trial_q"-------
    t = 0
    trial_qClock.reset()  # clock
    frameN = -1
    continueRoutine = True
    # update component parameters for each repeat
    if question == "no":
       continueRoutine=False
    comp_q.setText(q)
    key_resp_3 = event.BuilderKeyResponse()
    # keep track of which components have finished
    trial_qComponents = [comp_q, key_resp_3]
    for thisComponent in trial_qComponents:
        if hasattr(thisComponent, 'status'):
            thisComponent.status = NOT_STARTED

It seems that the code after the first if statement still wants to run. comp_q is the question that is set to update from the conditions file; key_resp_3 is the keypress in response to the question.

Any idea how to fix this?

Thanks again,
Rob

What exactly do you mean by “question” here? i.e. is comp_q a sort of stimulus, and if so exactly what sort?

and is that line ( comp_q.setText(q)) some of your own custom code?

comp_q is the text component within the trial_q routine: it displays the question to which the participant must respond based on the sentence they’ve heard in block1. The trial_q routine also contains a keyboard component (key_resp_3) for the participant’s response to the question.

The only code that is my own in the lines provided is


if question == "no":
   continueRoutine=False

Everything else is generated by Psychopy.

Hope that’s clear!

Ah, after much trial and error it is fixed.

I put a loop around the trial_q routine and set the nReps of that loop using code in the ‘End Routine’ tab of a code block in the block1 routine.

Seems the ‘NoneType’ object error came from blank cells in my conditions file (I figured I could leave them blank, since there wouldn’t be questions on that trial, but seems not).

Thanks for your time, Michael.

1 Like

I’m using the newest version of PsychoPy (2020) and I am also new to PsychoPy & coding

I would like to do something similar to Rob:
I have a self-paced reading task, and after some of the sentences, I would like to present a comprehension question.
E.g., The participant may read 3 sentences and then on the 4th, a Y/N comprehension question about the immediately preceding question will appear. Then they’ll read maybe 5 sentences without a CQ until the next one.

The stimulus file would have the following columns: sentence, sentenceCondition1, sentenceCondition2, CQPresent [1, 0], CQ [text of the question, NONE], CQCorrect [y,n,N/A]

I have the questions already set in the stimulus file, with its own conditions/factors.

For now, I have the loop set up to include a fixation cross, the self-paced reading sentence, and the comprehension question. Within the stimulus file, the CQ column either has the question text or NONE. It works EXCEPT the CQ screen appears as a blank and requires the participant to press SPACE to move past the blank CQ to the next sentence.

How can I remove the blank screen that needs to be responded to? Ultimately, when the stimulus file has NONE or blank under the CQ column (or if CQPresent = 0)**, I would like to skip past the CQ screen and continue on to the next sentence in the SPR routine.

**In other words: Only show CQ screen when CQPresent = 1 or when CQ does not = NONE.

Insert a code component (from the “custom” component panel) on the comprehension question routine. In its “begin routine” tab, put something like this:

if CQPresent == 0:
    continueRoutine = False
2 Likes

SOLVED! :grin:
The code didn’t work in Begin Routine (I was still presented with a blank screen that I had to press through), but it DID work when I moved the code to Each Frame.

Note for others: it didn’t work when I had selected Auto -> JS, but it worked fine after I selected Py. When the code was the wrong type, I was stuck on the initializing screen during piloting.

Are you running it online? I thought that continueRoutine=False in Begin Routine works locally but not online.

I am running it online.

I think that corroborates what you said, @wakecarter

I think I run into a similar problem like @CFWhitwell. I intend to skip one routine within a loop in my trial conditionally on a variable that I defined in my csv file. This variable can either be 1 or 0 (so basically skip vs. don’t skip routine). Like discussed here, I added a customised code component and set the following in the begin routine section:

if myVariable == 0:
continueRoutine = False

It works perfectly offline, however, when I try to run my experiment online, 2 things happen:
The routine is not skipped as expected and the loop seems to be stuck in one row of my csv file that gets shown over and over again. It does not seem to iterate through my csv file.
I have already tried to move my code to the “each Frame” sheet, but this does not change anything. I am attaching screenshots of my conditions file, my flow and my code component.
I would appreciate your help immensely! Thanks in advance!


Adding a screenshot of my conditions file:

  • Try inserting a loop just around the routine of interest (i.e. this will be a loop nested inside your existing trials loop).
  • Don’t connect this inner loop to a conditions file.
  • Put your variable adjust2Present in its nReps field.

i.e. the routine will run once when the value of that variable is 1, and the routine will be skipped when the value is 0. This is effectively a code-free way of achieving what you are currently doing.

Check the output of the data file though: you might need two uncheck “is trials” for this loop, as it might alter the structure of the data otherwise.

Thank you very much, @Michael. This worked!

I’ve been trying to accomplish this same thing (skipping a routine sometimes, based on the value in a column) and am using this approach.

However I am getting the following error when it gets to the routine in question.

* **TypeError: Cannot read properties of undefined (reading '0')**

Any chance you can tell what I’m doing wrong?

Edit. I realized that I was referring to the outer loop and have now fixed that. But I’m getting a different error now. For reference here is what the experiment looks like in the builder:

This variable gets created at the start of the experiment like this:

And here is the error I now get:

Hi @David_Sidhu, in the current state it can’t work because you are using trials_2.thisN in the nReps field of trials_2. So you indeed have to use the outer loop (trials.thisN) and find another way to fix the error that arises by doing this. I suspect you will need to use memoryduration[trials.thisN] in nReps.

2 Likes

Yessss that did the trick, thank you!!

2 Likes