Testing truth value works for 3 conditions works, but not 4 #2802
-
Hello, I'm new to jspsych, and I'm building a Stroop task in which I want to avoid 4 types of repetitions in consecutive trials: two consecutive stimuli (a) printed the same ink color, or (b) representing the same word; or a stimulus (c) representing the word corresponding to the ink color of the previous stimulus, or (d) printed in the ink color corresponding to the printed word of the previous stimulus. On lines 414-415 (see full code below), I use the function below to rule out type of repetition (a), and when I run the code locally in my browser, the code executes correctly:
I have no problem either when I replace the original function by the following ones to rule out (a) & (b), and then (a) & (b) & (c):
However, as soon as I add type of repetition (d) as shown below, the code no longer executes in my browser, and the page endlessly keeps trying to load. I'm failing to understand the issue.
Thank you very much in advance for any suggestion you may have! <!DOCTYPE html>
<html>
<head>
<title>Attempt</title>
<script src="https://unpkg.com/[email protected]"></script>
<script src="https://unpkg.com/@jspsych/[email protected]"></script>
<link href="https://unpkg.com/[email protected]/css/jspsych.css" rel="stylesheet" type="text/css" />
</head>
<body></body>
<script>
var jsPsych = initJsPsych({
on_finish: function() {
//jsPsych.data.get().localSave('csv', 'mydata.csv');
window.location = "https://yalesurvey.ca1.qualtrics.com/jfe/form/SV_5yWvFUxmyEt2mDs?subjectid=" + subject_id + ""
}
});
var timeline = [];
var numbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
var colors = ["red", "green", "blue", "black"];
// capture info from Prolific ID
var subject_id = jsPsych.data.getURLVariable('subjectid');
//jsPsych.data.addProperties({
// subject: subject_id
//});
var instructions = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<p>In this agility test, you will see words presented in different colors.</p>
<p>Your task is to indicate the <u>COLOR</u> that each word is printed in,
while ignoring what the word actually says.</p>
<p>Indicate the color of the word by pressing either of the following keys:</p>
<p>- d for <b><FONT COLOR=red>red</FONT></b> words.</p>
<p>- f for <b><FONT COLOR=green>green</FONT></b> words.</p>
<p>- j for <b><FONT COLOR=blue>blue</FONT></b> words.</p>
<p>- k for <b>black</b> words.</p>
<p><u>Example:</u> if you see the word <b><FONT COLOR=green>RED</FONT></b> printed in the color green, press ' f ' for green words,
regardless of the meaning of the word.</p>
<p>Press space to start the practice round.</p>
<div style='width: 700px;'>
</div>`,
data: {
task: 'instructions'
},
post_trial_gap: 1000
};
timeline.push(instructions);
var instructions2 = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<p>Get ready:</p>
<p>Place your index and middle fingers over the ' d ', ' f ', ' j ', and ' k ' keys.</p>
<div style='width: 700px;'>
</div>`,
choices: "NO_KEYS",
data: {
task: 'instructions'
},
trial_duration: 4000
};
timeline.push(instructions2);
function choose_color() {
return jsPsych.randomization.sampleWithoutReplacement(["red", "green", "blue", "black"], 1);
};
var myArray = ["red", "green", "blue", "black", "red", "green", "blue", "black", choose_color()[0], choose_color()[0]];
function shuffle_colors(tableau) {
return jsPsych.randomization.shuffle(tableau);
};
var color_assignment = shuffle_colors(myArray);
function translation(color) {
if (color === 'red') {
return 'd';
} else {
if (color === 'green') {
return 'f';
} else {
if (color === 'blue') {
return 'j';
} else {
if (color === 'black') {
return 'k';
} else {
return "problem";
}
}
}
}
};
function parameters(i) {
var color_selected;
var color_translated;
var color_selected = color_assignment[i];
var color_translated = translation(color_selected);
return {
stimulus: '<p style = "color: ' + color_selected + '; font-size: 60pt; "> ' + numbers[i] + ' <\/p>',
word: numbers[i],
color: color_selected,
correct_response: color_translated,
stim_type: "control"
};
};
var practice_stimuli = [
parameters(0),
parameters(1),
parameters(2),
parameters(3),
parameters(4),
parameters(5),
parameters(6),
parameters(7),
parameters(8),
parameters(9)
];
var fixation = {
type: jsPsychHtmlKeyboardResponse,
stimulus: '<div style="font-size:60px;">+</div>',
choices: "NO_KEYS",
trial_duration: function() {
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
},
data: {
task: "fixation"
}
};
var practice = {
type: jsPsychHtmlKeyboardResponse,
stimulus: jsPsych.timelineVariable('stimulus'),
choices: ["d", "f", "j", "k"],
data: {
task: 'practice',
word: jsPsych.timelineVariable('word'),
color: jsPsych.timelineVariable('color'),
congruency: jsPsych.timelineVariable('stim_type'),
correct_response: jsPsych.timelineVariable('correct_response')
},
on_finish: function(data) {
console.log(data);
data.correct = jsPsych.pluginAPI.compareKeys(data.response, data.correct_response);
}
};
var practice_procedure = {
timeline: [fixation, practice],
timeline_variables: practice_stimuli,
randomize_order: true,
repetitions: 1
}
timeline.push(practice_procedure);
var instructions3 = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<p>Practice is over. We will now start the real test. </p>
<p>Try to respond as <b>quickly</b> and <b>accurately</b> as you can, because you will be timed.</p>
<p>Press space when you are ready.</p>
<br></br>
<p><u>Reminder</u>: Your task is to indicate the <u>COLOR</u> that each word is printed in,
while ignoring what the word actually says.</p>
<p>Indicate the color of the word by pressing either of the following keys:</p>
<p>- d for <b><FONT COLOR=red>red</FONT></b> words.</p>
<p>- f for <b><FONT COLOR=green>green</FONT></b> words.</p>
<p>- j for <b><FONT COLOR=blue>blue</FONT></b> words.</p>
<p>- k for <b>black</b> words.</p>
<p><u>Example:</u> if you see the word <b><FONT COLOR=green>RED</FONT></b> printed in the color green, press ' f ' for green words,
regardless of the meaning of the word.</p>
<div style='width: 700px;'>
</div>`,
data: {
task: 'instructions'
},
post_trial_gap: 2000
};
timeline.push(instructions3);
var test_stimuli = [{
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>red<\/p>",
word: "red",
color: "red",
correct_response: "d",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>red<\/p>",
word: "red",
color: "red",
correct_response: "d",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>red<\/p>",
word: "red",
color: "red",
correct_response: "d",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>red<\/p>",
word: "red",
color: "green",
correct_response: "f",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>red<\/p>",
word: "red",
color: "blue",
correct_response: "j",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>red<\/p>",
word: "red",
color: "black",
correct_response: "k",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>green<\/p>",
word: "green",
color: "red",
correct_response: "d",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>green<\/p>",
word: "green",
color: "green",
correct_response: "f",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>green<\/p>",
word: "green",
color: "green",
correct_response: "f",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>green<\/p>",
word: "green",
color: "green",
correct_response: "f",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>green<\/p>",
word: "green",
color: "blue",
correct_response: "j",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>green<\/p>",
word: "green",
color: "black",
correct_response: "k",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>blue<\/p>",
word: "blue",
color: "red",
correct_response: "d",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>blue<\/p>",
word: "blue",
color: "green",
correct_response: "f",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>blue<\/p>",
word: "blue",
color: "blue",
correct_response: "j",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>blue<\/p>",
word: "blue",
color: "blue",
correct_response: "j",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>blue<\/p>",
word: "blue",
color: "blue",
correct_response: "j",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>blue<\/p>",
word: "blue",
color: "black",
correct_response: "k",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>black<\/p>",
word: "black",
color: "red",
correct_response: "d",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>black<\/p>",
word: "black",
color: "green",
correct_response: "f",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>black<\/p>",
word: "black",
color: "blue",
correct_response: "j",
stim_type: "incongruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>black<\/p>",
word: "black",
color: "black",
correct_response: "k",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>black<\/p>",
word: "black",
color: "black",
correct_response: "k",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>black<\/p>",
word: "black",
color: "black",
correct_response: "k",
stim_type: "congruent"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "red",
correct_response: "d",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "red",
correct_response: "d",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: red; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "red",
correct_response: "d",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "green",
correct_response: "f",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "green",
correct_response: "f",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: green; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "green",
correct_response: "f",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "blue",
correct_response: "j",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "blue",
correct_response: "j",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: blue; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "blue",
correct_response: "j",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "black",
correct_response: "k",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "black",
correct_response: "k",
stim_type: "control"
}, {
stimulus: "<p id = 'stroop_stim' style = 'color: black; font-size: 60pt;'>xxxx<\/p>",
word: "xxxx",
color: "black",
correct_response: "k",
stim_type: "control"
}];
var repeatedSet = jsPsych.randomization.repeat(test_stimuli, 3);
var shuffled = jsPsych.randomization.shuffleNoRepeats(repeatedSet, function(a, b) {
return a.color === b.color
//return a.color === b.color || a.word === b.word
//return a.color === b.color || a.word === b.word || a.color === b.word
//return a.color === b.color || a.word === b.word || a.word === b.color
//return a.color === b.color || a.word === b.word || a.word === b.color || a.color === b.word
});
var test = {
type: jsPsychHtmlKeyboardResponse,
stimulus: jsPsych.timelineVariable('stimulus'),
choices: ["d", "f", "j", "k"],
data: {
task: 'test',
word: jsPsych.timelineVariable('word'),
color: jsPsych.timelineVariable('color'),
congruency: jsPsych.timelineVariable('stim_type'),
correct_response: jsPsych.timelineVariable('correct_response')
},
on_finish: function(data) {
console.log(data);
data.correct = jsPsych.pluginAPI.compareKeys(data.response, data.correct_response);
}
};
var test_procedure = {
timeline: [fixation, test],
timeline_variables: shuffled,
randomize_order: false,
repetitions: 1
}
timeline.push(test_procedure);
var debrief_block = {
type: jsPsychHtmlKeyboardResponse,
stimulus: function() {
var trials = jsPsych.data.get().filter({
task: 'test'
});
var correct_trials = trials.filter({
correct: true
});
var accuracy = Math.round(correct_trials.count() / trials.count() * 100);
var rt = Math.round(correct_trials.select('rt').mean());
return `<p>You responded correctly on ${accuracy}% of the trials.</p>
<p>Your average response time was ${rt} milliseconds.</p>
<p>Your performance on this test would pass the bar for most industries.</p>
<p>Press any key to complete the experiment. Thank you!</p>`;
},
data: {
task: 'debrief'
}
};
timeline.push(debrief_block);
jsPsych.run(timeline);
</script>
</html> |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Hi @Oriane4972, I think the problem is that, when all four constraints are in place, there are too few valid permutations (i.e. trial orders) that meet your requirements. This issue is noted in the One option is to loosen your constraints a bit. For instance, maybe it's ok to repeat a word or color across neighboring trials, but not more than once, and only a certain number of times across the experiment. Or maybe some constraints are more important than others? If you need to keep all four of these constraints for neighboring trials, you'll probably have to find a different way of constructing the trial sequence, e.g. programmatically using a custom algorithm, or selecting from pre-defined trial sequences that meet your criteria. |
Beta Was this translation helpful? Give feedback.
Hi @Oriane4972, I think the problem is that, when all four constraints are in place, there are too few valid permutations (i.e. trial orders) that meet your requirements. This issue is noted in the
jsPsych.randomization.shuffleNoRepeats
docs here. The experiment hangs because jsPsych keeps shuffling the trial order and checking to see if the new order meets the constraints, which it doesn't, and repeating this process over and over again without success.One option is to loosen your constraints a bit. For instance, maybe it's ok to repeat a word or color across neighboring trials, but not more than once, and only a certain number of times across the experiment. Or maybe some constraints a…