CoreDump: An Experiment in Peace.
Dump 04.17.2022.14.56
Lisa: Just returned from Unicef, we are to join the UN peacekeeping forces in Serbia. They put me through a JSpsych-based test to see my aversion to war, violence, and all that stuff, that was the criteria to join the forces...
Calvin: I don’t see the point of force to fight force, maybe pacifism was better?
Lisa: It is a deterrent alone, to see strong macho men with weapons, maybe dummies and body doubles fit in, like in the movies.
It may be a movie, the horror oscar award?
Lisa: In any case, I decided to put unsuspecting people through the same test, with images and responses, so I build this timeline with five images from unsplash.com
I use the plugin image-keyboard-response
var trial = { type: jsPsychImageKeyboardResponse, stimulus: ‘##Fill the Image Link##’, choices: [‘e’, ‘i’], prompt: “<p>Type Your Response? Press ‘e’ for happy and ‘i’ for sad.</p>”, };
The complete code can be converted to a Fill In The Blanks Templating.
<!DOCTYPE html>
<html>
<head>
<title>Peace!</title>
<script src="https://unpkg.com/jspsych@7.0.0"></script>
<script src="https://unpkg.com/@jspsych/plugin-html-keyboard-response@1.0.0"></script>
<script src="https://unpkg.com/@jspsych/plugin-image-keyboard-response@1.0.0"></script>
<script src="https://unpkg.com/@jspsych/plugin-preload@1.0.0"></script>
<link href="https://unpkg.com/jspsych@7.0.0/css/jspsych.css" rel="stylesheet" type="text/css" />
</head> <body></body>
<script> /* initialize jsPsych */
var jsPsych = initJsPsych({ on_finish: function() { jsPsych.data.displayData();
}
});
/* create timeline */
var timeline = []; /* preload images */
var preload = {
type: jsPsychPreload,
images: ['https//unsplash.com/photos/WFRBQ94Xhhc', https//unsplash.com/photos/xnK_o6OdTew',
https//unsplash.com/photos/-lWubJa7co, https://unsplash.com/photos/PEJHULxUHZs,
https://unsplash.com/photos/mhib6U1gMcU] }; timeline.push(preload); /* define welcome message trial */ var welcome = {
type: jsPsychHtmlKeyboardResponse,
stimulus: "Welcome to the experiment. Press any key to begin." };
timeline.push(welcome);
/* define instructions trial */var instructions = {
type: jsPsychHtmlKeyboardResponse,
stimulus: ` <p>In this experiment, five images appear in the center of the screen.</p>
<p>If you sense war </strong>, press the letter W on the keyboard as fast as you can.</p> <p>if you sense peace <strong>orange</strong>,
press the letter P
as fast as you can.</p> <div style='width: 700px;'>
<div style='float: left;'>
<img src='img/blue.png'></img> <p class='small'><strong>Press the F key</strong></p>
</div>
<div style='float: right;'><img src='img/orange.png'></img> <p class='small'><strong>Press the J key</strong></p></div> </div> <p>Press any key to begin.</p> `, post_trial_gap: 2000 }; timeline.push(instructions); /* define trial stimuli array for timeline variables */
var test_stimuli = [
{
stimulus: "https://unsplash.com/photos/mhib6U1gMcU", correct_response: 'w'},
{
stimulus: "https://unsplash.com/photos/PEJHULxUHZs", correct_response: 'w'},stimulus: "https://unsplash.com/photos/-lWubJa7-co", correct_response: 'w'},
stimulus: "https://unsplash.com/photos/xnK_o6OdTew", correct_response: 'w'},
stimulus: "https://unsplash.com/photos/WFRBQ94Xhhc", correct_response: 'w'} ]; /* define fixation and test trials */ 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 test = { type: jsPsychImageKeyboardResponse, stimulus: jsPsych.timelineVariable('stimulus'), choices: ['f', 'j'],
data: { task: 'response', correct_response: jsPsych.timelineVariable('correct_response') }, on_finish: function(data){ data.correct = jsPsych.pluginAPI.compareKeys(data.response, data.correct_response); } };
/* define test procedure */
var test_procedure = { timeline: [fixation, test], timeline_variables: test_stimuli, repetitions: 5, randomize_order: true };
timeline.push(test_procedure); /* define debrief */ var debrief_block = { type: jsPsychHtmlKeyboardResponse, stimulus: function() { var trials = jsPsych.data.get().filter({task: 'response'}); 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}ms.</p>
<p>Press any key to complete the experiment. Thank you!</p>`; } };
timeline.push(debrief_block); /* start the experiment */ jsPsych.run(timeline); //data persistence
var data = jsPsych.data.get().filter({trial_type: 'image-keyboard-response'});
var count = jsPsych.data.get().filter({correct: true}).count();
var response_times = jsPsych.data.get().select('rt');
jsPsych.data.get().select('rt').mean(); jsPsych.data.get().select('rt').sum(); jsPsych.data.get().select('rt').min(); jsPsych.data.get().select('rt').max(); jsPsych.data.get().select('rt').variance(); jsPsych.data.get().select('rt').sd(); jsPsych.data.get().select('rt').median(); jsPsych.data.get().select('rt').count();<?php // get the data from the POST message
$post_data = json_decode(file_get_contents('php://input'), true); $data = $post_data['filedata']; // generate a unique ID for the file, e.g., session-6feu833950202
$file = uniqid("session-"); // the directory "data" must be writable by the server
$name = "data/{$file}.csv"; // write the file to disk file_put_contents($name, $data); ?>function saveData(name, data){
var xhr = new XMLHttpRequest();
xhr.open('POST', 'write_data.php'); // 'write_data.php' is the path to the php file described above.
xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify({filedata: data})); } // call the saveData function after the experiment is over
initJsPsych({ on_finish: function(){ saveData(jsPsych.data.get().csv()); }
});var trial = { type: jsPsychCallFunction, async: true, func: function(done){
var xhr = new XMLHttpRequest();
xhr.open('POST', 'write_data.php'); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function() {
if(xhr.status == 200){
var response = JSON.parse(xhr.responseText); console.log(response.success); }
done(); // invoking done() causes experiment to progress to next trial. };
xhr.send(jsPsych.data.get().json()); } }
</script>
</html>
Calvin: That looks like spaghetti code, with ancient AJAX and PHP! a function is still missing, I quote
“It involves a short PHP script and a few lines of JavaScript code. This method will save each participant’s data as a CSV file on the server. This method will only work if you are running on a web server with PHP installed, or a local server with PHP (e.g., XAMPP).”
<?php // get the data from the POST message
$post_data = json_decode(file_get_contents('php://input'), true); $data = $post_data['filedata']; // generate a unique ID for the file, e.g., session-6feu833950202
$file = uniqid("session-"); // the directory "data" must be writable by the server
$name = "data/{$file}.csv"; // write the file to disk file_put_contents($name, $data); ?>
You need to save this to disk as a PHP program and make sure PHP is either on the local server or the hosting server. You need to ask your system admin for help.
Lisa: It was always so easy, to have asked the system administrator or maybe even the librarian, they are code literate these days …