Randomise stimuli without repetition of consecutive presentations

Hello, I’m new to PsychoPy & in need of assistance.
I have designed an experiment (using the builder) where in a single trial participants are simultaneously presented with audio stimuli and text stimuli. In a single trial participants:

  • See text (combination of 3 letters)
  • Hear 3 sounds and must decide which sound is the odd one out.
  • Must indicate which sound is the odd one out by clicking either ‘z’ or ‘m’

I have created an excel sheet which contains all the values i.e. text stimuli (x 30 unique 3-letter-long combinations), sound stimuli (10 varieties input 3x to match no. of text stimuli), correct answers (in response to sound stimuli), and a jpg of a piano key (30x) which is to be displayed at all times. This list has to be repeated only once.

I have used the ‘randomize’ function within the builder which is fine but I would like to ensure that no one set of letters or sounds features in consecutive trials (i.e. TRIAL 1: text stimuli ‘ijb’ & sound/a.wav; TRIAL 2: text stimuli ‘abz’ & sound/d.wav; TRIAL 3: can’t include either text stimuli ‘abz’ or sound/d.wav)

I have tried inserting a code element at the beginning of the loop and top of the routine but info in the loop prevails i.e. same stimuli is still likely to feature twice in a row. This is the code I got from another post (by kmcdubb);

stimulus_list = [‘v’, ‘b’, ‘n’, ‘m’] * 3
shuffle(stimulus_list)

make sure the same target doesn’t appear on consecutive trials

double_stim = False
list_ok = False

while list_ok == False:
for i in range(len(stimulus_list) - 1):
# check for equal neighbours:
if stimulus_list[i] == stimulus_list[i + 1]:
double_stim = True # D’oh!
break # can stop checking on this run
if double_stim == True:
shuffle(stimulus_list) # try a new order
double_stim = False
else:
list_ok = True # Yay! The loop won’t run again.

print(stimulus_list)

I have adjusted it accordingly

stimulus_list = [‘jzt’, ‘wzt’, ‘ijb’, ‘ikj’, ‘abz’, ‘rnq’, ‘tkz’, ‘htg’, ‘orh’, ‘hia’] *# I have adjusted the values to those in my stimuli sheet. Removed 3.

shuffle(stimulus_list)

make sure the same target doesn’t appear on consecutive trials

double_stim = False
list_ok = False

while list_ok == False:
for i in range(len(stimulus_list) - 1):
# check for equal neighbours:
if stimulus_list[i] == stimulus_list[i + 1]:
double_stim = True # D’oh!
break # can stop checking on this run
if double_stim == True:
shuffle(stimulus_list) # try a new order
double_stim = False
else:
list_ok = True # Yay! The loop won’t run again.

print(stimulus_list)

I also created a revised excel sheet where I took out the column containing these 3 letter combinations so as not to confuse the builder. The revised sheet linked to the loop has 3 columns only (piano, corrAns, picture). When I run it in the builder the 3 letter combinations aren’t showing. Would anyone have any idea as to how to get around this problem?

Also, I need to be able to run this on Pavlovia, but for now getting it working in the builder would be great. Many thanks!

The way I approach this is to add a random number to the index being selected each trial.

For example, if there are four elements I’ll add a number from 1 to 3 and take modulus 4 of the result

Hello & thank you for taking the time to respond.

I’m not really following this solution though… :grinning: Would you be able to explain in more detail? I’m attaching a copy of my stimuli sheet. As you can see there are 4 columns. The values in $stimuli are already set i.e.the 3-letter combinations. The builder has to loop once through all these entries ensuring that consecutive trials do not contain the same values. They way it’s randomnised now (using built in randomise function) there is a chance that i.e. value ‘orh’ will be presented twice in a row - this kind of repetition I’m trying to avoid. Many thanks again!

stimuli.xlsx (9.0 KB)

In Begin Experiment thisStimulus = randint(0,10) (using the randint(min,maxplusone) function from my crib sheet).

In each trial
thisStimulus = (thisStimulus+randint(1,10))%10

So if the first stimulus is item 5 the second can be anything from item 6 to 14 (which is 4 in mod 10).

This won’t give exactly the same number of occurrences of each level but it will avoid consecutive trials being the same.

Hello, thank you again.
I’ve tried this solution and unfortunately same items still feature one after another at times.

I have revised my stimuli list so now same stimuli features in blocks with ‘hia’ & ‘rhi’ featuring 5 times each (see attached).

Then I tried to play around with the values in brackets i.e.
Experiment thisStimulus = randint(0,5)
thisStimulus = (thisStimulus+randint(4,5))%10

…But that didn’t work either. Not too far off - maybe one or two subsequent repetitions of the same value so seems like we’re on the right track (or it’s just been a coincidence). Would you have any more suggestions? Thank you.

stimulus_list_presentation_ed.xlsx (10.5 KB)

Are you using stimulus_list[thisStimulus] ?

You might be using a randint function that goes from min to max, not min to maxplusone, in which case it should be thisStimulus = (thisStimulus+randint(1,9))%10

+randint(4,5) either means always add 4 or either add 4 or 5 to the index.

Hello,

Whether I use:

stimulus_list = [‘jzt’, ‘wzt’, ‘ijb’, ‘ikj’, ‘abz’, ‘rnq’, ‘tkz’, ‘htg’, ‘orh’, ‘hia’]
thisStimulus = randint(0,10)
thisStimulus = (thisStimulus+randint(1,9))%10

or

stimulus_list = [‘jzt’, ‘wzt’, ‘ijb’, ‘ikj’, ‘abz’, ‘rnq’, ‘tkz’, ‘htg’, ‘orh’, ‘hia’]
thisStimulus = randint(0,10)
thisStimulus = (thisStimulus+randint(1,10))%10

…in Begin Experiment there is still repetition. Not a lot (one or two items are repeated consecutively) but it’s still there… Also note the 2nd column of my stimuli set $piano containing 10x wav files. Some of them have also been repeated consecutively. It doesn’t matter what value from $piano is combined with what value from $stimuli as long as neither of these values featured in the preceding trial. I can get around repetition in $piano by creating 30 unique wav. files… but I can’t do it for $stimuli as these values & their number is fixed. Would it matter at all if the 10 values (‘jzt’, ‘wzt’,… ) in $stimuli were grouped (at the moment they are in ‘random’ order)? I tried deleting $piano altogether to see whether it being there interferes with the above bit of script which only specifies values from $stimuli. It made no difference. I can’t think of anything else or what I’m doing wrong. Many thanks…

Please could you clarify where you are putting the code?

The third line is for Begin Routine in each repeat, not Begin Experiment

Hello,

Yes, this is what I’ve done. One item from $stimuli was repeated twice…