PsychoPy: Logging User Input Strings - psychopy

I have a PsychoPy routine that is intended to act as a memory object-span test. In one loop, the software presents an object (a single text character) followed by a user task multiple times. The software remembers the string of characters, and later asks the user to enter the characters as they were presented. This sequence (loop of tasks followed by character recall) is itself presented several times in a larger loop.
The characters are chosen randomly.
I would like to record, either in the CSV file which PsychoPy generates, or a log file of some sort, the characters that the user is entering. How does one do that in the PsychoPy graphical interface system?
The code block used to record the character sequences is:
Begin Routine
givenAnswer = ""
returnPressed = False
R_memPrompt.setText("Please enter characters in the order they were presented, then hit 'Return':")
R_memPrompt.draw()
win.flip()
Each Frame
loopTest = True
userInput = ""
if returnPressed == False:
while loopTest == True:
response = event.waitKeys(keyList=['a','b','c','d','e','f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'return', 'backspace', 'left'])
if response[0] == 'return':
loopTest = False
returnPressed = True
continueRoutine = False
elif response[0] == 'backspace':
userInput = userInput[:-1]
userInput = userInput.upper()
R_disp.setText(userInput)
R_disp.draw()
win.flip()
else:
userInput = userInput + response[0]
userInput = userInput.upper()
R_disp.setText(userInput)
R_disp.draw()
win.flip()
End Routine
givenAnswer = givenAnswer + userInput
A later routine has, as its Begin Routine
if memorySequence == givenAnswer: # memorySequence is the prior record of memory characters
# do some stuff
else:
# do some other stuff
Crude (it is a prototype) but the intent of the Each Frame section is simply to reflect characters as they are written to the screen, through the R_disp text stimulus, while allowing the user to backspace and not worry about case sensitivity. The final answer ends up in givenAnswer,
and is later compared to memorySequence which was built up previously.
I would like to dump the contents of those variables, memorySequence and givenAnswer to the CSV file or some log file so that I do not lose the information.
Is there a way to do this?

Certainly. In the "End Routine" tab of your code component, put something like this:
thisExp.addData("sequence", memorySequence)
thisExp.addData("answer", givenAnswer)
This will add two new columns to your data file, with column headers of whatever literal values you put in the quotes.

Related

Extracting data from google worksheet and selenium to write to webpage

from __future__ import print_function
from googleapiclient.discovery import build
from google.oauth2 import service_account
from selenium import webdriver
import time
sheet = service.spreadsheets()
result = sheet.values().get(spreadsheetId=SPREADSHEET_ID, range="TAX!A1:E5").execute()
data = result.get('values')
list = []
for i in user_input:
if i == 1:
list.append(data[0])
elif i == 2:
list.append(data[1])
elif i == 3:
list.append(data[2])
elif i == 4:
list.append(data[3])
elif i == 5:
list.append(data[4])
else:
print('ERROR')
print(list)
print(('The length of list is: ' + str(len(list)))
print(range(len(list)))
driver = webdriver.Safari()
try:
driver.get('some_website')
for i in range(len(list)):
search_box = driver.find_element_by_xpath('some_search_box')
search_box.click()
search_box.send_keys(list[i])
cart_button = driver.find_element_by_xpath('some_button')
cart_button.click()
#print any exceptions such as element not found error, then close browser
except Exception as e:
print(e)
print('driver closing on error')
driver.close()
This is what I get:
[['1', '2', '3', '4', '5'], ['2', '3', '5', '6'], ['6', '4', '2', '3', '4']]
The length of list is : 3
range(0, 3)
The user input one or more options, and depending on that option it extracts data from sheet that could be multiple values. This how the list forms.
It is working as it should but there is one problem. it types the whole first array in search box (['1', '2', '3', '4', '5']) but i want it to search with each element.
I want the length of list to be 14 not 3, and I don't know how to solve this.
Is it possible to append to list and get one array on the output, the length of array is depending on user input?
for i in range(len(list)):
# Add this line to loop through the second element and so forth.
for j in range(len(list[i])):
# Fix this one
search_box.send_keys(list[i][j])
Just use a for for loop to go through a 2d list.
You can also simplify the top bit
if i<=5 and i >=1:
list.append(data[i-1])
else:
print('ERROR')

Capitalize the element of list when unpacking

I'm unable to capitalize the first letter of the list.
let = ['a', 'b', 'c', 'd', 'e']
count = 5
for x in range(5):
print(*let[0:count])
count -= 1
So on this example don't know how to make 'a' printed as 'A'.
You can't make change to the print method but you can change your list to make the first element capitalized :
let[0] = let[0].upper().
If for some reason you can't modifiy the initial list make a copy let2=let and work on it.
I would probably write it this way:
let = ['a', 'b', 'c', 'd', 'e']
for i in range(5, 0, -1):
print(let[0].capitalize(), *let[1:i])

variable from text box won't assign

I am creating some code for a school project, and for a module I use later on, I need to know what the intensity to end on(end_intensity) is. When the code is run, the end_intensity still comes out as unassigned, this means that the
if client_intensity == "High":
line is never being run.Can someone please explain why it won't assign .
correct = False
end_intensity = "Unassigned"
while correct != True:
id_search = input("please enter the Client ID of the client you wish to record results for:")
# open file, with will automatically close it for you
with open("text_documents/clientIntensity.txt") as f:
user_found = False
# loop over every line
for line in f:
client,intensity = line.split(",")
if id_search == client:
correct = True
user_found = True
intensity = str (intensity)
client_intensity = intensity
#assigns which one is the end intensity
if intensity == 'High':
end_intensity = 'Moderate'
elif intensity == 'Moderate':
end_intensity = 'High'
if user_found == False:
print("I'm sorry no results we're found for that ID, please try again\n")
print(end_intensity)
The text document is in this format:
NeQua,High
ImKol,Moderate
YoTri,Moderate
(I apologize for the numbers for the text document formatting,stack overflow would only let me show it like that)
Any help would be appreciated,Thanks
Ieuan

times table generator python - syntax error

the error is on line 10. no clue why it crashes. the equals sign is highlighted red once it is run.
code as follows:
import random
question = 1
correct = 0
while question < 10:
a = random.randint(1, 12)
b = random.randint(1, 12)
answer = input(a, 'x', b, '=')
if 'answer' = 'a*b':
print ('correct!')
correct = correct+1
else:
print ('Incorrect\nthe correct answer was', a*b)
print ('You got', correct, 'out of 10 correct')
Change your if statement to this:
if answer == a*b:
Using = assigns the value where == tests equality.
The other issue is that you have too many arguments for the input function. Input takes one argument, that is a string to output to the command line to show the user. Then the input comes in as a string and you cannot directly compare string's to integers so you need to convert the string to an integer.
answer = input("Enter in the answer for {} * {}".format(a,b))
answer = int(answer)

structure of while loop

I am trying to use a while loop in Python to provide an error message while there is a backslash character in the user input. The code provides the error message when a fraction is input and requests a second input. The problem occurs when the second input differs in length from the original input and I do not know how to fix this since my knowledge of Python is limited. Any help is appreciated!
size = getInput('Size(in): ')
charcount = len(size)
for i in range(0,charcount):
if size[i] == '/':
while size[i] == '/':
getWarningReply('Please enter size as a decimal', 'OKAY')
size = getInput('Size(in): ')
elif size[i] == '.':
#Convert size input from string to list, then back to string because strings are immutable whereas lists are not
sizechars = list(size)
sizechars[i] = 'P'
size = "".join(sizechars)
That is not a good way to go about doing what you want because if the length of the new size is shorter than the original length, charcount, then you can easily go out of range.
I'm by no means a Python master, but an easily better way to do this is to wrap the entire thing in a while loop instead of nesting a while loop within the for loop:
not_decimal = True
while not_decimal:
found_slash = False
size = getInput('Size(in): ')
charcount = len(size)
for i in range(0, charcount):
if size[i] == '/':
print 'Please enter size as a decimal.'
found_slash = True
break
elif size[i] == '.':
#Convert size input from string to list, then back to string because strings are immutable whereas lists are not
sizechars = list(size)
sizechars[i] = 'P'
size = "".join(sizechars)
if not found_slash:
not_decimal = False