Import and display images and words from a mixted Excel file (images are not displayed)

Hi everyone!

I’m asking for help with my code that doesn’t work despite all my reseach and testing. In my experiment, I have to display simultaneously 1 image and 1 word on the screen in such a way that images and words are randomly associated at each trial and that images and words stay correctly linked with their emotional valence in my output data file. The experiment: psycho_essai_1_images - Copie.psyexp (14.4 KB)

The problem:
When I run my experiment, the window closes immediately and Psychopy sends me this error message (see below). I have compiled my script and this error appears when psychopy “update component parameters for each repeat”. It may refer to the variable that I have used do indicate the image to be displayed in the Image Component ($imageLat[$imageLat_order[$cur_imageLat]]) but, if it’s right, I don’t understand why because this way of indictating variables in Builder Components had worked perfectly in my last testing (with colors and words). Maybe a mistake in the code?

Traceback (most recent call last):
  File "C:\Users\roman\Desktop\essai_image_psycho\psycho_essai_1_images - Copie_lastrun.py", line 304, in <module>
    image_lateralisation.setImage(imageLat[imageLat_order[cur_imageLat]])
TypeError: list indices must be integers or slices, not list
##### Experiment ended. #####

The code:
All variables have been stored in an Excel file containing images (path) and words to display and the emotional valence of each image and each word.
To import my file and load my variables, I have used two Code Components like this:

import xlrd, random
random.seed()

#I create an object to load my file
in_file = 'essai_image_1.xlsx'
#I define the number of items for the experiment
num_items = 6
#I start to increment the counter of my trials 
cur_imageLat = 0
cur_mot = 0

#I open and read my file and select the sheet
inbook = xlrd.open_workbook(in_file)
insheet = inbook.sheet_by_index(0)

#I create my empty lists
imageLat = [] #list that will contain images to display
valence_image = []
mot = [] #list that will contain words to display
valence_mot = []
#I fill my lists
for rowx in range(1, num_items+1):
    row = insheet.row_values(rowx)
    imageLat.append(row[0])
    valence_image.append(row[1])
    mot.append(row[2])
    valence_mot.append(row[3])

#I create two empty lists to group and randomize together imageLat+valence_image, mot+valence_mot
mot_order = []
imageLat_order = []

mot_order.append(mot)
mot_order.append(valence_mot)#here this list contains mot and valence_mot

imageLat_order.append(imageLat)
imageLat_order.append(valence_image)#here this list contains imageLat and valence_image

random.shuffle(mot_order)
random.shuffle(imageLat_order)

#At the end of the test routine, I log my data and increment mot and imageLat counters
thisExp.addData('image_later', imageLat[imageLat_order[cur_imageLat]])
thisExp.addData('valence_image', valence_image[imageLat_order[cur_imageLat]])
thisExp.addData('mot', mot[mot_order[cur_mot]])
thisExp.addData('valence_mot', valence_mot[mot_order[cur_mot]])

cur_imageLat = cur_imageLat+1
cur_mot = cur_mot+1

Then, I have used an Image Component to configure the display of images (size, position…) and I have put $imageLat[$imageLat_order[$cur_imageLat]] to indicate the image to be displayed. And I have used a Text Component to configure the display of words and I have put $mot[$mot_order[$cur_mot]] to indicate the word to be displayed.

As I say previously, I don’t understand the error message. Maybe it’s because I have made other mistakes in my code, especially in the way I process images (no window in my code, no .draw() for images and words because I thought it was treated by the Builder Components).
If someone has any suggestions, I would be very grateful!
Romane.

Re!
I answer my own question! :joy:
In this previous message, I said that Psychopy sent me an error message explaining that the indices of list must be integers or slice, whereas mine was a list.
I think the problem was the way I filled out my combined lists:

# The incorrect manner:
mot_order.append(mot)
mot_order.append(valence_mot)
imageLat_order.append(imageLat)
imageLat_order.append(valence_image)

It wasn’t the right way to do it (at ALL)! So I have changed that using a Loop to fill out my lists and it works perfectly now! I have done this:

#the correct method:
for i in range(num_items):
imageLat_order.append(i)
mot_order.append(i)

So, now, I post the right code, hopping that will help some people! :wink:
If you want more details about the purpose of my experiment, you can read the begining of this topic (not the code in it, it was incorrect) : topic

