Scripting in Gorilla: The Big 5 Questionnaire


Overview


This walkthrough introduces the use of the script widget in the questionnaire. To do this, we'll go through the Big 5 Questionnaire and how the script widget is used to collate and process participant answers into their personality score. The Big 5 Questionnaire can be found here in the Samples here.

The Questionnaire


The Big 5 Personality TIPI is a standard questionnaire that can be found in 'Samples' > 'Classic Tasks: Personality'.

As implemented in this example, the questionnaire consists of a Rich Text widget, followed by a series of Rating Scale/Likerts widgets and finally a script widget. We will primarily discuss the Script widget during the course of this walkthrough. To gain an understanding of the other Questionnaire widgets and how they work please visit the article here

To the participant, the Questionnaire will look like this.

As you can see, we don't see any of the contents of the Script widget here - that runs silently in the background of the Questionnaire, once the data has been entered by the participant. Let's look at that now!

Scripting Goals


To calculate the participants personality score, we need to collect their answers and then run some post-processing on them to create a score and rating for each personality area. We'll be doing this using the Script widget.

Below is the complete script from the zone, with a few annotations on the purpose of each area. We'll go through the contents and workings of each part in the next sections - this is just to give you the overall picture

This section of the script collects the answers from each question, reversing them if necessary.

var extroversionNormal = parseInt(gorilla.retrieve('extroversionNormal', 4, true));
var agreeablenessReverse = 8 - parseInt(gorilla.retrieve('agreeablenessReverse', 4, true));
var conscientiousnessNormal = parseInt(gorilla.retrieve('conscientiousnessNormal', 4, true));
var emotionalStabilityReverse = 8 - parseInt(gorilla.retrieve('emotionalStabilityReverse', 4, true));
var opennessNormal = parseInt(gorilla.retrieve('opennessNormal', 4, true));

var extroversionReverse = 8 - parseInt(gorilla.retrieve('extroversionReverse', 4, true));
var agreeablenessNormal = parseInt(gorilla.retrieve('agreeablenessNormal', 4, true));
var conscientiousnessReverse = 8 - parseInt(gorilla.retrieve('conscientiousnessReverse', 4, true));
var emotionalStabilityNormal = parseInt(gorilla.retrieve('emotionalStabilityNormal', 4, true));
var opennessReverse = 8 - parseInt(gorilla.retrieve('opennessReverse', 4, true));

This section calculates a score for each personality trait using the appropriate answers.

var extroversion = (extroversionNormal + extroversionReverse) / 2;
var agreeableness = (agreeablenessReverse + agreeablenessNormal) / 2;
var conscientiousness = (conscientiousnessNormal + conscientiousnessReverse) / 2;
var emotionalStability = (emotionalStabilityReverse + emotionalStabilityNormal) / 2;
var openness = (opennessNormal + opennessReverse) / 2;

This section calculates a rating for each personality level.

var extroversionRange = [2.99, 4.44, 5.89];
var agreeablenessRange = [4.12, 5.23, 6.34];
var conscientiousnessRange = [4.08, 5.4, 6.72];
var emotionalStabilityRange = [3.41, 4.83, 6.25];
var opennessRange = [4.31, 5.38, 6.45];

var getRating = function(score, range) {
    if(score < range[0]) {
        return 'Low';
    } else if(score >= range[0] && score < range[1]) {
        return 'Medium Low';
    } else if(score >= range[1] && score < range[2]) {
        return 'Medium High';
    } else {
        return 'High';
    }
}

var extroversionRating = getRating(extroversion, extroversionRange);
var agreeablenessRating = getRating(agreeableness, agreeablenessRange);
var conscientiousnessRating = getRating(conscientiousness, conscientiousnessRange);
var emotionalStabilityRating = getRating(emotionalStability, emotionalStabilityRange);
var opennessRating = getRating(openness, opennessRange);

This section uploads each of the scores and ratings to Gorilla, so they can be used in the experiment tree.

gorilla.store('extroversion_score', extroversion, true);
gorilla.store('extroversion_rating', extroversionRating, true);

gorilla.store('agreeableness_score', agreeableness, true);
gorilla.store('agreeableness_rating', agreeablenessRating, true);

gorilla.store('conscientiousness_score', conscientiousness, true);
gorilla.store('conscientiousness_rating', conscientiousnessRating, true);

gorilla.store('emotional_stability_score', emotionalStability, true);
gorilla.store('emotional_stability_rating', emotionalStabilityRating, true);

