psychopy.org | Reference | Downloads | Github

Creating multiple loops and lists

Hi all,

For my experiment, I am creating a simple reaction time test. It will have 4 blocks, with 6 trials in each. I have managed to present the first trial of a block on screen. However, I am not sure whether I should be creating a number of lists (i.e. to hold the different stimuli for the different trials) or if I should be altering the characteristics of my one existing loop. My code is below:

from psychopy import visual, core, event #import some libraries from PsychoPy
import psychopy.event

#Create the code for saving the data at some point


#create a window
mywin = visual.Window([1920,1080], monitor="testMonitor", units="deg")
mywin.update()

# create the six stimuli:
Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them
Stim_text = ["Berlin", "Paris", "London", "Nice", "Vienna", "Charming"] # their content

#the positions of the stimuli
positions = [
 (-10, 10),
 (10, 10),
 (-10, -10),
 (10, -10),
 (-1, -10),
 (1, 10),
 ]

#Initial message to participants about the study 
message1 = visual.TextStim(mywin, text = "You have been captured by the plotters. As a test to see if you have information regarding the event, an on screen test will be adminstered. Press Spacebar when ready")
message1.draw()
mywin.update()

#this will wait for a button press confirmation from p's to continue
response = event.waitKeys(keyList = ['space',], timeStamped = True)

#Initial message to participants about the study 
message1 = visual.TextStim(mywin, text = "On the next screen, you will be presented with a practice round of stimuli. Press Q if any of the cities are familiar, or press P if you do not recognise the cities")
message1.draw()
mywin.update()

#this will wait for a button press confirmation from p's to continue
response = event.waitKeys(keyList = ['space',], timeStamped = True)

#Loop for drawing the stimulus 
#code for the keyboard response
keys = psychopy.event.waitKeys(keyList=["q", "p"])

#Practice round-should it be stopped by a button press?

for frameN in range(7*60):
    # draw each stim *on each frame*
    for i in range(len(Stim_text)):
        Target.setPos(positions[i])
        Target.setText(Stim_text[i])
        Target.draw()
    # now flip the window (after all stimuli drawn)
    mywin.flip()

#Initial message to participants about the study 
message1 = visual.TextStim(mywin, text = "On the next screen, the cities which our intelligence tells us are at risk will be presented. Press Q if any are familiar, press P if not blah blah blah.. press space when ready")
message1.draw()
mywin.update()
response = event.waitKeys(keyList = ['space',], timeStamped = True)#wait for subjects to state they are ready

#Cities block
#First trial 

print Stim_text
del Stim_text[1,2]
print Stim_text

Any help is much appreciated

Nathan

Hello Nathan, you also seem to have asked this question at StackOverflow. Please just ask in one place, to avoid duplication of effort (the same people answer at each location).

I’d suggest deleting the SO question as you might need a bit of to-and-fro discussion on this, which this forum is better suited to.

Hi Michael,

You are quite right-this forum is probably much better to converse on. So I have managed to get some code to work, but what is happening is that: Either each entire list of stimuli appears in each position (Loop 2), or only one list appears in only one position(loop 4). I’m really stuck as to how to get the 6 six lists to be part of the same loop, as well as the positions of these lists randomised (which I have the code for, and have confirmed that it works).

from psychopy import visual, core, event #import some libraries from PsychoPy
import psychopy.event
import os
from psychopy import data
from random import shuffle
import random, copy

#Create the code for saving the data at some point

#create a window
mywin = visual.Window([1920,1080], monitor="testMonitor", units="deg")
mywin.update()

# create the stimuli lists:
#Practice Round
Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them cities not used in the main exp!
Practice_Stim_text = ["Montreal", "Melbourne", "Boston", "Havana", "Toronto", "Tripoli"] # their content



#First trial of cities block
Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them
Stim_textT1 = ["Berlin", "Paris", "Brussels", "Madrid", "Vienna", "Athens"] # their content

#Second trial of cities block
Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them
Stim_textT2 = ["Berlin", "London", "Stockholm", "Istanbul", "Vienna", "Warsaw"] # their content

#Third trial of cities block
Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them
Stim_textT3 = ["Berlin", "Budapest", "Stockholm", "Warsaw", "Madrid", "Istanbul"] # their content

#Fourth trial of cities block
Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them
Stim_textT4 = ["Paris", "London", "Brussels", "Frankfurt", "Helsinki", "Istanbul"] # their content

#Fifth trial of cities block
Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them
Stim_textT5 = ["Paris", "Budapest", "Athens", "Vienna", "Stockholm", "Warsaw"] # their content

#Sixth trial of cities block 
Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them
Stim_textT6 = ["London", "Budapest", "Madrid", "Brussels", "Athens", "Helsinki"] # their content

List_of_all_Stimulilists = [ Stim_textT1, Stim_textT2, Stim_textT3, Stim_textT4, Stim_textT5, Stim_textT6]


trials = ["Stim_textT1", "Stim_textT2"]

