Chapter 17 Giving feedback

Sometimes you might want to give participants feedback on their performance. In particular, this might be the case while they are still practising the task, as shown in the flow of our flanker task:

In this example, participants will be presented with a routine called feedback after every practice trial. The problem is that you cannot know what type of feedback (e.g., correct or incorrect) will be required in advance, because the feedback will depend on the participant’s response. Therefore, you will need to figure out what feedback to give on the fly, while the experiment runs. To achieve this, you need to add a Code component (located in Custom components) to the feedback routine:

Code components allow you to insert Python code into an experiment. You don’t need to learn how to write Python code to be able to do this, but you need to know a few Python basics. I’ve compiled these basics in Appendix I. If you have no previous experience using Python, you should have a look at the appendix first.

First, let’s go through how this works in our flanker task (again, please open the flanker task in PsychoPy and make sure you can find the relevant routines and components):

  • Routine trial
    • The Text component presents the stimulus.
    • The Keyboard component records the response.
    • If we told it to (see Section 12.3), the Keyboard component will store the accuracy of the response.
  • Routine feedback
    • The Code component checks whether the response was correct or incorrect.
    • Depending on the accuracy, the Code component updates the message to be shown as feedback.
    • The Text component presents the feedback message.

Here is what we need to know to make this work in PsychoPy:

  • The name of the Keyboard component that stores the accuracy of the response. In our flanker task, this is response.
  • PsychoPy stores the accuracy information in a variable called <nameOfResponseComponent>.corr
    • The text between the angle brackets is a place-holder for the actual name of the component.
    • In our example, the relevant variable would be response.corr.
  • PsychoPy codes correct responses as 1, and incorrect responses as 0.
  • The feedback message itself is some text that needs to change from trial to trial. Therefore, it needs to be a variable (see Section 15.1). In our flanker task, this variable is called fbMsg.
  • After the Code component has figured out what the feedback message should be, we would like to present the feedback to the participant using a Text component. As described in Section 15.1, we thus need to add $fbMsg to the Text component presenting the feedback in the routine feedback and set it to set every repeat.

Now, let’s look at the actual Python code. We need two pieces of code in two different places. The first piece of code is this:

fbMsg = "Argh! It's not working!"

This needs to be placed in the “Begin Experiment” tab of the Code component:

The aim of this is to define the variable and to assign a value to it that will help you figure out whether or not your feedback is working. You could simply define an empty string, but this will make it harder to determine what is going wrong if the feedback doesn’t work as intended:

fbMsg = ""  # possible, but not useful!

The second piece of code is this:

if response.corr == 1:    # if the response was correct
    fbMsg = "Correct!"    # this should be our FB message
else:                     # alternatively (i.e., the response was incorrect)
    fbMsg = "Incorrect!"  # this should be our FB message

This needs to be placed in the “Begin Routine” tab of the Code component:

Note that the order of components is important! In the routine feedback, the Code component needs to be above the Text component, otherwise the feedback will not work (see Section 18.2).

For some experiments, you might also want to give “Too slow!” feedback if a participant does not respond before a set RT deadline. In this case, you need to slightly modify the above approach, because PsychoPy codes both “wrong” responses and “too slow” responses as 0. Thus, we also need to check whether or not a key was pressed to decide if the feedback should be “Too slow!” or “Wrong!”. This is the code:

if response.corr == 1:  # correct response
    fbMsg = "Correct!"
elif response.corr == 0 and response.keys != None:  # response given, but it was not correct
    fbMsg = "Wrong!"
elif response.corr == 0 and response.keys == None:  # no response given
    fbMsg = "Too slow!"

How does this work?

  • PsychoPy stores the information about pressed keys in a variable called <nameOfResponseComponent>.keys
  • In Python, None (capitalisation is again important here!) means “no value”; here it means that no response keys were pressed

You could replace the latter elif statement by simply saying else:, but being more verbose sometimes makes it easier to understand what the code does.