Step 20¶
In this step, we’ll break down the components of the reaction-time.html
file used to create a reaction time experiment that you will participate in for class! Then in step 21, we'll use Pandas to analyze the data we collect.
The reaction time experiment is implemented in JavaScript using the jsPsych library, designed to help researchers conduct behavioral science experiments in a web browser.
Click this link to download the reaction-time.html
file
In order to read this file, you'll want to move it to a folder in VSCode, and open it there.
Throughout this step, I don't expect you to be learning JavaScript or jsPsych. Instead, I want you to see how the principles you've learned in Python programming apply to other languages and tools. By examining the experiment’s structure and components, you’ll see how programming concepts you’ve learned in Python are used in a different context.
We'll also need to cover some basic concepts of experimental design, we'll do that before we dive into the code.
General Principles of Experimental Design¶
Let's take a moment to recall (or learn for the first time!) the concepts of the Independent Variable and Dependent Variables in an experiment.
Independent Variable (IV)¶
The indepdent variable in the experiment is the thing that is being manIpulated - I personally remember this by thinking of the "I" in IV. In the reaction time experiement, the independent variable is the color of the circle that is displayed, which requires a specific key press response from the participant depending on the color of the circle.
Dependent Variable (DV)¶
The dependent variable in the experiment is the thing that is being measured - in other words, the thing that depends on the manipulated (independent variable). In the reaction time experiment, the dependent variable is the time it takes for the participant to press the correct key after the circle is displayed.
Control Variables¶
Control variables are variables that are kept constant throughout the experiment. In the reaction time experiment, the control variables include the size of the circle, the position of the circle on the screen, and the key press that is required for each color.
Data Collection¶
When programming an experiment, it's critical to think about how you're collecting your data. We'll look at how the data is collected in the reaction time experiment in the code breakdown.
Random and Blocked Designs¶
In the reaction time experiment, there are two different trial types, trials where the circle is blue and trials where the circle is orange. These trials are presented in randomized order, which is a common design in psychology experiments to prevent participants from anticipating the next stimulus.
If you wanted to understand how color similarity might make people respond more slowly, you could have an additional "block" of trials within the experiment where blue and - let's say, a blue-ish purple - are presented as competing colors. This would allow you to examine the difference in reaction time between the two color pairs of blue and purple, and blue and orange.
Jumping into the JavaScript¶
Important code blocks will be highlighted in the following sections, but feel free to explore the entire file! If you want to know how the entire code block works, you give the file to ChatGPT or Copilot and ask the chatbot to explain it to you!
Many of the decisions for the experiment are made outside of the code. For example, in this experiment, the colors were chosen to be blue and orange. While we will load images into the experiment to show these colors to the participant when we want to display them, the actual color of the circle is not defined in the code. This is a design decision that was made before the experiment was programmed.
Similarly, it's not written into the code that the color is the IV, and that reaction time is the DV. These are concepts that are understood by the researcher before the experiment is programmed.
Now we'll dive into the pieces of the code that make the experiment run.
Test Procedure¶
Below is a block of code within the JavaScript
called "test_procedure
", let's break it down:
var test_procedure = {
timeline: [fixation, test],
timeline_variables: test_stimuli,
repetitions: 25,
randomize_order: true
};
timeline
- The
timeline
parameter is an array of objects that represent the sequence of events in the experiment. Here, thetest_procedure
consists of two components:fixation
andtest
. Thefixation
object displays a fixation cross, while thetest
object presents the colored circle for the participant to respond to.
- The
timeline_variables
- The
timeline_variables
parameter specifies the stimuli to be used in the experiment. In this case,test_stimuli
is an array of objects containing the color of the circle and the correct response key for each trial.
- The
repetitions
- The
repetitions
parameter determines how many times thetest_procedure
is repeated. With 25 repetitions, it tells the experiment to show the orange and blue circles 25 times each, meaning that there will be 50 trials in total.
- The
randomize_order
- The
randomize_order
parameter specifies whether the order of trials should be randomized. When set totrue
, the order of trials is randomized to prevent participants from anticipating the next stimulus.
- The
Loading Images¶
This experiment uses two images, preloaded at the start to prevent delays during trials. Preloading is crucial when images need to display instantly. Other designs, like experiments requiring many images or complex visuals, may benefit from a more dynamic image-loading approach.
var preload = {
type: jsPsychPreload,
images: ['images/blue.png', 'images/orange.png']
};
timeline.push(preload);
In simpler terms, this code gets the images ready to be shown at a moment's notice. The jsPsychPreload
function is used to preload the images, ensuring they are ready for display when needed.
Data Storage and CSV Export¶
Data in this experiment is stored in memory by jsPsych, including response accuracy and reaction times. At the experiment’s end, participants see a summary with accuracy and average reaction time. The jsPsych.data.get().csv()
method then generates a CSV file of the collected data, downloadable via a button.
var jsPsych = initJsPsych({
on_finish: function() {
jsPsych.data.displayData();
document.getElementById('download-csv').style.display = 'block';
document.getElementById('download-csv').onclick = function() {
var csv = jsPsych.data.get().csv();
var blob = new Blob([csv], { type: 'text/csv' });
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = 'reaction_time_data.csv';
a.click();
window.URL.revokeObjectURL(url);
};
}
});
Let's break down the significant parts of the code block above:
jsPsych.data.displayData()
- This function displays the data collected during the experiment, showing participants their accuracy and average reaction time.
var csv = jsPsych.data.get().csv();
- This line generates a CSV file containing the data collected during the experiment.
var blob = new Blob([csv], { type: 'text/csv' });
- This code block creates a Blob object, which is a file-like object of raw data. In this case, it's a CSV file. A "Blob" is a way to store data that can be downloaded as a file.
a.download = 'reaction_time_data.csv';
- This line sets the
download
attribute of the anchor element to the desired filename for the downloaded CSV file. This allows the participant to download the data as a CSV file namedreaction_time_data.csv
.
- This line sets the
Connecting JavaScript and jsPsych to Python Principles¶
This experiment may be in JavaScript, but it uses many programming concepts you've learned in Python, let's think through them:
- Functions and Initialization: The function
initJsPsych()
initializes the experiment, just as you've used Python functions to set up programs and prepare data structures. - Control Structures (Loops and Conditions): The timeline configuration is structured similarly to Python dictionaries and lists. jsPsych uses objects to store multiple settings (analogous to Python’s dictionaries). Loops and conditional logic, like
randomize_order: true
, create flexible procedures, just as you’ve seen in Python loops and conditionals. - Trial Data Collection: The way trial data is collected and stored in
jsPsych.data.get()
is similar to Python data management libraries (likePandas
), where you collect, process, and export data. Here, we export as CSV, a format you’ve worked with for storing and analyzing data in Python. - Parameter Setting and Modularity: Each
timeline
component is modular and configured with specific parameters, similar to defining functions with arguments in Python. This modularity in design is essential for scalability and reusability in behavioral science programming.
In summary, although this experiment is in JavaScript, it reinforces core programming concepts: initializing structures, using loops and conditions to control flow, collecting data, and organizing code modularly.
These are skills you’ll carry into any programming language, allowing you to adapt tools like jsPsych confidently for experimental design.
Looking for more?¶
Check out the jsPSych documentation website to learn more about how to use jsPsych for your own experiments: https://www.jspsych.org/.