| Reference | Downloads | Github

Sequential variable and random variables


I’m creating an experiment on Psychopy3 with the Builder (I don’t know how to code in python and I would like to use just the builder).

My experience consists of displaying pairs of words on the screen, followed by the appearance of a dot. I would like the words to appear in sequential order (so I selected “sequential” in the loop type), however I want the point position to be random (below or above the word pair) but I want that this position is not fixed for a pair of words. In other words, I would like PsychoPy to work in columns and not in lines.


How can I do ?

Thank you in advance,

Hi @Fanny, here is a demonstration of shuffling single columns in your conditions file. This will create a new conditions file, which you need to feed into your loop. In the attached example, the shuffled column is called “Prime”, so this will need replacing with “PositionPoint”. E.g.,

import pandas as pd 

# Get condition file
dat = pd.read_excel("your-condition-file.xlsx", index=False)
# Shuffle Prime column
dat.loc[:, 'PositionPoint'] = np.random.permutation(dat['PositionPoint'].values)
# save shuffled dataframe to new spreadsheet ready for loop
dat.to_excel("newCond.xlsx", index=False)

Builder doesn’t have the built-in flexibility to handle that (it can only work with entire rows of your conditions file). But in this case, it will be possible to tweak Builder’s behaviour with a few tiny snippets of Python code:

  • Delete the “PositionPoint” column of your conditions file (as the control of that variable will now be handled in code).
  • Insert a “code component”. These come from the custom component panel in the Builder window, and when you open it it will have a tabs into which you can paste code, which run at specific times in the experiment.

In the “begin experiment” tab, put something like this:

# create a vertical position for each trial:
vertical_point_pos = [0.2, -0.2] * 10
#randomise the order across subjects:

NB the multiplier above should be half your number of trials: I can’t see how many rows you have in your conditions file, so instead of 10, use the number appropriate for your design.

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

# get a value for this trial:
current_vertical_point_pos = vertical_point_pos.pop()
# record it in the data file manually:
thisExp.addData('vertical_point_pos', current_vertical_point_pos)

Then in your stimulus component for the point, simply specify its position like this:

$[0, current_vertical_point_pos]

and set that field to update very repeat.

Make sure that the code component is above the point stimulus component, so that the latter gets to refer to the current value of current_vertical_point_pos .

EDIT: or use David’s answer, as we must have been thinking about this simultaneously but from different directions. :wink:

Ha yes, although I prefer your version @Michael. It will be easy to translate into JavaScript for online use, whereas the use of Pandas in my example limits the use to Python tasks only.

Thanks you very much @dvbridges and @Michael for your answers. I try with Michael’s version. But when I Run the expermient, this message appears :

current_vertical_point_pos = vertical_point_pos.pop()
IndexError: pop from empty list

I Don’t know what to do ?

Every time you pop an entry out from a list, the list shrinks in length. That list was defined like this:

# create a vertical position for each trial:
vertical_point_pos = [0.2, -0.2] * 10

In the example above, you would get a list of 20 values (two entries repeated 10 times). As noted, you need to adjust the multiplier to ensure it matches your number of trials.


That’s what I tried but it doesn’t function. Don’t matter, I’m gonna try an other solution. Thanks you very much for response.