psychopy.org | Reference | Downloads | Github

Randomization stimuli w/o consecutive presentation

Hi guys,

I am programming a learning experiment in which children need to learn like ‘a new alphabet’.
In every trial they hear a sound and see two new symbols (left or right on the screen). Then they have to indicate which symbol they think that corresponds to the sound they heard.
The first block consists of 4 different sounds they need to learn (so also 4 symbols that corresponds to a sound). This means that every sound can be combined with its corresponding symbol or 3 other incorrect symbols, which means that there are 12 different alternatives (4 sounds with itself ánd 3 incorrect symbols, as we present 2 symbols each trial).

I want to have 72 trials in the first block, which means that each sound will be repeated 18 times. For now I used a code with a while loop (while next stimulus is same as current, randomize symbol_order) which shuffles the sounds as long as two consecutive sounds are the same. This works great when using less trials, but takes soooo long for randomizing 72 (didn’t even come to the point where it found a good order and I waited for already 10 minutes so not an option).

Which alternatives can you suggest?

maybe important to know, each sound corresponds to the 2 symbols, so these rows need to be randomized together (that’s why I used symbol_order):

[code below]

if block == 0:
    num_items = 72
    stimuluslist1 = {'setA/A1.wav': 'setA/A1.png', 'setA/A2.wav':'setA/A2.png', 'setA/A3.wav':'setA/A3.png','setA/A4.wav':'setA/A4.png'}
    #input file
    in_file = 'block1.xlsx'
    inbook = xlrd.open_workbook(in_file)
    insheet = inbook.sheet_by_index(0)

    sound = []
    symbol1 = []
    symbol2 = []

    #loop through rows in stimulus file
    for rowx in range(1, num_items+1):
        row = insheet.row_values(rowx)
    
        sound.append(row[0])
        symbol1.append(row[1])
        symbol2.append(row[2])
    #print(sound)
    #print(symbol1)
    #print(symbol2)


#randomize symbols
    for rowx in range(0, num_items):
        if random.random() > .5:
            TEMP_B = symbol2[rowx]
            symbol2[rowx] = symbol1[rowx]
            symbol1[rowx] = TEMP_B
    #print(symbol1)
    #print(symbol2)

    #create order list
    symbol_order = []
    for i in range(num_items):
        symbol_order.append(i)

    #randomly shuffle sound_order
    random.shuffle(symbol_order)
    print(symbol_order)
    
    double_stim = False
    list_ok = False
    
    while list_ok == False:
        for i in range(len(symbol_order)-1):
            #check for consecutive stimuli
            if sound[symbol_order[i]] == sound[symbol_order[i+1]]:
                double_stim = True
                break
        if double_stim == True:
            random.shuffle(symbol_order) #try new order
            double_stim = False
        else:
            list_ok = True

    #arrays for final stimuli
    sound_list = []
    symbol1_list = []
    symbol2_list = []
    
    #create final lists
    for i in range(num_items):
        sound_list.append(sound[symbol_order[i]])
        symbol1_list.append(symbol1[symbol_order[i]])
        symbol2_list.append(symbol2[symbol_order[i]])
    #print(sound_list)
    #print(symbol1_list)
    #print(symbol2_list)
    
    corr_ans = []
    #set correct answer
    for i in range(num_items):
        if symbol1_list[i] == stimuluslist1[sound_list[i]]:
            corr_ans.append('left')
        else:
            corr_ans.append('right')
    #print(corr_ans)

Hello,

you seem to use a brute force approach to find your pseudorandom order. I use a different approach for pseudo-randomization (at least in Presentation). Imagine you have two types of answer, yes and no and you don’t want to have more than three yes or no-answers following each other. Your randomly select your first trial, then randomly your second trial and check whether they are the same or different and store the result. Then you randomly select your third trial, compare it to the ones before. If it is the same as the two trials before, select it and select the next trial from the other condition, reset your comparison result. This way you go through your trials.

I found this approach faster than a real randomization and checking whether it turned out the way I wanted it. Keep in mind, that this approach does not guarantee a solution. So, you might restart the loop after some time, for instance if there are no more items left from condition A but you still have trials to come.

Cheers Jens

Hi @JensBoelte,

Thank you for your reply!

What do you mean by condition? Is it yes vs no in your example?
I can append the stimuli to a trial list trial per trial as you proposed, and then check whether these are the same or not, but then how can I make sure that each sound is presented an equal number of times?
In my case I have 72 trials and 4 sounds, so each sound should be presented 18 times.

Is it an option to make a list of the four sounds (e.g. sound_list = [‘soundA’, ‘soundB’, ‘soundC’, ‘soundD’], then shuffle this list and append it to the a ‘general’ stimulus list.
Then shuffle the sound_list again and check whether the first item is the same as the last of the general list, if yes --> shuffle again, if not: append to the general list.
Something like this until I have 72 items?

Cheers,
Cara

The method I use is as follows if I have n trial types and I don’t want consecutive trial to be of the same type.

  1. The trial types should be in an array with indices 0 to n-1

  2. If the current trial type is thisCondition then the next trial type is (thisCondition + randint(1,n))%n

where randint is defined as min,maxplusone as per my crib sheet

Dear Cara,

sorry for being inprecise. Conditions do not matter in my example but just the order of yes-no answer.

In your case, simply shuffle your list of four stimuli, append it to a ‘general’ list, reshuffle your four stimuli, check whether the last item of the general list and the first item of your list of stimuli differ or match. Reshuffle (or follow wakecarter suggestion) until the last item of the general list and the the first item of the stimuli list differ. Do this until you have 72 trials. So, this is what you suggested yourself :wink:

Cheers Jens