gorilla.store('openness_score', openness, true);
gorilla.store('openness_rating', opennessRating, true);

This final section uploads the scores and ratings to the metrics, so they appear in your downloadable data file for the questionnaire.

gorilla.metric({
    question_key: 'extroversion_score',
    response: extroversion,
})

gorilla.metric({
    question_key: 'extroversion_rating',
    response: extroversionRating,
})

gorilla.metric({
    question_key: 'agreeableness_score',
    response: agreeableness,
})

gorilla.metric({
    question_key: 'agreeableness_rating',
    response: agreeablenessRating,
})

gorilla.metric({
    question_key: 'conscientiousness_score',
    response: conscientiousness,
})

gorilla.metric({
    question_key: 'conscientiousness_rating',
    response: conscientiousnessRating,
})

gorilla.metric({
    question_key: 'emotional_stability_score',
    response: emotionalStability,
})

gorilla.metric({
    question_key: 'emotional_stability_rating',
    response: emotionalStabilityRating,
})

gorilla.metric({
    question_key: 'openness_score',
    response: openness,
})

gorilla.metric({
    question_key: 'openness_rating',
    response: opennessRating,
})

In the next section, we'll discuss each part of the script in more detail

Collecting Answers


Over the course of the next few section, we'll go through how to collect, calculate and then store the values for the extroversion score and rating. For the other personality traits, the process will be almost identical.

To calculate the participants extroversion score we need the participants answers to the 'Extroverted, enthusiastic' and 'Reserved, quiet' questions. To do this, we need the Key for each of these questions. The Key is an option that exists on some Questionnaire widgets that is used to mark a participants response to this question in the metrics, as well as to store the answer in embedded data. To learn more about this setting go here (link to questionnaire article)

For the 'Extroverted, enthusiastic' question you can see the key below, highlighted in red.

For the above question, the key is extroversionNormal. For 'Reserved, quiet', the key is extroversionReverse.

Next we use a special function in gorilla called (retrieve) to collect the stored answer from the participants embedded data.

gorilla.retrieve('extroversionNormal', 4, true)

retrieve is one of a number of functions that exists in the 'gorilla' library - a javascript library which we provide in the Questionnaire, Task and Code Editor tools.

The function takes three arguments. The first is the key we located earlier. The second is a default value to return, in case we don't find anything stored in that key. This could happen if you've allowed the question to be 'missing' i.e. unanswered. It is optional, though your script could break if retrieve doesn't return something sensible! The third argument indicates whether or not we should look in local or global storage for this key. Because the answer is being stored in 'embedded_data' we need to look in global storage - this will almost always be the task when using this function in a questionnaire.

For more information on gorilla.retrieve please see the API docs which I haven't finished writing yet.

Next, we need to to a little bit of processing on this retrieved value and then assign it to a variable for later use. We'll do this using standard JavaScript functions and variable declarations. If you're familiar with JavaScript, looking at the code in the previous section may be enough to understand what happens next - in which case, move on to the next section. Otherwise, keep reading!

The gorilla.retrieve function will return our information to us in the form of a string - text. We need to do some number crunching on it and we can't do that to a piece of text so we first need to parse it into a suitable format. As all the answers the participant can give to the likert question are whole numbers, let's parse it to an integer.

parsetInt(gorilla.retrieve('extroversionNormal', 4, true))

This forces the returned text into an integer format.

Finally, as we need to use this information later in the script, we'll assign it to a variable called 'extroversionNormal'.

var extroversionNormal = parseInt(gorilla.retrieve('extroversionNormal', 4, true));

Variable declarations in JavaScript are easy! All you need to do is use the keyword 'var' followed by a name for the variable. It's always good practice to make this something easy to remember and relevant to information being stored: e.g. calling it 'extroversionNormal' is much more informative than 'variable1'!

For the 'Reserved, quiet' question, we need to reverse the score i.e. if the answer is 7 give it a score of 1. To do this, we just need to subtract the collected value from 8.

var extroversionReverse = 8 - parseInt(gorilla.retrieve('extroversionReverse', 4, true));

Calculating Scores and Ratings


We've now stored the answer for 'Extroverted, enthusiastic' in the variable 'extroversionNormal' and the reversed answer for 'Reserved, quiet' in the variable extroversionReverse. Next, we're going to do some processing on these variables to calculate a score for the extroversion personality trait and then assign it a rating from Low to High. All of this next section of code is just standard JavaScript - there's nothing unique to Gorilla here!

