Overwriting/editing an excel sheet

Hello,
I’m making a categorization test for animals on a touchscreen system. The categorization test contains 20 different tasks/stimulus sets, I have each task as a different excel sheet (e.g., Task1.xlsx with the stimuli images and answers, Task2.xlsx with those stimuli images and answers, etc).
The animal should move to the next excel sheet/task once they meet a criterion of 80% correct on their last 50 trials, which I have working. My issue is that I need a way for the program to remember which excel sheet/task the animal ended on, so they can restart in the same place as before. So if in one session they get to Task3, when the program is restarted they start in Task3.
With humans, I would just have an outer loop with an excel sheet that has a list of the excel sheets so it would loop through the list of tasks as the criterion is met. So I am wondering if I should use this same method, and if there’s a way to save what task the animal was in so it begins there when the program is restarted instead of starting back at task 1. Or if there’s some way to have a csv or txt file that writes and saves the current task and then when the program is restarted I can use a code component to say ‘start at the task in the csv file’?
Any help is very appreciated!
Thanks,
Brooke

Edit
I added this code to the “Before experiment” tab just to see if I could have psychopy read the task number and then use the corresponding excel sheet. And I put $Tasks in my loops conditions. However it is not working. When I try to run the experiment it just says its loading and then never loads.

“”"
task_check = open(‘parameters.txt’,‘r’)
if task_check.mode == ‘r’:
contents = task_check.read()
search_task1 = input(‘1’)
search_task2 = input(‘2’)
if search_task in contents:
Tasks = ‘Task1.xlsx’
if search_task2 in contents:
Tasks = ‘Task2.xlsx’
“”"

If your image is set according to different conditions, please add the image path according to different conditions, as follows:
If condition == 1:
imagePath = [“Image/1.png”,“Image/2.png”,]
If condition == 2:
imagePath = [“Image/3.png”,“Image/4.png”,]

I’m not sure that’s what I’m looking for.
I will try to be more clear:
I have 20 excel sheets (Task1.xlsx, Task2.xlsx, Task3.xlsx, etc to Task20.xlsx). The excel sheets contain the stimuli for each task, the correct answers, and other information I need for the data files. The experiment needs to play each excel sheet in order 1-20. It will start with Task1.xlsx, showing the stimuli in that excel sheet until the participant reaches a criterion of 80% correct, and then it will move to Task2.xlsx showing the stimuli from that sheet until criterion is met, etc.
Because my participants are animals and the program has to be quit out of each day, I need a way to restart at the beginning of the Task#.xlsx that the animal was on before closing out. So if they made it to Task5.xlsx in their last session, I need it to restart at Task5.xlsx in the next session automatically.
There may but a much easier way to do this, and if there is I’m happy to try that.
But what I have been testing out myself (with little knowledge of psychopy or javascript) is to create a parameters.txt file that writes the Task # (1-20) and then updates the parameters.txt when a Task is completed (so Task 1 is completed the parameters.txt is updated to 2). Then have code in the Before Experiment tab that checks the parameters.txt and depending on the number in the parameters, opens the corresponding .xlsx file. However, I am not even sure if the way I am trying to do this is feasible. I have found python code online on how to read a .txt but I get error codes saying that “r” is not defined. Or when I try to run the experiment the screen goes black and I have to force quit out.
I have attached my experiment, my code to read the task number is in my first routine in the parameters_check custom code. I hope this more clear. Thank you so much.
testing.zip (221.4 KB)

Hi Brooke, seems to be quite the PsychoPy time for you, hope you are having fun :smiley:

Replacing your “parameter check” code with

with open('parameters.txt') as f:
    contents = f.readlines()

if '1' in contents:
    Tasks = 'Task1.xlsx'
if '2' in contents:
    Tasks = 'Task2.xlsx'

makes it work for me (at least the reading part).

Yes! I have my dissertation, as well as 6 other projects I’m trying to program! Luckily (and thanks to you), I have been learning a lot!

So I have ended up with the code below in my Begin Experiment tab of my first routine and it is working!:

filename = 'parameters.txt'
search1 = '0'
search2 = '1'
search3 = '2'
search4 = '3'
search5 = '4'
search6 = '5'
search7 = '6'
search8 = '7'
search9 = '8'
search10 = '9'
with open(filename) as f:
    if search1 in f.read():
        row_num = '0'
with open(filename) as f:
    if search2 in f.read():
        row_num = '1'

Then in my last routine, I have this code in the End Routine tab and it is working as well:

