Introduction

The easiest and most straightforward to choose conditions and stimuli is by using a table. The table contains what parameters are used in a condition (e.g., which stimulus and which response).

For some experimental designs, that is not the necessarily the most straightforward way of doing this. There is different way of doing it which we will discuss here.

Example experiment

Let’s imagine this example situation.

A researcher wants to show two pictures at the same time on the screen. On the left, the researcher wants to show a picture of a person in a uniform and on the right the researcher wants to show a picuture of a person in a uniform. The participant needs to respond with kbd:[y] or kbd:[n] whether the two match (e.g., a fire truck with a firewoman).

The researcher has 5 images of people in uniforms (nurse,fireman,policeman,soldier,farmer) and 5 images of cars (ambulance,fire truck, police car, tank, tractor). So

The research wants that the 5 images of vehicles are randomly combined with the 5 uniforms.

This can be done with tables

In principle, this can be done with a table, and it would contain 25 rows (one for each combination). If you have longer lists the tables can become very long. There is actually a tool in PsyToolkit (create table) on the left in the PsyToolkit screen that you can use for these sort of combinations, but there is another way of doing it as well.

Doing it with random numbers

We have in total 10 images for this experiment, so let’s assume this list of pictures in your bitmap section.

bitmaps
  nurse
  fireman
  policeman
  soldier
  farmer
  ambulance
  firetruck
  policecar
  tank
  tractor

The way PsyToolkit represents these internally is simply as numbers. The computer knows that nurse is image number 1, fireman is image number 2. We use this to choose images as follows.

task match_me
  set $my_person random 1 5 (1)
  set $my_car random 6 10  (2)
  show bitmap $my_person -150 0  (3)
  show bitmap $my_car 150 0  (4)

In this example, we have created two new variables using the set command. One is $my_person which will contain the number of the image to be used on the left for the person to be shown. The other is $my_car will contain the number of the car.

1 We set the variable $my_person to a value between 1 and 5 because the first five bitmaps in the bitmaps section are the person images.
2 We set the variable $my_car to a value between 6 and 10 because the next five bitmaps in the bitmaps section are the person images.
3 Now we show the person on the left of the screen (-150 means 150 pixels left from screen center)
4 Now we show the car on the right of the screen (150 means 150 pixels right from screen center)

And that is it. Well that is the short story. The next thing is collecting a response and making sure you know whether there is a match or not (are people correct or not).

Adding response and checking correctness

task match_me
  keys y n (1)
  set $my_person random 1 5
  set $my_car random 6 10
  show bitmap $my_person -150 0
  show bitmap $my_car 150 0
  # (2)
  set $my_diff expression $my_car - $my_person  (3)
  set $correct_key 2  (4)
  if $my_diff == 5 (5)
    set $correct_key 1  (6)
  fi  (7)
  #
  readkey $correct_key 5000  (8)
  if STATUS == CORRECT  (9)
    show bitmap correctresponse  (10)
  fi
  if STATUS != CORRECT  (11)
    show bitmap wrongresponse
  fi
  delay 1000  (12)
  clear -1  (13)
  save $my_person $my_car $correct_key STATUS RT  (14)
1 Tell the computer to only use the keyboard keys kbd:[y] and kbd:[n]
2 This comment character just creates a bit of space (i.e., enhances readability) between two parts of code that do different things, just for clarity.
3 We know that correct matches are pictures 1 and 6, 2 and 7, 3 and 8, 4 and 9, and 5 and 10. Thus, the difference is 5. Here we calculate what the difference between the two pictures is
4 One of the two keys will be correct. It is key 1 (i.e., the kbd:[y]) or key 2 (i.e., the kbd:[n]). We assume by default that the correct key is kbd:[n] and later on we change this if not correct.
5 If and only if the difference between the two pictures equals 5 (i.e., == stands for is equal in computer languages), then do the following line…​
6 …​that means the first key, the kbd:[y], is the correct key.
7 The end of the if block
8 Now we the $correct_key variable contains either 1 or 2, exactly as needed. Now we wait for a key press for 5000 ms (or 5 secs) and we tell the computer what the correct key is given the two images shown
9 Another if block. The following line is only done if the response was correct …​
10 …​ we show a bitmap that contains something like a happy message "well done"
11 We also have an if block if the response was not correct (!= stands for is not in computer languages).
12 Now we leave the feedback bitmap for 1000 ms (1 second) on screen
13 We remove the last added bitmap (-1) from the screen.
14 Now we save all the useful information to the output data file. It is important that you know which stimuli were shown, what the correct response would be, the actual status (1=correct, 2=wrong, 3=time out), and the response time RT.

How can I prevent repeating the same stimuli in repeating trials?

The above is great, but what if the same stimulus combination is repeated on consequtive trials? When using tables you can use no_repeat but that does not work, so you need to make it even a bit more complicated.

Basically, you need to "remember" which images were done in the previous trial and simply do not chose them again. For this, we are going to change the code.

For this, it is useful to explain the idea of "local" and "global" variables in PsyToolkit (a concept used in many programming languages).

A local variable in PsyToolkit starts with a $ sign.

A global variable in PsyToolkit starts with a & sign.

In principle, you can just always use global variables and everything would work just the same. So why ever use local variables? I have actually thought of not having "local" variables at all in the PsyToolkit language.

But there is something nice about local variables. Local variables are being reset to zero at the beginning of a trial. So every trial you start with a clean slate of variables.

But now we also need some variables remember what happened in the previous trial, and for that we are going to introduce some global variables.

Then we are going to add a while loop. Let me first explain just that before showing the whole set of code.

In the following code, we start with choosing the random value of $my_person, and then we keep doing that while the newly chosen value of $my_person is the same as &pervious_person. You do the line between while and _while_end until the condition is no longer true. At the end, we then store the new value of $my_person to the &previous_person variable so that we can use that in the next trial. This way, you will not have repeats.

task match_me
   set $my_person random 1 5
   while $my_person == &previous_person
     set $my_person random 1 5
   while-end
   set &previous_person $my_person

Now using this way of coding, we can make sure that neither of the variables are repeated.

task match_me
  keys y n
  set $my_person random 1 5
  set $my_car random 6 10
  while $my_person == &previous_person
    set $my_person random 1 5
  while-end
  set &previous_person $my_person
  while $my_car == &previous_car
    set $my_car random 6 10
  while-end
  set &previous_car $my_car
  #
  show bitmap $my_person -150 0
  show bitmap $my_car 150 0
  #
  set $my_diff expression $my_car - $my_person
  set $correct_key 2
  if $my_diff == 5
    set $correct_key 1
  fi
  #
  readkey $correct_key 5000
  if STATUS == CORRECT
    show bitmap correctresponse
  fi
  if STATUS != CORRECT
    show bitmap wrongresponse
  fi
  delay 1000
  clear -1
  save $my_person $my_car $correct_key STATUS RT