the code:
In a first code component at the begining of the flow, in the ‘begin experiment’ field:

# I import packages to read xlsx files, randmize lists, manipulate images
import xlrd, random

# I precise random function to have one particular random order per subject
random.seed()

# I load my xlsx file containing images, words and 2 attributes
in_file = 'essai_image_1.xlsx'

# I define the number of items that I will use in my entire experiment
num_items = 6

# I put the reference to increment 'mot' and 'imageLat' counters through the experiment
cur_motStim = 0
cur_imageStim = 0

In the same Code component in the ‘begin routine’ field:

#I open and read the file that I load in the 'inbook' object
inbook = xlrd.open_workbook(in_file)
#As it's an excel file I precise the sheet to be selected
insheet = inbook.sheet_by_index(0)

#I create empty lists to stored my four variables
imageLat = []
valence_image = []
mot = []
valence_mot = []

#I fill out my lists with a loop
for rowx in range(1, num_items+1):
    row = insheet.row_values(rowx)#I define what is 'row' here
    imageLat.append(row[0])
    valence_image.append(row[1])
    mot.append(row[2])
    valence_mot.append(row[3])

#I create two empty lists that will be used to group together images+valence of images and words + valence of words 
mot_order = []
imageLat_order = []

#I fill out them with all values of all variables
for i in range(num_items):
    mot_order.append(i)
    imageLat_order.append(i)

#I randomize separatly each list to have one particular random order per list
random.shuffle(mot_order)
random.shuffle(imageLat_order)

In a second Code Component in the test Routine (with Image and Text components) in the ‘end routine’ field:

#I log my data (cur_imageStim and cur_motStim to log the four variables values corresponding to this current trial)
#to keep images + valence of images together in the output file, I log them from the same combined list 'imageLat_order'
#I do the same thing for words + valence of words (from the 'mot_order' combined list)
thisExp.addData('image_later', imageLat[imageLat_order[cur_imageStim]])
thisExp.addData('valence_image', valence_image[imageLat_order[cur_imageStim]])
thisExp.addData('mot', mot[mot_order[cur_motStim]])
thisExp.addData('valence_mot', valence_mot[mot_order[cur_motStim]])

#I increment the counter of trials
cur_imageStim = cur_imageStim+1
cur_motStim = cur_motStim+1

And to finish, I create a Text component and a Image component in the Test Routine to configure the display of images and words (size, positions…).
To indicate the image to be displayed I put $imageLat[$imageLat_order[$cur_imageStim]] in the Image component and in the Text component I put $mot[$mot_order[$cur_motStim]] to indicate the word to be displayed (Be careful to not forget a $ when you do this !!).
Don’t forget a Keyboard component if you want a response from your subjects!

I precise that this code is largely based on the Jason Ozubko’s tutorials on youtube (very good tutorials, go and see them, really!!).
I hope this response will help!
Romane

1 Like

Hey hey

I know this is an old post but I am actually using the same code to randomize (within-subject) my stimuli.

I don’t know where I go wrong but I cannot make the code work… It is, I think, not indexing to the condition file at all? I attach some pictures here, showing my code in each section & the picture of the error message (& the excel sheet with the image list)… Maybe you will see something I cannot see.

Thanks in any case!





Hi,

You may be making things a bit too complicated. Is there a reason that you don’t just use a loop and point it to excel file to read the images? By default the loop will randomise the rows of excel for each participant.

If I misunderstood your question however, then use a print statement to check what the imagehub outputs in every trial. Also, you could put your image filenames in a list in a code component and work on this list avoiding in this way importing the xlrd library and using its methods i.e. less complicated (I think).

BW,
Yiannis

Hello @Yiannis Thank you for your response!

I actually followed Jason Ozubko’s tutorial here: Using Code to Randomize Two Lists of Stimuli within a Single Loop -- PsychoPy Mini Tutorials - YouTube And tried doing the same thing as, I thought, the code does what I want to achieve… And I am very unfamiliar with Phyton, unfortunately, so I cannot really adjust it / change it as I wish at the moment.

And I am doing this, instead of just using the loop, because I have other routines later in which certain stimuli pairs are presented and I want to randomize these pairs also - which can be achieved by the code in the tutorial above. And as I know, when the loop randomizes the stimuli, it randomizes the same way for each participant? I might be wrong but this is not something I want to achieve.