I’m building a linguistic experiment and I’d like for the participants to rewrite a sentence they are presented with.
I started using the builder but then changed to the coder to try and modify the code. Adding some lines to the code for the keyboard response I’ve managed to capture all the keys the participant presses until ‘return’ is pressed. However, this is far from ideal… I can’t make the participant see what he’s writing which makes the task almost impossible, and I don’t really want ALL the keys he presses, just the final rewritten sentence.
Does somebody know a way to do this? Is there a pre-defined function that does this and I just haven’t been able to find it?
Hi @alba, a simple solution involves using text and code components in Builder. Have one component display text called e.g., displayText, and another called e.g., copyText
In the code component, add the following code to the relevant tabs. Note, the shift keys to capitalize are not working at this point.
keys = event.getKeys()
if 'escape' in keys:
core.quit() # So you can quit
else:
if keys:
if keys[0] == 'space':
textFill += ' ' # Adds a space instead of 'space'
elif keys[0] == 'backspace':
textFill = textFill[:-1] # Deletes
elif keys[0] in allLetters:
textFill+=keys[0] # Adds character to text if in alphabet.
copyText.setText(textFill) # Set new text on screen
Thank you, @dvbridges!!
That solved my problem And it was such a quick response, what a great surprise (it’s my first time in the forum and I thought it would take a while to get an answer)!
And since we are here…
I guess that if shift keys to capitalize are not working neither are special characters like ‘ç’ or ‘ã’, am I right? (I work with Portuguese and it has A LOT of those…)
In fact, I have another experiment in which the participants just assign a number to each sentence and in the data file the original sentence has lost its special characters and instead has some capital letters with other symbols, for example:
‘está’ becomes ‘está’
No problem @alba. If you do want capitalisation to work, you could use the following for “Every Frame”. The alternative is to use iohub, which has options of checking whether a particular key on the keyboard is down or up. That might make a more fitting solution, but for now:
keys = event.getKeys()
if 'escape' in keys:
core.quit()
else:
if keys:
if keys[0] == 'space':
textFill += ' '
elif keys[0] == 'backspace':
textFill = textFill [:-1]
elif keys[0] in allLetters and not capitalize:
textFill+=keys[0]
# Dealing with shift
elif keys[0] in ['lshift', 'rshift']:
capitalize = True
if len(keys)>1 and 'lshift' in keys or 'rshift' in keys: # If shift and letter together
keys = [key for key in keys if key not in ['lshift', 'rshift']]
if capitalize == True and keys[0] in allLetters:
textFill += keys[0].upper()
capitalize = False
text_2.setText(textFill)
As for the characters coming out incorrectly, it sounds like the character encoding is going wrong. How are you reading the data?
Sorry for the delay, I’ve been crazy busy over here. I introduced a loop in the builder version which reads the sentences from a .xlsx file. Then the output file I get is a .csv which contains these weird transformations of special characters. I don’t know what I’m doing wrong
Thanks again for the code, that solves the capitalization perfectly! But my main concern is actually the special characters like ç ã á à that the subjects in the experiment may want to use… Is there a way to solve this? Maybe using their extended ASCII code?
It looks like PsychoPy is doing its job, and using several bytes to represent non-ASCII characters (using UTF-8 encoding). It is probably the case that the software you are using to open your data file is not Unicode aware, or at least, doesn’t default to assume that the text is UTF-8 encoded (let me guess, you’re using Excel, right?) If so, see the relevant part of this post:
I know this is an old thread, but hopefully someone may see it and respond…I have been trying to work out how to write to the screen for weeks now and this is the first code I have been successful with. Thank you!
My question is, how do I also allow it to accept numbers as well as letters? I’m sure this is simple, but I’m so new to this that I am unsure what to adjust.
Sorry, one more question, I’m using the above code as part of a loop where it is reading a maths question from my Excel spreadsheet. This code allows me to write the answer to the screen, but what would the command be to move to the next math question in the sequence after they have typed their answer? I am happy for the participant to hit ‘return’ after they have written their answer.
You could insert something like this somewhere in your list of checks above:
elif keys[0] == 'return':
# record the answer in your data file:
thisExp.addData('answer', textFill)
# go on to the next trial:
continueRoutine = False
One other thing: the code above is structured around only processing one keypress per screen refresh. If a person types very quickly, it’s possible that this might miss some keypresses (e.g. say two keypresses make it into the event queue but the code only checks the first one (keys[0]). If this seems to be an issue, the code could be restructured to loop through all keys in the queue on every screen refresh.
Hi this subject helped me a lot!!!
I’m using Psychopy V3.0.7 in linux ubuntu 18.04, it works ok on my computer, but when I sync the builder code with Pavlovia.org. The behavior does not seems to be the same.
I mean the “writen response” does not shows on screen as I am typing.
Is there a solution or a bypass I can do to have the same behavior as local.
HI @djan4848, this is a Python code solution for writing keypresses to the screen. You would have to go to code component, change the code type to “Both” and translate your Python code into JavaScript, because currently the translation of code components is manual. However, there is already a solution from another post. Have a look at the following:
Tanks for your help. After enabling the “both” option in the builder and declaring following javascript code I got the test working in an acceptable online way:
‘’'if (test_7.status == PsychoJS.Status.STARTED){
var answer = prompt(“Respuesta:”, “?”);
test_7.setText(answer);
psychoJS.experiment.addData(‘Answer’,test_7.getText());
psychoJS.experiment.addData(‘RT’,respuestaClock.getTime());
continueRoutine = false;
Hi @djan4848, just for info, I have uploaded a demonstration of using written responses online and on your desktop. The demo can be ran from the URL, or downloaded from Pavlovia for use locally.
Sorry to get back to this topic, but I’ve tried to use the script @dvbridges generously provided to allow for special characters and capital letters (I’m also working with Portuguese) and I get the following error:
if capitalize == True and keys[0] in allLetters:
NameError: name ‘capitalize’ is not defined"
When I use the original code with the line:
else:
textFill += keys[0] # Adds character to text
provided by @Michael I’m able to use numbers (but not special characters or capital letters) but not the ones in the numbers pad (I get something like: num_1 or num_2…).
Also, I would like to create a frame (a small square 10cmx10cm) with a different color for the text that participants will be writing.
Hello @dvbridges, thank you very much for the above code you provided. I am also carrying out a linguistics experiment and it helped me a lot. I only have one problem, when I execute this experiment I cannot see the “typed answers” in my data file, neither in excel nor in csv. I am showing 24 pictures to the participants and asking them to write 24 answers, however when I try it and type the answers, the answers typed in are not visible in the data file (all of these I give inside the same routine). How can I get the responses from the participants recorded? Thank you so much in advance
There isn’t any need any more to use custom code to collect typed responses. Instead, use the new TextBox component, and simply set it to be editable. Check that it saves the data for you automatically.