Adding code to Builder for the first time to accomplish randomization of stimuli

I have an experiment I made with Builder that runs well, but I need to be able to randomize two sets of image stimuli separately for each trial. I have read many of the previous posts on this subject and followed a tutorial online. I wrote some code but you will see below I am getting error messages.

The images are posters and faces presented sequentially – I simply want Poster A to not always be presented with Face A simply because they are in the same row -ie, randomize each column independently before starting the experiment.

I added the following code (appended below) as a routine at the start of the experiment. My excel file is called Conditionsfile.xlsx and the two columns are labeled poster_stim and face_stim in that file.

I keep getting the following error message: File “/Users/Username/Desktop/PsychopyRose/MacKenzie2/MacKenzieCode_lastrun.py”, line 601
trialloop = data.TrialHandler(nReps=$num_items, method=‘random’,

SyntaxError: invalid syntax
################ Experiment ended with exit code 1 [pid:29420] #################

In the trial loop gui of the Builder, I designated $num_items as the total number of rows in the excel sheet and removed the conditions file designation there (bc I designated it in the code below). So I expected the program to ignore the ‘random’ designation at the top of the trial loop gui. But it is clearly not. (for example, I changed that drop down to sequential, and the error message about method= changed from ‘random’ to ‘sequential’)

I am using the terms ‘posters’ and ‘faces’ in the code below as terms I am defining here - that is, I am purposely not using the names of my excel columns bc when I do I get a different error message : Alert 4705: Column name ‘poster_stim’ in conditions file already exists as a variable in this experiment (user).

So before I wrote the code I used the Gui boxes of Builder for the Images to designate the columns in the conditions file $poster_stim. I changed that to $posters[cur_poster] based on the code below.

CODE I ADDED:

Before Experiment Tab:

import random, xlrd

#randomize seed
random.seed()


#input file
in_file = 'Conditionsfile.xlsx'

#number of items to load
num_items = 9

#counters to hold the next stimulus reference
cur_poster = 0
cur_face = 0

Begin Experiment Tab:

#open the excel file
inbook = xlrd.open_workbook(in_file)
insheet = inbook.sheet_by_index(0)

#arrays to hold our stimuli
posters = [ ]
faces = []

#loop through the rows in the stimulus file
for rowx in range(1,num_items+1):
    #read in an entire row
    row = insheet.row_values(rowx)
    
    #save the poster and face stim
    posters.append(row[0])
    faces.append(row[1])

random.shuffle(posters)
random.shuffle(faces)

End Routine Tab:

#log the current word and color to our data file
thisExp.addData('posters, posters[cur_poster])
thisExp.addData('faces, faces[cur_face])

#increment stimuli counters
cur_poster = cur_poster + 1
cur_face = cur_face + 1

Note: what look like check boxes in the code are [ then closed ] brackets following posters = and faces =. Not sure what happened there. - pjw

Have a look at my online demos for Independent Randomisation and also Trial Switching for a method of loading trials in a code component.

Thank you Wakecarter!
That totally worked. It was indeed independent randomization of two columns I needed (each ColA stimulus appears only once followed by a randomly selected stimulus from colB).
FYI- I used only your code in loadA routine and within the trial loop. I didn’t use your code_JS in the Start routine because when I did I got error messages (psychoJS not found) - but when I deleted this everything worked fine.

I cannot thank you enough.

Hi Wakecarter - one more question

My experiment works well locally. When I try it on pavlovia I get an error message as it tries to bring up the first image:

  • when setting the image of ImageStim: Posterpic
  • the argument: images/AINeu.jpg is neither an image nor a video” }

Any thoughts?

Nevermind Wakecarter! I found your post from Nov 23 solving this problem by changing thisA=listA.pop() to thisA=listA.pop()[0]

Thank you again!

I note that adding that [0] makes the program work online but makes it crash locally.

One final question if I may: I assume your line thisExp.addData(‘thisA’,thisA) is what has the program write to the data file the name of the stimulus from col A that was presented on that trial. I added another line to have it also write what was presented from col B. thisExp.addData(‘face_stim’,face_stim)
where face_stim is the col name in my conditions file

When I make your change of adding [0] to thisA=listA.pop() (which makes it work online) the second command above no longer writes the name of the filename from Col B in the data file when collected online

I assume it’s because I’m using the actual name from the local conditions file and I would have to create a new variable that is specific to the file? (like I did for ‘thisA’). Is that close?

I see only now, that even though that second command doesn’t seem to work, the data file contains a column with the colB stimuli written out as presented