Randomizing without Replacement across loops

URL of experiment: Child Attention and Learning Lab / A_R_R_O_W_S · GitLab

Description of the problem:

The experiment shows a fixation cue c (color) or s (side) and then an arrow. Depending on the fixation cue, participants need to choose whether the arrow is light/dark (color) or leans right/left (side).




I have a .csv file with a list of other .csv files in the conditions in wholeBlock. Each of these .csv files represents a condition (i.e. HardColorEasySide) and contains a list of images that fit this condition (i.e. pictures where it is hard to tell what color the arrow is but easy to tell what side it leans to). wholeBlock runs through these .csv files sequentially and define_sample uses one image from the chosen .csv file as its conditions. Each define_sample loop is one trial, whole_Block runs through that loop 65 times (so 65 trials) and break_loop has a break for participants in it and runs through 3 times (for a total of 195 trials).

I need the images to be chosen randomly without replacement, so one image should not be shown twice before all of the other images (across all .csv files) are shown. This is tricky in builder since each define_sample loop is only one trial, so I used a modified code from this topic: Random Without Replacement (over multiple blocks) - #2 by hunterb1005.

Code1:

Code2:

However, I get this error when I reach this section of the experiment online:
image

Console says:
ReferenceError: blockType is not defined
at Scheduler._currentTask (Arrows_new.js:3236)
at Scheduler._runNextTasks (util-2020.1.js:1093)
at Scheduler._runNextTasks (util-2020.1.js:1096)
at Scheduler._runNextTasks (util-2020.1.js:1096)
at Scheduler._runNextTasks (util-2020.1.js:1096)
at update (util-2020.1.js:1060)

Basically I have two questions:

  1. Why am I getting this error?
  2. Will this code I’m using get me the results I would like or should I try something else?

I am super new to Psychopy and Javascript so its definitely possible that I’m missing something basic. Let me know if you need more information!

Hi Caitlin, welcome!

I couldn’t get into your experiment; could you give me permission? (or set permission to public)

And a quick question: so blockType isn’t defined. Do you have any expectations on what blockType would do in your experiment?

Best, Thomas

Hi Thomas,

My apologies! It should be public now.

I’m not entirely sure what blockType does in my experiment. I included it because it was in the code in the discourse I used as a reference when building the code.

I removed it to see what would happen, so now the code is:

currentArray =
for (let i=0; i<2; i++) {
currentArray.push(stimArray.pop())
}

However, I get this error now:

  • when importing condition: HardSideHardColor.csv
  • RangeError: Invalid array length

It will run through a few of the trials before I get that error, so I might not need the blockType segment in my code, but since I’m new to Javascript I’m unsure of if it would be necessary to randomize the trials without replacement.

Thank you,
Caitlin

Hey again,

I reproduced your error-message. I’ve got a couple of pointers for you:

  • General tip: don’t use BMP images; they are huge. If you convert them to PNG, you’ll have smaller files without loss of quality.
  • About the error message: My bet is that something goes wrong with Selected rows: $currentArray in the define_sample loop. Perhaps you are selecting more rows than HardSideHardColor.csv has rows?
  • General programming tip: you’ve got quite a lot of logic in your experiment. Changing things just to see if it might solve your issue without knowing what it does will likely cause more (and more complicated) bugs. I recommend to proceed via “stepwise refinement”. Make a separate experiment where you build up that triple loop (break_loop, wholeBlock, and define_sample) step-by-step, running it after each modification to see if it still works. It’s much easier to catch bugs that way.
  • Make copious use of “console.log”, via that statement you can log values to the browser console to inspect them. You can open the browser console via F12.

Good luck debugging!

Hi Thomas,

Thank you again for your help!

Ok, I will work on converting those!

After building up the loop on a separate file, I redid the code and simplified it a ton, following the advice from this thread: Exit a loop on pavlovia - #34 by dvbridges. It now reads

stimArray = […Array(17).keys()];
util.shuffle(stimArray)

in begin experiment and

currentArray = stimArray.pop()

in begin routine. This is because I realized that I didn’t want a loop since I just needed the trial to run once and move to the next file.

However, I am still getting the invalid array length error, but now with a different .csv file each time, even though they all have same amount of rows as the other csv files and I didn’t change any of the files.

I apologize, I’m not very familiar at all with Javascript. What would be the best way to use the console.log function in this case? Would it be console.log(currentArray)?

Thank you again!

Happy to read you’re making progress! In my earlier post I mentioned that I suspect the issue is with which rows you select versus the length to the conditions table. You could, for example, print the values for the selected rows and the file name of the conditions table to the console, just before entering the loop. The moment that PsychoJS fails, check the latest values printed to the console to see whether they are what you’d expect.