psychopy.org | Reference | Downloads | Github

I need to be able to randomize length of study lists

OS : Windows 10
PsychoPy version: 3.1.5

What are you trying to achieve?:
I am doing a serial recall task using 11 different consonants. I want 30 trials where they see the consonants then they report them in the order they saw them. I am getting stuck because I want the order of letters randomized but I also want different list lengths (2, 4, 6, 8, or 10). I want these different list lengths randomized. So for each trial it pulls consonants from my .csv with 11 letters on it. either 2 or 4 or 6 letters and so on. I can get the letters to come up but only at 1 specified length. I would also like it to tell the participant how many consonants they are about to see before each trial.

Example of a desired loop

4 —> W —> X ----> T —> S —> REPORT

Could I create a loop for each list length (2, 4, 6, 8, 10) and then have another loop that randomly picks which list length loop to use at the start of each trial?

Here is my excel stimulus list wordstimulus.xlsx (8.3 KB)

Here is what I have so far cognitiveoffloading10_5.psyexp (18.1 KB)

Thank you!!!

Separate your task into different routines: one to show the upcoming list length, a second to show the letters, and a third to do the reporting.

Insert a code component from the “custom” component panel into the first routine. In its “begin experiment” tab, put something like this:

list_lengths = [2, 4, 6, 8, 10]
shuffle(list_lengths)
show_prompt_trial = 0

Then in the “begin routine” tab, put something like this:

# check if this is the beginning of a trial, where
# you need to show the prompt:
if your_loop_name.thisN == show_prompt_trial:
    current_length = list_lengths.pop()
    your_text_stimulus.text = str(f'There will be {current_length} letters in this trial')

    # update for the next time it will be shown:
    show_prompt_trial = show_prompt_trial + current_length 
else:
    continueRoutine = False # skip this routine on most iterations

# record the value in the data on every trial:
thisExp.addData('list_length', current_length)

Ensure this code component is above the text stimulus on this routine, and that the text component is set to have a “constant” value, so that the code above can overwrite it.

On the third routine, you only want this to show on iterations of the loop where the last letter in a given sequence has been shown. So insert a code component on that routine and put something like this in its “begin routine” tab:

# only ask for a report on the iteration immediately before the 
# beginning of the next trial:
if your_loop_name.thisN != show_prompt_trial - 1:
    continueRoutine = False

None of this is tested, of course.

Hi @Michael, this worked really great! How exciting, thank you so much. One issue though is that it is only doing 5 trials, one trial for each list length. It randomizes the order of the list lengths but only does each one time then the experiment ends. I would like 30 trials with 6 trials per list size.

I have this in my first routine in the “begin experiment”

list_lengths = [2, 4, 6, 8, 10]
shuffle(list_lengths)
show_prompt_trial = 0

And this is in the same routine but in the “begin routine” tab.

# check if this is the beginning of a trial, where
# you need to show the prompt:
if choicetrials.thisN == show_prompt_trial:
    current_length = list_lengths.pop()
    lengthnumber.text = str(f'{current_length}')

    # update for the next time it will be shown:
    show_prompt_trial = show_prompt_trial + current_length 
else:
    continueRoutine = False # skip this routine on most iterations

# record the value in the data on every trial:
thisExp.addData('list_length', current_length)

Also what section of the code is actually telling it how many letters to present. Is list
_lengths a predetermined action that tells the program how many letters to present?

So it all worked great I just need 30 trials now.

Thank again!

I misread your description as meaning that you had 30 letters to present. To get 30 overall trials, simply do this to get a balanced list which has 30 entries (and implies presentation of 180 letters):

list_lengths = [2, 4, 6, 8, 10] * 6

There is no section of code doing that: the loop will just run through your conditions file until it ends. You just need to ensure that the number of rows in the conditions file exactly equals the sum of the numbers in list_lengths, which will now be 180 rather than 30.

i.e. the number of trials is the number of entries in list_lengths, and the number of letters that will be presented is the sum of all of those entries.

An alternative to your conditions file having 180 rows is that it is has 30 rows, but you specify an nReps value of 6 in the loop dialog, so each row gets repeated 6 times (or use whatever other factors of 180 give you the balancing across letters you need). If doing this, you need to understand the distinction between the “random” and “full random” options in the loop dialog.

NB PsychoPy’s datafile output is normally structured around one row per trial, because normally one iteration of a loop corresponds to one trial. But in this case, each loop iteration and thus each row of your data file will correspond to one letter being presented, i.e. there will be multiple (and varying) rows per trial. You’ll need to deal with that in your analysis scripts.