I created an experiment in Builder where I want my stimuli to be presented in pseudorandom order, e.g. without presenting more than 3 stimuli in the same condition in a row. I added a function called pseudoRand() in a Begin Experiment code component, adapted from here: Pseudo-randomization of stimuli trials in a loop
The following function works locally using PsychoPy:
import random
def pseudoRand(excelFile):
# Load trials
trials=data.importConditions(excelFile)
conditionMet = False
# Pseudo-randomize trials
while conditionMet == False:
random.shuffle(trials)
conditions = []
for row in range(len(trials)):
conditions.append(trials[row]["stim_type"]) #Name of the conditions type column
# Condition for pseudo-randomization: No consecutive same type
for row in range(len(trials) - 3):
if trials[row]["stim_type"] == trials[row + 1]["stim_type"] and trials[row]["stim_type"] == trials[row + 2]["stim_type"] and trials[row]["stim_type"] == trials[row + 3]["stim_type"]:
conditionMet = False
break
elif trials[row]["question_num"] == trials[row + 1]["question_num"] and trials[row]["question_num"] == trials[row + 2]["question_num"] and trials[row]["question_num"] == trials[row + 3]["question_num"]:
conditionMet = False
break
elif trials[row]["target_num"] == trials[row + 1]["target_num"] and trials[row]["target_num"] == trials[row + 2]["target_num"] and trials[row]["target_num"] == trials[row + 3]["target_num"]:
conditionMet = False
break
elif trials[row]["target_phoneme"] == trials[row + 1]["target_phoneme"] and trials[row]["target_phoneme"] == trials[row + 2]["target_phoneme"] and trials[row]["target_phoneme"] == trials[row + 3]["target_phoneme"]:
conditionMet = False
break
else:
conditionMet = True
# Save the final order of the trials
customOrder = []
for row in range(len(trials)):
customOrder.append(trials[row]["stim_order"]) #Name of the original index column
return customOrder
The function creates new random orders until all conditions are met (no more than 3 trials in each of the conditions of interest, namely “stim_type”, “question_num”, “target_num” and “target_phoneme”). I then call the function in the “Selected rows” property of my trial loop as:
$pseudoRand('List1_stim_data.csv')
To upload the experiment to Pavlovia, I edited the function in PsychoJS as follows:
shuffle = util.shuffle;
pseudoRand = function(excelFile) {
var conditionMet, conditions, customOrder, trials;
trials = data.importConditions(excelFile);
conditionMet = false;
while ((conditionMet === false)) {
shuffle(trials);
conditions = [];
for (var row, _pj_c = 0, _pj_a = util.range(trials.length), _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
row = _pj_a[_pj_c];
conditions.push(trials[row]["stim_type"]);
}
for (var row, _pj_c = 0, _pj_a = util.range((trials.length - 3)), _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
row = _pj_a[_pj_c];
if ((((trials[row]["stim_type"] === trials[(row + 1)]["stim_type"]) && (trials[row]["stim_type"] === trials[(row + 2)]["stim_type"])) && (trials[row]["stim_type"] === trials[(row + 3)]["stim_type"]))) {
conditionMet = false;
break;
} else {
if ((((trials[row]["question_num"] === trials[(row + 1)]["question_num"]) && (trials[row]["question_num"] === trials[(row + 2)]["question_num"])) && (trials[row]["question_num"] === trials[(row + 3)]["question_num"]))) {
conditionMet = false;
break;
} else {
if ((((trials[row]["target_num"] === trials[(row + 1)]["target_num"]) && (trials[row]["target_num"] === trials[(row + 2)]["target_num"])) && (trials[row]["target_num"] === trials[(row + 3)]["target_num"]))) {
conditionMet = false;
break;
} else {
if ((((trials[row]["target_phoneme"] === trials[(row + 1)]["target_phoneme"]) && (trials[row]["target_phoneme"] === trials[(row + 2)]["target_phoneme"])) && (trials[row]["target_phoneme"] === trials[(row + 3)]["target_phoneme"]))) {
conditionMet = false;
break;
} else {
conditionMet = true;
}
}
}
}
}
}
customOrder = [];
for (var row, _pj_c = 0, _pj_a = util.range(trials.length), _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
row = _pj_a[_pj_c];
customOrder.push(trials[row]["stim_order"]);
}
return customOrder;
}
This first led to an error as “data.importConditions()” is not supported by PsychoJS. Following Access Condition File variables online experiement - #2 by hellenjingyuan I edited:
trials = data.importConditions(excelFile);
to:
trials = excelFile;
However I now get this error:
TypeError: Cannot assign to read only property '18' of string 'List1_stim_data.csv'
I’m not familiar with JavaScript so I’m not sure where the issue is in the code (e.g., whether the indexing is wrong). Thanks in advance for the help!