Exit a loop on pavlovia

@Kath_K, here is another version, I have tried to simplify the structure of the Builder task, by removing some loops. For example, rather than having a loop with nReps = 6 to control 6 presentations of the inner loop, I have created an array of 6 row indices, which are fed into the trial loops, and this controls the number of trials. In this version, there should be randomisation without replacement, because the arrays which control the trial randomisation are created at the beginning of the experiment. Again, there seems to be a difference in how selecting rows works between online and offline studies. E.g., [1] will select row 1 from the conditions file locally, but online it will select that row, but parse it incorrectly, so for online tasks, you need to use [1, 1] to get a single row (where 1 can be a variable) - this should be reported as a bug. By the way, I have shortened the task by removing the startup instructions and practice runs, since they were working correctly, and it makes it easier to debug.

https://run.pavlovia.org/dvbridges/test_kuhne/html/

Here is the Builder file, I have commented the code to help explain what each piece does. Also, I had to correct the keyboard component using corrAns as a correct answer, since your conditions files use CorrAns and the variables are case senstive

cotidie_de1_NEW_debugged.psyexp (125.1 KB)

Oh wow incredible! It almost works like a charm but at some point after trial 10 or so I get

Unfortunately we encountered the following error:

  • when importing condition: story_gerpriv.xlsx
  • RangeError: Invalid array length

We are almost there…Thank you for your patience

Ah ok, I did not do the whole task, so always good to check. Its an error described above where we are popping from empty lists. In the outermost loop, you have 10 repetitions of the loop containing your chooseBlocks file, which has 2 files in it, so 10 * 2 iterations of the outer block. There are 10 stories per and 60 sentences per block, so in total you have 20 stories and 120 sentences. Currently, its set up so that only 10 stories are presented, and 60 sentences, because that is how we created the arrays in the code component, and once those arrays that control the randomisation run out, which will be after the 10 iterations of the outer block, we get the error.

The issue is, that if you recreate the arrays after they have emptied, you end up having randomisation with replacement. The solution is to create two arrays, one for each condition (pub & priv), then switch between the arrays depending on which condition the outer block has been selected. For this, you have to add an extra column to your chooseBlocks sheet (see attached) which contains a value for the condition e.,g pub = 1. This value is used in a code component to decide which random array to select the trial numbers. I have not run through the whole task, only checked that it runs ok. Bte, I also noticed some of the sum answers in the catch trials are not always correct, not sure if that is intentional.

link
https://run.pavlovia.org/dvbridges/test_kuhne/html/

files
cotidie_de1_NEW_debugged.psyexp (126.0 KB)
chooseBlocks_ger.xlsx (7.1 KB)

You have just officially saved my life! :slight_smile:
I am so very thankful! Even if I had tried another 5 years I wouldnt have come up with this solution, because it is not obvious. Your link and mine on pavlovia seem to run with no error.

The only minor thing I (but it’s not a drama!) it doesnt record the story as such (the sentences are recorded all right) in results. Just wonder why it can be.

Thank you ever so much!!!

Ok, well you could save it manually using code at the beginning or end of the story routine using

psychoJS.experiment.addData("storyText", story)

Although, it should save the text automatically, since you are using the text component.

It returns an error Story not defined. But I can live with it

Cool, well if you decide you need it, add the following the the End Routine tab of the story_2 routine code component (JS code)

psychoJS.experiment.nextEntry()
1 Like

oh wow you work miracles! Fantastic, it works now! I will keep my fingers crossed. :hugs:

I would like to thank you and everyone else here for being so nice and helping me so much! You are terrific guys

@dvbridges
@jonathan.kominsky

And I have also learned here more then anywhere in my life about coding :slight_smile:

2 Likes

Hi! Sorry, for posting a new question in this one, but I guess it’s easier than to explain the whole design again. Is it possible to show a routine (text) in every 5th trial? Many thanks

Apologies for more questions directly to you, but maybe it is easier because you know the whole story :slight_smile: @dvbridges I am very sorry if it is not appropriate to tag you like this

