| Reference | Downloads | Github

Is it possible to randomize image order, but repeat that specific randomized order during a loop?

Windows 10 (e.g. Win10):
PsychoPy v2020.1.3 (e.g. 1.84.x):

What are you trying to achieve

I have a csv of images to load and I would like to randomize their order, then repeatedly present this randomized order based on other experiment variables (loop number, participant number). [Meaning that sometimes I’d like it continuously randomize the order and other times I’d like it to repeat the order] Importantly, I’d like to do this without importing as few libraries as possible, since it’ll have to eventually run on Pavlovia.

What did you try to make it work?:

I believe that since there should be an on-going log of what pictures were presented, based on the participant number and loop number I’m hoping to modify the routine to re-present the images it just showed if it repeats.

What specifically went wrong when you tried that?:
I have no idea how to do this. Please send assistance. Also, please remember that I’m trying to do with as many built-in PsychoPy features as possible, since it’ll eventually have to be run on Pavlovia and “import random” doesn’t work easily with that.

I’ll restrict any of my updates to the above questions here:

Adjusting Based on Participant Number
To access Participant number refer to “expInfo[‘participant’]” in the custom code in builder.

An example of modifying some parameter based on whether the participant number is odd or even is:

if int(expInfo['participant']) % 2 == 0:

Adjusting based on loop number
To adjust it based on some loop’s loop number


Appending shown image to a list
I have the feeling that this is the code to do so:

At beginning of experiment


At end of each presentation of image


I’m not sure if it works as intended or not, but then at the begin routine of each loop around the image I tried doing


However, it seems like the images are still being randomly presented in a different order.

So it looks like this line needs to be set/adjusted based on the conditions, will investigate soon

LOOPNAME = data.TrialHandler(nReps=1, method='random', 
    extraInfo=expInfo, originPath=-1,
    trialList=data.importConditions('PATHTOSTIMULI.csv', selection='0:10'),
    seed=None, name='LOOPNAME')

If you use a seed in your loop then you can repeat a specific random order within the same experiment (set the seed to a random value and then use the variable in multiple loops).


Sorry for the late reply. I think your solution is promising.

Do you know what custom code I should run to set the seed and to generate one?

I imagine that I’ll have to set it at the beginning of the loop, then generate a new one each time I exit the inner loop.


Seed is one of the loop parameters. Try setting a randint before the first loop and then reusing the same number.

Yes, I understand that. But how do I set a random integer without doing

import random


import numpy

I’m having difficulty finding anyway of doing so.

Have you tried randint(min,maxplusone) ? I use that in Builder without importing random

I will update if I hit any further issues. Just in case someone needs randint in JS, here’s a link that discusses it:

If you need randint in JS then please look at my crib sheet, which I didn’t mention in this thread because I hadn’t noticed your reference to online.

Is this the crib sheet?:

Also, for my particular situation I need to take this defined-randomized order into an entirely loop. Do you know how to make this work? What I’m worried about is what CSVs to load into the loops and whether the randomseed in one loop will translate to another.

I think describing what’s going on will make it easier to understand so,

Here’s what’s happening:

Loop 1A

Participants loop through a set of images in random order and the particular random order is repeated multiple times until they can recall the images in the order they appeared 3 times in a row.

Pre-Loop 1B

Participants are presented with a random location (word-form) and are asked to imagine it.

Loop 1B

Participants see the images again in the order that it was presented in Loop 1A, but this time a random set of words is also paired with the images.

After seeing the word presented with the image, the location, word, and image are presented together.

After loop 1 completes, loop 2 begins where a different set of images, words, and location need to be selected.

What I’m Thinking

  1. In the outer most loop (Loop N) Load a .csv with 3 columns (image, word, location). Then each row would list the path to a different CSV for each stimuli type (image1, image2, etc). Set the loop type to random, so that a random csv is selected each cycle of the outer loop.

    • 10 rows in each image csv
    • 10 rows in each word csv
    • 1 row in each location csv (location is constant per loop)
  2. In Loop 1A, refer to the image column in 1., set a random seed, then reuse that random seed on each loop.

  3. In Pre-loop 1B, refer to the context column in 1. and get the context.

  4. In Loop 1B… ?

    • The same image set and order of images as in 2. needs to be preserved
    • The same context as in 3. needs to be preserved.
  5. Outer-most loop proceeds to Loop 2 and steps 2-4 repeat.

Issues that I can’t figure out

I’m unsure what to do for Loop 1B and if solving it requires a completely different approach.

Yes that’s the one.

I would recommend using the method I use in Prospective Memory LDT and Brookes Template 2020 where I use a loops to load the contents of Excel files into arrays in a random order. My main trials loop then uses those arrays rather than having an Excel of its own.

Okay, then I guess I should drop the random seed idea altogether?

I’ll take a look at your projects.

For anyone else and future readers:

Prospective Memory LDT

Brookes Template 2020

The seed option might work but it seems unlikely if the loops aren’t identically defined.

I see, also just to double check. Is the util.shuffle mentioned in your crib the translation for the Python random.shuffle()?

I need it badly, so for it to really be so simple would be a great boon.

I’m certainly using it as shuffle() which as far as I know is the same abs random.shuffle()