Unable to give feedback on answers

OS Win10
PsychoPy version 2

I have built an experiment to test participants ability to recall a word from a word pair. The experiment shows participants one word from the word pair and the participants have to type the corresponding word. I have built the experiment so that participants see their answers on screen as they type and they are able to correct mistakes as they type and press enter when they are happy with their answer.

This means that resp.keys store every key press so an answer for the word light may look something like this: [‘l’, ‘i’, ‘f’ ‘backspace’ ‘g’, ‘h’, ‘t’, ‘return’]. In addition I have also designed the experiment to store the final text string using the following code:

thisExp.addData(‘inputText’, inputText)
inputText=“”

Therefore the data output file looks something like this:

What I would like to do is to give feedback to participants about whether their answers are correct or incorrect. I have set the correct answer to be corrAns (in red) but this is compared to resp.keys (in blue) which contain an infinite amount of different strings based on participants key presses and so resp.corr is always 0 even if participants write the correct word.

Therefore I thought the easiest solution would be to create feedback by comparing inputText (in blue) to corrAns (in red). I attempted this by creating an addition routine at the end of the loop so that feedback shows after each trial. I created a text box in this routine with the text: $msg. I then created the following code within this routine:

However when I try to run the experiment I am presented with the following error:

if inputText=$corrAns: msg=‘correct!’
‘’‘’‘’‘’‘’‘’ ^
SyntaxError: invalid syntax

I am hoping someone here can help. What I need to achieve is basically a feedback message after each trial telling them if they were correct or incorrect. I cannot set the correct answer to a string version of the word e.g. '[‘s’,‘e’,‘a’,‘t’, ‘return’] as we want to test older participants and so expect mistakes. Please let me know if you need any more information to help!

1 Like

Hi.

The bulk of what you’ve done is fine - it’s just you’ve missed a couple of Python conventions.
The $ sign is not nessecary in code components since you are dealing with python code anyway - in other builder components it is used to indicate that the following is a variable rather than a constant - in code any non-python text outside of quotes is treated as a variable.

You also need to indent (typically one tab) your if and else statements - Python uses white space to indicate that the following is bound by the if statement:

if inputText == corAns:
     msg = 'Correct'
else:
   msg = 'Sorry, Incorrect'

However, you can also just use:

if inputText.corr:
  msg.....

which is basically a Boolean (True/False) variable that is set automatically depending on whether the input = corAns.

Best wishes,

Oli

Hi Oli,

Thanks for the quick reply, this is the first experiment I have ever coded (excluding some simple tutorials) so I still have a lot to learn.

I tried your first solution and got rid of the error and psychopy let me run the experiment. However the incorrect answer message appeared even when I entered the correct answer. I checked the output data and as you can see corrAns and inputText are identical so the correct answer message should appear.

I then tried your second solution and was give the following error when I tried to run the experiment:

if inputText.corr:
AttributeError: ‘str’ object has no attribute ‘corr’

I am not sure why the first solution is not working, it seems as if psychopy is having difficulty identifying inputText, perhaps because it is a variable created during the experiment? Just a guess.

Sorry - inputText should actually be the name of the keyboard component - e.g.

 key_resp_2.corr

Also make sure that your code component is above the text component in your routine - or the the message will be set after the text component has been displayed.

BW

Oli

hang on - are you getting participants to type in words? I don’t think that will work because the keyboard component will save a list not a string i.e.

Typed
C A M E R A

Stored
key_resp_2.keys = [‘C’,‘A’,‘M’,‘E’,‘R’,‘A’]

Which are not the same. Do you participants need to produce this freely, or could you use a different input method like C = Camera?

A way around this would be to store your words as lists = so in excel have corAns with [‘c’,‘a’,‘m’,‘e’,‘r’,‘a’] - when that is compared with key_resp_2.keys it would return true. However, this would not allow backspacing so it would have to be typed in perfect first time…

Hi Oli,

Unfortunately we need participants to recall the entire word as it is a memory test. This is the issue I have been facing, the responses are stored as a string of key presses while all the other psychopy experiments I have come across only require single key press to answer. That is why I have included the inputText variable which only stores the characters on screen before they press enter (their final answer).

I am hoping there will be a way to compare inputText with the corrAns as storing the correct answers as lists [‘c’,‘a’,‘m’,‘e’,‘r’,‘a’, ‘enter’] is not a viable solution as we expect older adults to make typing mistakes.

OK - got a solution here…

keyboard component should look like:

then have a code component in your typing routine with the following:

#Each frame
if len(key_resp_2.keys) > 0: #to prevent list index error
    if key_resp_2.keys[len(key_resp_2.keys) - 1] == 'backspace': #allow backspacing
        try: #to avoid list index errors when backspacing
            key_resp_2.keys.pop(len(key_resp_2.keys)-1)
            key_resp_2.keys.pop(len(key_resp_2.keys)-1)
        except:
            print 'no need to backspace'
    elif key_resp_2.keys[len(key_resp_2.keys) - 1] == 'return': #allows return to end routine
        key_resp_2.keys.pop(len(key_resp_2.keys)-1)
        continueRoutine = False

#end of Routine
if key_resp_2.keys == list(corAns):
    msg = 'TRUE'
    trials.addData('correct', 1) #where trials is the name of the loop
    trials.addData('response', ''.join(key_resp_2.keys))
else:
    msg = 'FALSE'
    trials.addData('correct', 0) #store for accuracy
    trials.addData('response', ''.join(key_resp_2.keys)) #store full response

if you want to give feedback you can change TRUE and FALSE in the above to whatever you like and have a $msg entry in a text component in a feedback routine.

BW

Oli

1 Like

Hi Oli,

Thanks for spending so much time working on a solution. I have copied it exactly into my experiment except I had to call the keyboard component key_resp_1 as key_resp_2 already exists later on in the experiment (but I have updated the name in the coding).

Psychopy doesn’t seem to like the else in the end of routine section, I am getting the following error when I try to run the experiment:

else:
^
SyntaxError: Invalid syntax

I can’t detect anything wrong with the syntax however…

if key_resp_1.keys == list(corrAns):
msg = ‘TRUE’
trials.addData(‘correct’, 1) #where trials is the name of the loop
trials.addData(‘response’, ‘’.join(key_resp_1.keys)
else:
msg = ‘FALSE’
trials.addData(‘correct’, 0) store for accuracy
trials.addData(‘response’, ‘’.join(key_resp_1.keys) store full response

Any suggestions?

Ah - with syntax errors it’s either on the same line or the line before - add another bracket to the very end of the line just above…same with the bottom line - I’ll amend it in my post too

It works! Thanks so much Oli.

I do not want to take up much more of your time as you have been so helpful with this all but I wondered since you seem to be gifted in python, do you know how I can get the text to appear on screen as participants are typing so they can see their answers? If not then I am sure I will be able to figure it out some how! :sweat_smile:

Lee

hahahah - not gifted, just persistent.

Sorry I forgot to mention that - you would have a text component with a blank duration and Set Every Frame selected for the text update option - then add:

$''.join(keyList)

to the text box

2 Likes

That works great, thank you!

Final question, I promise! In the feedback, I want to give participants the correct answer if they get it wrong. So the coding for my typing routine looks like this:

End of routine

if key_resp_1.keys == list(corrAns):
msg = ‘Correct!’
trials.addData(‘correct’, 1) #where trials is the name of the loop
trials.addData(‘response’, ‘’.join(key_resp_1.keys))

else:
msg = ‘Incorrect, the correct answer was $corrAns’
trials.addData(‘correct’, 0) store for accuracy
trials.addData(‘response’, ‘’.join(key_resp_1.keys)) store full response

I would like the correct answer to display during the incorrect message but I am not sure how to do this. Obviously the way I have it at the moment just outputs “Incorrect, the correct answer was $corrAns” when you run the experiment. Any ideas?

You want formatted strings for that -

msg = 'incorrect, the answer was %s' %corrAns
1 Like

Hi Oli,

Thanks, that worked like a charm! :slight_smile:

Lee

Hello - I have the same question: how can I have participants see the letters and numbers that they are typing in real time? I’ve tried doing what you said about join(keyList), but it didn’t work for me: it says keyList is undefined. I’m in Builder. Any ideas? Thanks!

Hey Oli,
I’m running into a similar problem. I have all of the code working for the participant to type in a response and then receive feedback, but I want them to get correct feedback if they spell a word wrong, to a certain degree. For example, if the type in “whales” instead of “whale” then I would like them to get correct feedback. I’m not sure if this is possible, but if you have any suggestions, that would be great.

Hi - could you be more specific about the types of answer you want accepting? Is it typo’s, homophones, conjugations or just pluralisation? If you have a specified selection of possible answers then it would be easy enough - you’d just use list comprehension to compare the input to all specified entries - if it’s typos etc it would require regular expressions I expect.

I would like to accept typos, with maybe like 75% overlap with the correct spelling. Also pluralization if possible. I’m relatively new to coding so I’m not that familiar with list comprehension or regular expressions. Right now I have an excel file with the correct answers (spelled correctly and no plurals) and have the program matching the participant responses to that. I would like participants to get correct feedback for typos and pluralization and also for the program to recognize those as correct answers in the output file.

The are a variety of algorithms out there to quantify the nearest of one string to another, e.g.

https://pypi.python.org/pypi/editdistance

Michael,
I have actually read through this. The issue is that I’m not skilled enough with coding to implement this on my own. I was looking for someone to give me a better understanding of how to do this.