Split location co-ordinates into two numerical conditions, trying to make this consistent with pre-existing code-component

OS (e.g. Win10): win10
PsychoPy version (e.g. 1.84.x): 20.20.1
Standard Standalone? (y/n) If not then what?:y
What are you trying to achieve?:

I had an objects locations task up and running in psychopy locally but realised that I would need to split the screen co-ordinates for the objects into two condition in my conditions file so that it would work in java script.

This is fine and i’ve tested it online.
I originally was just referring to objects as “loc”, I then created xloc and yloc and put $[xloc,yloc] into the builder which was great, so far so good.

The problem is that I have a code component which was referring to “loc” and I don’t know how to correct this to be consistent with the changes I described above. Here is the code component:

Begin Experiment:
obs_dict = {}

Begin Routine:

    for image in trials.trialList:
        image = image['object']
        obs_dict[image] = 0
        

correct = False

loc = trials.thisTrial['loc']
image = trials.thisTrial['object']
if obs_dict[image] == 2:
    if 0 in obs_dict.values() or 1 in obs_dict.values():
        continue
    else:
        trials.finished = True
        continue

End Routine:

    if mouse.y[0] in range(loc[1]-150, loc[1]+150):
        correct = True


if correct == True:
    obs_dict[image] +=1
elif correct == False and obs_dict[image] == 1:
    obs_dict[image] = 0

I don’t imagine there’s a lot of tweaking to be done here but i’ve tried several different things and can’t figure it out.

Hope someone can point me in the right direction.

Cheers,
Tom

Hi Tom, just going to throw out a suggestion and hope it helps.
It seems like for this code, you are just defining loc (at the beginning of the routine) in order to use it to compare the mouse position to it at the end of the routine (the line
if mouse.y[0] in range(loc[1]-150, loc[1]+150): correct = True )
If this is all that loc is doing in this code, then I think you could just replace loc with yloc in the beginning of the routine, and how it is defined to make sure it gets the variable yloc from your conditions file.
Then in the end of the routine code you are now no longer indexing loc, you are just using yloc which is already a scaler. So you should be able to just do
if mouse.y[0] in range(yloc-150, yloc+150): correct = True

Let me know if that helps!

Hi Bobby,

Thanks a lot for getting back to me -

I tried a couple of variations based around what you said and didn’t get any luck.

Maybe this will help - ‘loc’ doesn’t exist anymore because that’s what I was using in the builder to specify location - now I have $[xloc,yloc]

  • i see what you are saying here i think - but what would I have for the x co-ord?

i’ve tried:

begin routine:

xloc = trials.thisTrial['xloc']
yloc = trials.thisTrial['yloc']

End routine:

if mouse.x[0] in range(xloc[0]-150, xloc[0]+150):
    if mouse.y[0] in range(yloc[1]-150,yloc[1]+150):
        correct = True

and I also tried:

loc = trials.thisTrial['[xloc,yloc]']

and this didn’t do it either.

Unsure where to from here.

Cheers,
Tom

Hi Tom, I think your method of defining xloc and yloc is totally fine, but a way to test this is just to insert some easy code/component in that might print out the values of xloc and yloc on each trial to confirm they are defined correctly.
I think the issue comes from doing xloc[0] and yloc[1]. You had to use the 0 and 1 to index loc originally, because loc used to be a vector or a series of numbers, so you needed to pick out the first and second component of this (this is what the 0 and 1 are doing).
But now that you have xloc and yloc already defined as single numbers, you shouldn’t need to “pick out” or index any values from them, just use those variable names exactly as they are.
So assuming xloc and yloc are being defined correctly (and I think they are using the

xloc = trials.thisTrial['xloc'] 
yloc = trials.thisTrial['yloc']

approach,
then I think the only thing you should need to change is :

if mouse.x[0] in range(xloc[0]-150, xloc[0]+150):
    if mouse.y[0] in range(yloc[1]-150,yloc[1]+150):
        correct = True

Notice I only removed the indexing 0 and 1 from xloc and yloc, not from the mouse.x or mouse.y.

very interesting, it seemed work better but popped up another error at exactly the end of the first loop:

Alert 4205:Python Syntax Error in ‘Begin Routine’ tab. See ‘None’ on line number 14 of the ‘Begin Routine’ tab.

begin experiment:
obs_dict = {}

begin routine:

if obs_dict == {}:
    for image in trials.trialList:
        image = image['object']
        obs_dict[image] = 0
        

correct = False

xloc = trials.thisTrial['xloc']
yloc = trials.thisTrial['yloc']
image = trials.thisTrial['object']
if obs_dict[image] == 2:
    if 0 in obs_dict.values() or 1 in obs_dict.values():
        continue
    else:
        trials.finished = True
        continue

end routine:

if mouse.x[0] in range(xloc-150, xloc+150):
    if mouse.y[0] in range(yloc-150, yloc+150):
        correct = True

if correct == True:
    obs_dict[image] +=1
elif correct == False and obs_dict[image] == 1:
    obs_dict[image] = 0

any idea why?

Cheers,
Tom

Just judging by the line it is pointint you to it must have something to do with the keyword continue. I’ve personally never used that keyword in my code so I’m not positive what might be going wrong here.
Intuitively I know that continue tries to essentially reset the current loop iteration in python (so in a for loop it increments by 1 and then starts the loop over, skipping any remaining code).
Since in your else statement you set the loop to finished, I am wondering if Python is throwing an error since you are trying to continue a finished loop?
Long story short my first attempt at debugging would be to delete the continue in the else statement and see if that works.

okay i thinks it because I had the loop set to 1 instead of 100 so i could test something!

i’ll confirm in a second… :joy:

cheers,
Tom

nope it crashes now unfortunately.

I was in the process of changing the code to make it translate to java and jon sent this suggestion:

begin exp:
obs_dict = {}

begin routine:

if obs_dict == {}:
    for image in trials.trialList:
        image = image['object']
        obs_dict[image] = 0
        

correct = False

xloc = trials.thisTrial['xloc']
yloc = trials.thisTrial['yloc']
image = trials.thisTrial['object']
if obs_dict[image] == 2:
    skipThisTrial = True  # variable to use in feedback etc
    continueRoutine = False  # end this routine
    if 0 not in obs_dict.values() and 1 not in obs_dict.values():
        # end the whole trials loop
        trials.finished = True
else:
    skipThisTrial = False

end routine:

if mouse.x[0] in range(xloc-150, xloc+150):
    if mouse.y[0] in range(yloc-150, yloc+150):
        correct = True


if correct == True:
    obs_dict[image] +=1
elif correct == False and obs_dict[image] == 1:
    obs_dict[image] = 0
    

and then this for feedback in each frame of my feedback routine:

if skipThisTrial:
    continueRoutine = False

but this isn’t quite working either so i’m getting quite fed up haha!

Cheers,
Tom