psychopy.org | Reference | Downloads | Github

How to read data from generated excel during the task

Hi, what I am trying to do is:
First. collecting response from key press,

if choice.keys == 'a':
    own_delay_time = float(left_delay[0:-1])
elif choice.keys == 'l':
    own_delay_time = float(right_delay[0:-1])

and store in the data in the generated excel file:

        timebudget_block1.addData('time_spent', own_delay_time)

Second. In the generated excel, I found there is a column name "time_spent"
Third. then I want to add the “time_spent” after every trail, and check whether the sum of total “time_spent” is over 20, if so, then finish the whole trail.
My problem is how can I read data from the excel, and do the calculation? Thanks a lot!

1 Like

Hi, you don’t beed to access the Excel file; the data you need is stored inside the TrialHandler object, which in your case is called timebudget_block1. This should do the trick:

if timebudget_block1.data['time_spent'].sum() > 20:
    continueRoutine = False
1 Like

Hi Richard,
thanks a lot for replying! I am trying to write an array to store the data temporally, but your is much better,
I tried, however an error came out

TypeError: ‘TrialHandler’ object has no attribute ‘getitem

don’t really understand what happens…

I am sorry, there was a mistake in my code. I edited the above posting the fix it. It’s supposed to be timebudget_block1.data['time_spent'].sum() instead of timebudget_block1['time_spent'].sum().

1 Like

hi Richard,
Thanks for correction!
Good news is no error this time!
Bad news is seems if sentence does not work…

I put like this

if choice.keys != None:  # we had a response
    timebudget_block1.addData('choice.rt', choice.rt)
    timebudget_block1.addData('time_spent', own_delay_time)
    if timebudget_block1.data['time_spent'].sum() > 3:
        continueRoutine = False

or like this

if choice.keys != None:  # we had a response
    timebudget_block1.addData('choice.rt', choice.rt)
    timebudget_block1.addData('time_spent', own_delay_time)
if timebudget_block1.data['time_spent'].sum() > 3:
    continueRoutine = False

and expect the routine will end after two or three choices when the time spent should longer than 3,
however… :sweat:

However…? What happens instead?

the routine did not stop, continued to next trail… :cry:

Is this a Builder experiment or did you program this in the Coder?

I put this in the coder

Ok, could you please post the relevant code that does the trial handling? :slight_smile:

1 Like
# set up handler to look after randomisation of conditions etc
timebudget_block1 = data.TrialHandler(nReps=1, method='random', 
    extraInfo=expInfo, originPath=-1,
    trialList=data.importConditions(u'timebuget_block1.xlsx'),
    seed=None, name='timebudget_block1')

i actually first built the program in the builder, and then further modify in the coder…
here is the code set up handler :slight_smile:
Thanks a lot for offering help!!

Ok we’re getting closer, but I actually need another part of your code. I meant the part where you do something like for trial in timebudget_block1 or similar :slight_smile:

1 Like

btw if you enclose your code blocks in three backticks, it will be formatted correctly automatically. That is:

```
if a == b:
    print "Hello"
```

will produce

if a == b:
    print "Hello"
1 Like
# set up handler to look after randomisation of conditions etc
timebudget_block1 = data.TrialHandler(nReps=1, method='random', 
    extraInfo=expInfo, originPath=-1,
    trialList=data.importConditions(u'timebuget_block1.xlsx'),
    seed=None, name='timebudget_block1')
thisExp.addLoop(timebudget_block1)  # add the loop to the experiment
thisTimebudget_block1 = timebudget_block1.trialList[0]  # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisTimebudget_block1.rgb)
if thisTimebudget_block1 != None:
    for paramName in thisTimebudget_block1.keys():
        exec(paramName + '= thisTimebudget_block1.' + paramName)

for thisTimebudget_block1 in timebudget_block1:
    currentLoop = timebudget_block1
    # abbreviate parameter names if possible (e.g. rgb = thisTimebudget_block1.rgb)
    if thisTimebudget_block1 != None:
        for paramName in thisTimebudget_block1.keys():
            exec(paramName + '= thisTimebudget_block1.' + paramName)
    
    # ------Prepare to start Routine "trial"-------
    t = 0
    trialClock.reset()  # clock
    frameN = -1
    continueRoutine = True

wow! i did not know that… looks nicer~~~
i hope this time I provided something you need…:grin:

Ok, so continueRoutine was actually not the correct place to address your issue.

What you can do is, at the very end of that loop (i.e., when the trial is finished, data have been collected etc.), put the if statement we introduced earlier, but change it to simply exit the loop:

if timebudget_block1.data['time_spent'].sum() > 3:
    break

I think this should do what you want!

1 Like

it worked!
may I ask why? is it because I added and defined “currentLoop”?

1 Like

Awesome!

No, in fact, I don’t know what purpose currentLoop is supposed to serve. It works now because we simply quit the loop (i.e., iteration over trials in timebudget_block1) as soon as timebudget_block1.data['time_spent'].sum() > 3: The break statement breaks out of for and while loops.

1 Like

Just to clarify: the only change/addition you need to apply to the code you posted originally is adding the if statement mentioned here. You don’t need to change anything else.

1 Like