This time problem is probably less complicated :slight_smile:
I wanted to add another routine question which I want to repeat only in 20% that is after every 4th story. So, there are 5 questions

in the code_shuf_story I added

make question array

questArray = list(range(5))
shuffle(questArray)

In the same code routine an extra counting code:


Then, in the Question code (Begin routine)

Get 1 question

questRow =
questRow.append(questArray.pop())

and another piece of code

The Question loop goes like this:

image

First 2 questions are correctly placed after 4th and 8th story, but then I get an error

image

I tried the range this way or another, but no better. Please help me, where did I make a mistake?

Thank you ever so much in advance and I am very sorry for bothering.

How exactly are you declaring questArray in JavaScript? This looks like the Python declaration.

In any case, the problem seems to be that it’s emptying out questArray faster than you expected. To narrow down what’s happening, you can change your questRow code as follows (in Python):

questRow = []
print(questArray)
questRow.append(questArray.pop())

This will auto-convert to a console.log statement in JS, but basically it’s just going to put the current contents of questArray in the run window (on Python) or the browser JS console (online, you can get to the console by going to view -> developer), and help you see why it’s running out of contents too soon.

Thank you ever so much. I will try this out.
In fact, I have not run it on JS yet, only offline.

You were absolutely right: it appended the list every story, not only in 20%
So I changed the code adding a condition

On Python:

questRow = []
if n > 0 and n % 4 == 0:
questRow.append(questArray.pop())

In JS:

questRow = [];

if (((n > 0) && ((n % 4) === 0))) {
val = questArray.pop();
questRow.push(val);
questRow.push(val);
}

I runs fine offline (juhu!) but I apparently made a mistake in JS translation. I get an error on pavlovia:

  • when importing condition: questions.xlsx
  • RangeError: Invalid array length

I would be very thankful if you could give me a hand this time again :slight_smile: Thousand thanks!

That’s curious. That might not be an issue with that particular bit JS at all, because it’s saying it’s encountering the error when importing the condition file. Did you change anything about the condition file? If you open the JS console does it tell you which line the error is originating from?

Thank you for your reply. I get this error in console:

image

I think it is of a similar nature as explained above:

Ah ok, I did not do the whole task, so always good to check. Its an error described above where we are popping from empty lists. In the outermost loop, you have 10 repetitions of the loop containing your chooseBlocks file, which has 2 files in it, so 10 * 2 iterations of the outer block. There are 10 stories per and 60 sentences per block, so in total you have 20 stories and 120 sentences. Currently, its set up so that only 10 stories are presented, and 60 sentences, because that is how we created the arrays in the code component, and once those arrays that control the randomisation run out, which will be after the 10 iterations of the outer block, we get the error.

So the code shold state that we only need a list of 5, because only every 4th n

Can you link your current repository for this? The error coming from TrialHandler like that makes it sound like there’s something weird with the condition file or something that interacts with it, which your code never does directly.

Just for kicks, another thing you could try is saving your conditions file as a .csv file instead and see if that is better-behaved. It probably won’t be, but just isolating and ruling out potential issues at this point.

Thanks a lot. When I use cvs it has always returned a UTF-8 errror with German characters (ü etc) this is why I am using this format. I have tried now and yes, this UTF error is there (from the very beginning when uploading to PsychoPy)

I think I found it. It may be as simple as the fact that you call questRow.push twice rather than once in your JS. That is, your questRow array is twice as long in JS as in Python.

Unfortunately even if I change it to

questRow = ;
if ((n > 0) && ((n % 4) === 0)) {
val = questArray.pop();
questRow.push(val);
}

it still shows the same error

OK, I had a closer look. I think that what’s happening has to do with where certain code is executed in Python vs. JS. In JS, it looks like this is in “begin routine”, but in order to affect that loop, it would need to be in “begin experiment”. This is because the setup for the loop itself, and that trialHandler call, happens during the experiment startup. It may be that you can put a “dummy” definition of questRow in begin experiment and still have it defined on every loop, but it needs to be defined at least once in a “begin experiment” code section.