psychopy.org | Reference | Downloads | Github

Is there a way to jump ahead to a later index in the loop?

Hi all,

Question:
Can I put something in a code snippet that makes the loop jump to another point (e.g. ahead) in the index other than just the next trial in line?

Here’s the context:
I’m working on an experiment in which I need to dynamically be able to repeat certain trials. I’ve read that jumping back is very ugly and quirky in builder.

Therefore, I doubled the the trials in the excel file and added a code snippet to always run the first copies (continueRoutine = False for the second), unless there’s need for repetition, in which case the second copies are also displayed.

This works. However, it slows down my experiment too much (it has to skip around 10-15 copies to get to the ones it needs display), which is sensitive to timing. Therefore, I need a more direct way to tell the loop what the next trial is instead of just skipping my way through lots and lots of routines.

Many thanks for any ideas,
Amir

Your question seems to talk about several things:

  1. Repeating trials: this is relatively simple in Builder, if the trial to be repeated is the current one. Just nest the trial routine(s) within another loop within the main trial loop.
  2. Jumping ahead to other trials. As you note, this isn’t something Builder is really designed for and so solutions may be messy. You might want to look into calling thisExp.nextEntry() as many times as required, but I have no idea if this will actually work for you or not, or what the implications will be in the data output file.

https://www.psychopy.org/api/data.html#psychopy.data.ExperimentHandler.nextEntry

Custom requirements like this are probably the best case for writing experiments directly in Python rather than using Builder-generated code, which is inherently less flexible.

Hi Michael,

  1. I thought about that too, but that would be a huge pain, as the trials are all unique. The experiment presents a story one word at a time on the screen. Nevertheless, if nothing else works I will nest a word-per-sentence-loop (which means a separate conditions file for each sentence if I’m not mistaken) in a sentence-loop.
  2. I tried thisExp.nextEntry()but it didn’t seem to do anything. I added it to the ‘Begin Routine’ tab. I looks something like this:
if repeat_mode == 0: # if repeat mode is off -> rep1
    if repetition == 2: # skip repeat sentence words
        thisExp.nextEntry()

Do I need to put something in the brackets? I looked at the documentation, but I did not learn more there.

OK, I think we have a classic XY problem here. How about you start by describing exactly what you want to do in terms of your task, rather than the software details of how you are trying to implement it.

i.e. describe your task as you would in a methods section. Then describe what aspect of that you aren’t currently able to achieve.

Hi Michael,

sorry it took me so long to respond. I was on a deadline to finish the experiment. I ended up using a somewhat crude method, but it worked. I will share it here in case someone has the same problem I had.

As I mentioned above, my desired outcome was to have a loop structure, that allows for skipping back in the index.The context is that participants are reading a story word for word. That means only one word appears on the screen at a time and they can see the next word by pressing the space bar. Sometimes it is necessary to repeat the sentence that they are reading at the moment (error detected by the participant). Given that the sentences are unique and are of different lengths nesting a word loop in a sentence loop didn’t make any sense. Or let’s say it would’ve been a lot of work to implement (The way I see it I would have needed a seperate spreadsheet for every sentence).

People kept telling me that if I wanted a loop that allowed for jumping back in the index, I needed to drop the builder and directly write the psychopy script. I ended up doing a bit of that. Basically, I created a loop through the code junk that I could directly control. This way I could still work with the builder and have a custom loop.

I based my code of this video: Using Code to Randomize Two Lists of Stimuli within a Single Loop -- PsychoPy Mini Tutorials - YouTube

Here’s the loop setup:

import random, xlrd

#input file
in_file = 'gibberish_conditions.xlsx'

# counter
trial_index = 0

inbook = xlrd.open_workbook(in_file)
insheet = inbook.sheet_by_index(0)

#arrays to hold stimuli
sentence_list = []
word_num_list = []
normal_word_list = []
gibberish_word_list = []
new_sentence_list = []
last_word_list = []

for rowx in range(1, insheet.nrows):

    # read in an entire row
    row = insheet.row_values(rowx)

    # save the words and colors
    sentence_list.append(row[0])
    word_num_list.append(row[1])
    normal_word_list.append(row[2])
    gibberish_word_list.append(row[3])
    new_sentence_list.append(row[4])
    last_word_list.append(row[5])

# Set experiment constants and vars    
time_of_last_gibb = globalClock.getTime()
time_of_last_tp = globalClock.getTime()
experiment_start_time = globalClock.getTime()
tp_interval = random.randint(120, 180)
gib_interval = random.randint(70, 110)

In the trial, the information can be accessed by indexing the lists:

And then iterating the trial_index at the end of every trial:

Also, the information needs to be saved manually:

The trial is in a builder loop that runs for thousands of trials unless it is manually broken:

That is the gist of it.

Here are all the files, in case someone needs them (tested in 3.1.5):
gibberish_conditions.xlsx (142.9 KB) word_gibberish_12.psyexp (180.9 KB) loop_conditions.xlsx (7.8 KB) practice_conditions.xlsx (11.1 KB)