First, to calculate our score, we'll add our extroversionNormal and extroversionReverse values together and divide them by two.

var extroversion = (extroversionNormal + extroversionReverse) / 2;

Notice we've assigned the result to a new variable 'extroversion.'

Now, we need to give this value a rating from low to high. We'll need two things to do this: a sense of what values should be considered low, medium or high and then, for ease of use, a function to determine where the value sits in the range. While we are only calculating one range here, in the full script we calculate four.
Rather than repeating all that code, its better to put it in a function.

To begin, we define the range for extroversion.

var extroversionRange = [2.99, 4.44, 5.89];

Any extroversion score lower than 2.99 we'll call 'low'. Anything between 2.99 and 4.44 we'll call 'Medium Low'. Anything between 4.44 and 5.89 we'll call 'Medium High' and anything above 5.89 we'll call 'High.'

To work out what rating we should give a score, we're going to create a function. This function will take in a score and a range as arguments and will return to us a string that says what rating the score is. There are a number of different ways to define functions in JavaScript. The method we use here is similar to creating a variable except that, rather than assign a value to the variable, we assign a function to it. It then works in the same way that functions do in many other coding languages.

var getRating = function(score, range) {
    if(score < range[0]) {
        return 'Low';
    } else if(score >= range[0] && score < range[1]) {
    	return 'Medium Low';
    } else if(score >= range[1] && score < range[2]) {
    	return 'Medium High';
    } else {
    	return 'High';
    }
}

To use this function to find our extroversion range we just need to give it the right variables.

var extroversionRating = getRating(extroversion, extroversionRange);

We pass in our extroversion score and extroversion range as arguments to the function and assign the result to a new variable 'extroversionRating.' The function uses a series of if statements to check the score compared to elements in the array. The syntax for this is very similar to that used in other languages for if/else statements and accessing array elements.

Now that we have finished our preprocessing, the final step is to store these values for later use and, very importantly, include them in the participants metrics!

Storing Scores and Ratings


The last things we need to do is store our calculated values for use later and upload them to the participants metrics. We'll do both of these by using some functions that gorilla provides for you!

Storing values_

The first of these is 'store'.

gorilla.store('extroversion_score', extroversion, true);

gorilla.store is the other half of gorilla.retrieve. Where gorilla.retrieve() allows us to retrieve embedded data, gorilla.store() allows us to add embedded data to the store or update an existing value in the store. It requires three arguments. The first is a key, in the form of a string, that will be used to store the value and access it again later. It's useful to make these keys memorable so that you won't have to look them up all the time. In this case, we've used the key 'extroversion_score.' The second argument is the value we want to be stored. This is our extroversion variable. The final argument indicates whether you want the data to be stored locally or globally. In order to access the embedded data in the experiment tree and in other tasks, we're going to use the global option, for which we use 'true'.

Uploading to the metrics

Our last action is to also add the extroversion score to our metrics. To do this, we use the function gorilla.metric().

gorilla.metric({
    question_key: 'extroversion_score',
    response: extroversion,
})

gorilla.metric takes a single argument called a 'dictionary'. This is an object of key-value pairs. To understand this a little better let's look at the argument a bit closer.

question_key: 'extroversion_score',

The first part question_key is the key. This key will be used to store the passed value in the metrics. It corresponds to the Question Key column in your downloadable data and the value passed along side this key will appear in that column. Importantly, when using gorilla.metric in the Questionnaire Builder or Task Builder, these must match keys that already exist in the metrics. We'll be providing a more detailing listing of these keys in a future article - however, the two keys listed above are the ones you'll most likely need to use.

The second part 'extroversion_score' is the value to be stored under that key. It will appear in the Question Key column in your participants metrics.

Each key-value pair in the dictonary needs to be seperated by a comma. Our next pair is

response: extroversion,

This will upload the value of extroversion, our extroversion score, to the metrics with the key 'response'. This will appear in the column in your data download labelled 'Response'.

We then do the same for the extroversion rating.

gorilla.metric({
    question_key: 'extroversion_rating',
    response: extroversionRating,
})

Note that each individual value that you want to upload to the metrics needs to be uploaded in a seperate call to gorilla.metric.

And there we have it! We've collected our participants answers, calculated some additional information based on those answers and then uploaded them to our data store as well as our metrics!