Search code examples
pythonpsychopy

Drawing 1 image from previous image set + 2 random images from list (Python/Psychopy)


In the code below i am drawing 3 images from a list (targetset) then displaying them to the screen. Next I am displaying another 3 images (pics) to a different part of the screen. For this second part; on 50% of occasions I want the 'pics' images to be the same as those displayed initially (target set). I am ok with this part, I am setting pics = targetset when x == 0 (basically flipping a coin).

My probleme is, on the other 50% of occasions I want one of the 'pics' set to be the same as one of the orignally showed set (targetset), any one of the three. And i want the remaining 2 to be randomly choosen from the pics list. As it stands, according to my logic, I can only get the 'pics' images to be all the same, or all different as the originally shown images from 'targetset'.

Adding to the problem: When x==0 (making pics=targetset) they all display ok, but when x==1 (meaning make no change) i get the following error message:

pics[i].pos = location[i] UnboundLocalError: local variable 'pics' referenced before assignment

Here is my code:

#create initial target set
imgList1 = glob.glob(os.path.join('stim','*.png'))
random.shuffle(imgList1)
targetset = [visual.ImageStim(window, img) for img in imgList1[:3]]

#initial target set location
setlocation = [(-2,0),(0,0),(2,0)]
random.shuffle(setlocation)

#create target list
imgList = glob.glob(os.path.join('stim', '*.png'))
random.shuffle(imgList)
pics = [visual.ImageStim(window, img) for img in imgList[:3]]

#set target locations
location = [(1,2),(3,3),(5,5)]
random.shuffle(location)

'''define sequential presentation function'''
def seq():
    x = random.randint(0,1)
    if x == 0:
        pics = targetset
    print x

    #display initial target set
    for i in range(3):
        targetset[i].pos = setlocation[i]
        targetset[i].draw()

    window.flip()
    core.wait(3)

    #display targets
    for i in range(3):
        pics[i].pos = location[i]
        pics[i].draw()
        window.flip()
        core.wait(1)

seq()
core.wait(3)
window.close()
quit()

I hope someone can help, Cheers S


Solution

  • I see a few possible pitfalls with your code. One is that you are creating two separate lists imgList1 and imgList from the same set of images, then you are randomizing each of these lists separately and pulling the first three elements from each list into targetset and pics respectively. It is possible that these sub-sets will have some overlap in images. From the description of your task, I don't think that this is intentional. I might suggest creating only 1 imgList and then using the imgList.pop() function to pull images from the list. Pop returns the last element from the list and then deletes that element from the list. I think of it like drawing a card from a deck, you cannot draw the card again because it is no longer in the deck. What you're currently doing is like drawing cards from two different decks. You might get the same card twice.

    The second problem I see here is that you define a condition for what to do when your coin-flip for x is 0, but you do not define one for when your coin-flip is 1. Currently, it will just display the first 3 images from imgList because that's how you've defined pics. I might suggest defining pics within an if/else block for your x coin-flip. If it's 0, then go with targetset, if it's 1, then randomly choose an element from target list, then copy that element to pics and pop two more images from imgList. As with all coding, there is more than one way to solve this problem, but I'll offer a solution here.

    #Outside the trial loop
    imgList = glob.glob(os.path.join('stim', '*.png'))
    random.shuffle(imgList)
    
    #Inside the trial loop
    targetset = []
    for i in range(0,3):
        targetset.append(imgList.pop())
    #Do your display stuff with targetset
    if random.randint(0,1) == 0:
       pics = targetset
    else:
       pics = []
       pics.append(targetset[random.randint(0,2)])
       pics.append(imgList.pop())
       pics.append(imgList.pop())
    random.shuffle(pics)
    #Do your display stuff with pics