if(avg_acc >=0.8 and total_trials >= 10):
    if Tasks == 'Task1.xlsx':
        with open(filename, 'w') as file:
            file.write('1')
    if Tasks == 'Task2.xlsx':
        with open (filename, 'w') as file:
            file.write('2')
    if Tasks == 'Task3.xlsx':
        with open (filename, 'w') as file:
            file.write('3')
    if Tasks == 'Task4.xlsx':
        with open (filename, 'w') as file:
            file.write('4')
    if Tasks == 'Task5.xlsx':
        with open (filename, 'w') as file:
            file.write('5') 
    if Tasks == 'Task6.xlsx':
        with open (filename, 'w') as file:
            file.write('6')
    if Tasks == 'Task7.xlsx':
        with open (filename, 'w') as file:
            file.write('7')
    if Tasks == 'Task8.xlsx':
        with open (filename, 'w') as file:
            file.write('8')
    if Tasks == 'Task9.xlsx':
        with open (filename, 'w') as file:
            file.write('9')

The only thing I haven’t figure out on my own is how to have the program update the $Tasks variable in my loop after the parameters changes. So once I meet criterion (80% on 10 trials) on task 1, the parameters updates to ‘2’, but continue in Task1.xlsx instead of updating to Task2.xlsx. I had tried moving my first code to the Begin Routine tab that way it would consider the parameters.txt every time it begins, but that didn’t seem to work.

If you have the conditions parameter of the outer loop set to be $Tasks, then on each iteration it should read in the new Excel file and start using it. So I think all you need to do for the last part is have something like

taskNum += 1
Tasks = f"Task{taskNum}.xlsx"

(where taskNum is the number of the current tasks file)

Hello, thanks for your response! I changed my End Routine to the code below, but I’m getting an error message:
File “C:\Users\17703\Desktop\TouchCat4\HoverCat4_lastrun.py”, line 675, in
taskNum += 1
TypeError: ‘int’ object is not iterable

e = open(filename, 'r')
taskNum = e.readlines()
e.close()
if(avg_acc >=0.8 and total_trials >= 10):
    if Tasks == 'Task1.xlsx':
        with open(filename, 'w') as file:
            file.write('2')
    if Tasks == 'Task2.xlsx':
        with open (filename, 'w') as file:
            file.write('3')
    if Tasks == 'Task3.xlsx':
        with open (filename, 'w') as file:
            file.write('4')
    if Tasks == 'Task4.xlsx':
        with open (filename, 'w') as file:
            file.write('5')
    if Tasks == 'Task5.xlsx':
        with open (filename, 'w') as file:
            file.write('6') 
    if Tasks == 'Task6.xlsx':
        with open (filename, 'w') as file:
            file.write('7')
    if Tasks == 'Task7.xlsx':
        with open (filename, 'w') as file:
            file.write('8')
    if Tasks == 'Task8.xlsx':
        with open (filename, 'w') as file:
            file.write('9')
            Tasks = 'Task9.xlsx'
    if Tasks == 'Task9.xlsx':
        with open (filename, 'w') as file:
            file.write('10')
    taskNum += 1
    Tasks = f"Task{taskNum}.xlsx"

File “C:\Users\17703\Desktop\TouchCat4\HoverCat4_lastrun.py”, line 675, in
taskNum += 1
TypeError: ‘int’ object is not iterable

Thank you! Yes it is working to read in the number when I first startup the program. But then when the parameters changes, the Task variable doesn’t update so it continues playing the same task. Also, every time I meet the criterion, it will change. So if I start with 1 in the parameters.txt, it will start with Task1.xlsx as expected, then when I meet the criterion at the end, it’ll update parameters to ‘2’, but continue showing me Task1.xlsx. If I continue playing and meet criterion again, it’ll update the parameters to ‘3’, and so on. But never actually changing the .xlsx file. When I restart the program, it will start with Task3.xlsx. But it has skipped over 2. I’ve also tried putting the same code in the Begin Routine tab so it checks the parameters not just at the beginning of the experiment but also at the beginning of every trial, and this hasn’t helped.

Another thing I have been trying, it to have an excel with the list of Task#.xlsx sheets in the Tasks column. Then have an inner loop with the $Tasks variable, and have a variable in the Selected rows box. And once criterion is met, it changes the number and therefore changes the Row that the excel sheet is looking at? But I’m having the exact same issue here. The parameters will update but the currently running task doesn’t change.

Do I understand you correctly that you basically want to change the conditions file of your loop while the loop is already running? If that’s the case, I think you are better off having two loops, one inner which repeats the trials and one outer that goes through the tasks (just like in your other experiment, if I remember correctly).

When you read the parameter where the experiment was left the last time, you have to feed this information to the “selected rows” of the outer loop. E.g., if you left at Task2 and there are 9 in total you want your outer loop to only go through Tasks 2 to 9, which are rows 1 to 8 (1:8).

From what you write you are quite close to this. Maybe what is missing is the breaking of the inner loop to go to the next task, when the criterion is met? The specification of selected rows only has to be done once before the outer loop is entered for the first time (i.e., when the experiment starts). So that is not the way to change the task mid-experiment but to specify which rows to go through for the whole experiment.

1 Like

You’re a genius. That worked great. I’m glad I was starting to get on the right track changing to he selected rows variable instead of the task# variable!
For the thousandth time, thanks for your help!