psychopy.org | Reference | Downloads | Github

"Take a break" works locally but not online

Thanks for your response. Replacing “if not in” with “if…” is in principle fine, but did not work in practice. After revising the code, it continues to run locally in PsychoPy, but not online. The “take a break” still happens after every trial online, suggesting the code was ignored in Javascript. I don’t know how to change the visibility of my project public (it’s in pilot mode). Here’s the Python to JS translation:

Just taking a stab at it but have you tried running it with the loop name as “trials” instead of “trialsLoop”. After some trial-and-error yesterday, I noticed that my code was working when I used “trials” but not when using the name of my loop

Thanks for your response. The names “trials” vs. “trialsLoop” are arbitrary; I happened to define the loop around my trials as “trialsLoop”. If I change it to “trials” and also update the codes, it does not affect the function of the script. It continues to run properly on local PsychoPy, but the “take a break” part of the code is not skipped according to the script, when run online.

Thanks Jonathan. When run online, the console shows the message “no break here” after every single trial.

That indicates that the condition is always being met. Looking at the last js code you posted, first of all it does need to be trials.thisTrialN, specifically (javascript has trouble referencing the current loop by name for reasons that are unclear, but the developers are working on it). Beyond that I’m not sure why it would be true on every trial.

Let’s try two things:

  1. Please post the javascript you are currently using that is generating this behavior.
  2. Let’s try adding a more informative log statement. Replace the console.log line with the following:
console.log(trials.thisTrialN);

This will tell us exactly what the trial number is, or what it thinks it is, which will help us determine why the condition is not being met.

Here is the javascript (sorry for not including it previously; I only just figured out how to make it public).

The console log accurately incremented trials.thisTrialN - 0, 1, 2, and so on. The problem seems to be that the commands are ignored by continueRoutine.

Pavlovia is down right now so I’ll have to look at it later, but continueRoutine failing is weird. Is this an embedded loop within a loop situation?

The experiment structure is attached here as a figure. There is a loop (trials) that includes three components: SearchTrial (the task of the trial), feedback (correct or incorrect for that trial), and TakeABreak (this routine should be skipped on most trials. This one contains the continueRoutine = False). PsychoPy correctly interpreted the commands, but Javascript did not.

By the way, some problems I encountered in PsychoPy to JS seem intractable. Perhaps there’s a PsychoPy development issue here. From Builder to JS works well if there aren’t any customized codes inserted into Builder. When codes are inserted, the converted JS just doesn’t seem to handle the codes well - it can’t find variables, functions, etc.

Perhaps this is a major area of further development for PsychoPy.

Oh believe me the developers know all about it, and to be honest they’ve already done an incredible job. Automatically translating code from Python to JS at all is a tremendous achievement given how different the two languages are. Everything else in the builder is just a representation that can be compiled into any language that they’ve programmed those objects into, so it’s not trying to directly translate python into javascript, but code elements are pure python code, so translating them procedurally without making you write out python code and javascript code separately and manually? Sure, doing it better would be nice, but from the perspective of someone who has manually coded whole experiments from scratch in both languages, doing it at all is very impressive.

Also I think I know how to fix it. Try moving the code to “every frame” instead of “begin routine”. I’ve seen other people say that skipping trials only works if the skip code is in the “every frame” tab.

2 Likes

Putting the code to every frame works like a charm! Thank you so much for your help. I do appreciate the auto Python to JS functionality, as well as PsychoPy overall. The learning curve is much smoother compared with MATLAB/Psychtoolbox. The community support, like this one, is incredible. Thank you.

Hi Jonathan, I think i’m having a trial-skipping issue that’s related to some of this discussion but I can’t quite get my loop to operate correctly and you seem to have some experience here.

The loop is not behaving as it is supposed to online (works fine locally).

I used your every frame suggestion for some of my code and it made it run better, but still not quite as desired.

I’ll try and explain:

To loop is supposed to work like this:
(1) object is correct if within 150 pixels (i.e., inside the polygon i’ve included for easy testing)
(2) if an object is answered correctly twice in a row , (i.e., on two consecutive occasions that item, e.g., cow is attempted) it drops from the loop (i.e., its value goes from 0>1>2; if it is answered incorrectly, its value in the dict drops to 0 - the values for the other objects should stay the same here and they should still be skipped if their value reaches 2)
(3) loop terminates when all objects placed in correct location twice in a row (i.e., all objects values are 2 in dict).

The java script is behaving in the following undesirable way:
(1) if all trials are answered correctly it terminates exactly when it is supposed to
(2) if an object is answered incorrectly the dict for that object seems to reset to 0 as it is supposed to
(3) it will then finish all the objects in the that round of the loop
(4) it will then demand two new full loops in which I answer the original incorrect trial correctly (i.e., it is not skipping)
(5) then it will start a final round of the loop and terminate only once it reaches the object I originally answered incorrectly (even though that object reached its desired value of 2 a number of trials ago)

note* currently I have all values of objects in dict set to 1 for quicker testing.
note* works fine in psychopy builder

do you know whats going wrong? All of that seems complicated but I think its just something to do with skipThisTrial :thinking:

Any help you have will be very much appreciated!

Cheers,
Tom

That’s an interesting and complex failure. I don’t have a definite answer for you, I’m afraid, but my guess is that it might have to do with the dictionary, or the way it is updated between loops. That said, I have to say that at a glance I don’t see an obvious problem with any of the code around obs_dict. It looks like it should do exactly what you intend it to.

I recommend, for debugging purposes, adding some console.log calls whenever obs_dict is updated, so you can double-check that it’s being updated correctly. That may help you isolate the issue.

okay to update - i’ve tried a million examples of changing components to each frame/end routine etc and had no luck.

where do i put these console.log commands? online in the javascript code?

cheers,
Tom

I am having this same issue where my break works perfectly in psychopy, but does not in Pavlovia. There is no error message, it simply skips the break. Basically, I want a 30 second break after half of the trials have been completed (304). Attached is the code I currently have that works in psychopy.

It worked for me online when I change the loop name to “trial”. In your case, do not use “Flankers_Test” as the loop name. Use “trial” instead. So the if command will be “if trial.thisN !=303:”

If you need to use Flankers_Test as the loop name, then you will need a separate variable that counts the number of trials. E.g., a TrialCounter that is initially 0, and then increases value by 1 after each trial. After that, you can do “if TrialCounter = 303:” or something like that.

I tried changing it to trial, and PsychoPy quits the experiment. I am fairly new to PsychoPy, how would a trial counter look?

i got the same error as you and when i changed the name of the loop to “trials” it is finally working…
maybe the problem is that you changed it to “trial” but it should be “trials” (I tried it whit “trial” but it was not working online - it looks like it should be named really “trials” with S at the end)

trials.thisN works online in 2020.1 but for 2021.1 you have to change the loop name to snapshot on the JS side only, i.e. snapshot.thisN

3 Likes

Wonderful!!
You killed the game :star_struck:

I just lost the game…

trials.getTrialIndex() should also work online