#the positions of the stimuli
positions = [
 (-10, 10),
 (10, 10),
 (-10, -10),
 (10, -10),
 (-1, -10),
 (1, 10),
 ]

#Initial message to participants about the study 
message1 = visual.TextStim(mywin, text = "You have been captured by the plotters. As a test to see if you have information regarding the event, an on screen test will be adminstered. Press Spacebar when ready")
message1.draw()
mywin.update()

#this will wait for a button press confirmation from p's to continue
response = event.waitKeys(keyList = ['space',], timeStamped = True)

#Initial message to participants about the study 
message1 = visual.TextStim(mywin, text = "On the next screen, you will be presented with a practice round of stimuli. Press Q if any of the cities are familiar, or press P if you do not recognise the cities")
message1.draw()
mywin.update()

#this will wait for a button press confirmation from p's to continue
response = event.waitKeys(keyList = ['space',], timeStamped = True)

#Some more information about the study 
message1 = visual.TextStim(mywin, text = "A response deadline of three seconds will be imposed, so you must make your response within this time. Press the spacebar when ready")
message1.draw()
mywin.update()
response = event.waitKeys(keyList = ['space',], timeStamped = True)


#Loop for drawing the stimulus 
#code for the keyboard response
keys = psychopy.event.getKeys(keyList=["q", "p"])

#Practice round-should it be stopped by a button press?
#On these two loops, its possible to randomise the positions of the stimuli! Only one is needed for the practice round though
#Loop 1
for frameN in range(2*60):
    # draw each stim *on each frame*
    for i in range(len(Practice_Stim_text)):
        Target.setPos(positions[i])
        Target.setText(Practice_Stim_text[i])
        Target.draw()
    # now flip the window (after all stimuli drawn)
    mywin.flip()


#for frameN in range(2*60):
    # draw each stim *on each frame*
    #for i in range(len(Practice_Stim_text)):
#        Target.setPos(positions[i])
#        random.shuffle(positions)
#        Target.setText(Practice_Stim_text[i])
#        Target.draw()
    # now flip the window (after all stimuli drawn)
#    mywin.flip()
#    psychopy.core.wait(4)









#Initial message to participants about the study 
message1 = visual.TextStim(mywin, text = "On the next screen, the cities which our intelligence tells us are at risk will be presented. Press Q if any are familiar, press P if not blah blah blah.. press space when ready")
message1.draw()
mywin.update()
response = event.waitKeys(keyList = ['space',], timeStamped = True)#wait for subjects to state they are ready


#Loop 2
#Cities block#
for block in range(6):
   for i in range(len(List_of_all_Stimulilists)):
    Target.setPos(positions[i])
    Target.setText(List_of_all_Stimulilists[i])
    Target.draw()
    
mywin.flip()    
psychopy.core.wait(4)

#Loop 3
#Cities block# RANDOMISED POS
#for block in range(6):
#   for i in range(len(List_of_all_Stimulilists)):
#    Target.setPos(positions[i])
#    random.shuffle(positions)
#    Target.setText(List_of_all_Stimulilists[i])
#    Target.draw()
#    
#mywin.flip()    
#psychopy.core.wait(4)

#Loop 4
# Run the code inside this loop four times
for block in range(6):
    for i, position in enumerate(positions):
         # Prepare stimulus
        Target.pos = position
        Target.text = List_of_all_Stimulilists[i]
for i, value in enumerate(List_of_all_Stimulilists[i]):

        # Show it 
        Target.draw()
        mywin.flip()
        psychopy.core.wait(4)

So to reiterate, I am trying to present the six words around the fixation cross consecutively. Instead of using 6 loops, I wish to use nested for loops-one to cycle through the 6 lists, and one to draw the positions of these stimuli

Nathan

Hi Nathan,

You know what you want to achieve, but at this stage we don’t. The code is quite problematic for a number of reasons, so we can’t work out your intentions from that.

So what is needed here is a very precise, step-by-step description in prose of what you want to achieve. Start from the highest level (how many trials will run), to the trial level (what events happen in what sequence), down to frame-by-frame level (e.g. what stimuli are drawn and where).

A good pseudo-code-like description like that will make it much easier to translate into actual code.

But there are also some very basic Python things going wrong here, which make me think you might benefit from just some general Python language learning. e.g. when you do this six times in a row:

Target = visual.TextStim(mywin, text = "text default")
text_stim_list = [] # a list to hold them

You realise that there is only one reference to each of these variables, and they are needlessly being re-created an additional 5 times after the first time?

You might also find that the TrialHandler class will help you here immensely. You could move a lot of your stimulus information into an an external .csv or .xlsx conditions file rather than hard-coding it. The API is here http://www.psychopy.org/api/data.html and there are demos available from the Demos menu in PsychoPy. A TrialHandler object reads in all the variables for each trial from a row in that external file, and handles randomisation for you, as well as storing your data for you.