OK, insert a “code component” from the component panel. It will have multiple tabs, so you can paste in code that will run at specific times. In the Begin experiment tab, put something like this to create a function that you can use to select random samples of letters:
from numpy.random import choice # to draw random samples
from string import ascii_uppercase # the upper case alphabet
# function you can call to get samples from the alphabet as required:
def choose_letters():
alphabet = list(ascii_uppercase) # a list of length 26
# sample 8 letters without replacement:
sample = choice(alphabet, size = 8, replace = False)
return list(sample) # convert from a numpy array to a list
# define a constant sample of letters that will apply for this
# subject throughout their session:
session_list = choose_letters()
Your flow panel should have the target routine next to the distractor routine, and they should be nested together within a single loop (let’s call it letters
: pro-tip – you should use meaningful names for loops, rather than just have them all called trialsxx
: this will make your data much easier to analyse, and your flow panel with then actually describe your design/procedure).
letters
should have an nReps
value of 8 and doesn’t need to be connected to a conditions file (unless there are other variables you want to access).
letters
should be nested within an outer loop called, say trials
, which will have an nReps
of 24, and again, no conditions file.
So now you need to define a new list of 8 letters that will apply throughout the trial, so we set this to just get a new list on the first iteration of the inner loop (so it will run once for every iteration of the outer loop, or once per trial). So in the Begin routine tab, put some code like this:
# only once per trial, update the letter list:
if letters.thisN == 0:
# On every third trial, use the constant
# session list, otherwise get a fresh sample:
if (trials.thisN + 1) % 3 == 0:
trial_letters = session_list
else:
trial_letters = choose_letters()
# on every iteration of the inner loop, select a new
# letter, indexing by the iteration number:
current_letter = trial_letters[letters.thisN]
# record it in the data:
thisExp.addData('current_letter', current_letter)
Make sure that the code component is placed above your text stimulus component (that way, the text component can refer to the latest variables defined in the code component). Then just put this in the text field:
$current_letter
and set that field to update on every repeat.
The magic sauce here is the %
modulus operator, which gives us the remainder after dividing by 3. If the remainder is 0 (after adding 1 to the trial number to account for them starting at 0), then this is a trial with the constant letters.
Hey presto, you are in business, and with easy access to an almost infinite number of possible selections, as opposed to mucking about with conditions files.