# bta

## Forum Replies Created

Viewing 6 posts - 1 through 6 (of 6 total)
• Author
Posts
• in reply to: SepWithN + random item from template #10916
bta
Participant

I have figured out a solution, which I’m sharing below (I’ve put this code in a .js file that I added under “modules”).

I use it in my `Sequence()` as in `Sequence( sepChunkWithChunk("theSeparator", 1, "theStimuli", 2) )`, which does what I described in my previous post (*except that it doesn’t add a separator after the final stimulus, which I did on purpose*).

``````
// this code below lets you put something like sepChunkWithChunk("separators", 1, "stimuli", 2) into the Sequence
//      this works so that, if you have a Trial (in a Template) named "separators" and a Trial (in a Template) named "stimuli", …
//      …it will present trials from the "stimuli" in chunks of 2, with each chunk separated by 1 trial from "separators"
//		(NOTE: there will be a "separators" chunk between chunks of "stimuli" — meaning if there are 4 chunks of "stimuli", only 3 "separators" chunks will be alreadyUsed)
function  SepChunkWithChunk(sep, nSep, main, nMain) {
assert(typeof(nSep)=="number" && nSep>0, "nSep should be a number greater than 0");
assert(typeof(nMain)=="number" && nMain>0, "nMain should be a number greater than 0");

this.args = [sep, main];

this.run = function(arrays) {
var alreadyUsedSep = [];
var alreadyUsedMain = [];
let sep = arrays[0];
let main = arrays[1];
var numChunksForMain = Math.ceil(main.length / nMain); // calculates the number of chunks of 'main' are necessary to show all items from 'main'
var totalNumUsedFromMain = 0; // counter for tallying number of items used from 'main'

var chunkedAndSeparatedArray = []; // this array will house the order of all trials, randomized into chunks of 'main' separated by chunks of 'sep'

for (let i = 1; i <= numChunksForMain; ++i) { // run this loop as many times as there are chunks of 'main'
counterMain = 0;
counterSep = 0;

// create a chunk with 'nMain' elements by looping 'nMain' times
//		STOP LOOPING if it's already pulled out all trials from 'main'
//		(this will happen if, e.g., you have 8 trials in 'main' and 'nMain' is set to something like 5 — two chunks are needed, but the second chunk should only have 3 elements)
while (counterMain < nMain && totalNumUsedFromMain < main.length) {
// generate a random number between 0 and (main.length-1):
r = Math.floor(Math.random()*main.length);

// keep generating a new random number until the random number generated hasn't been used before
//		(this has the effect of blocking the repetition of items from 'main' that have already been added to 'chunkedAndSeparatedArray')
while (alreadyUsedMain.includes(r)) { r = Math.floor(Math.random()*main.length); }

// now that a unique random number has been generated, add it to the array of random numbers that have been used

// add the rTH trial from 'main' to 'chunkedAndSeparatedArray'
chunkedAndSeparatedArray.push(main[r]);

// increase counters
++counterMain;
++totalNumUsedFromMain;
}

// create a chunk with 'nSep' elements by looping 'nSep' times
//		DON'T RUN THIS LOOP if the last chunk of 'main' has just been added to 'chunkedAndSeparatedArray'
if (i != (numChunksForMain)){
while (counterSep < nSep) {
// generate a random number between 0 and (sep.length-1):
r = Math.floor(Math.random()*sep.length);

// keep generating a new random number until the random number generated hasn't been used before
//		UNLESS all the trials from 'sep' have already been used
//		(this has the effect of allowing separator trials to be re-used just in case the number of separators needed is greater than the number of unique trials in 'sep')
while (alreadyUsedSep.includes(r) && sep.length > alreadyUsedSep.length ) {
r = Math.floor(Math.random()*sep.length);
}

// now that a unique random number has been generated, add it to the array of random numbers that have been used

// add the rTH trial from 'sep' to 'chunkedAndSeparatedArray'
chunkedAndSeparatedArray.push(sep[r]);

// increase counter
++counterSep;
}
}
}

// return the finalized Array, which will have all the trials of 'main' in a raondomized order
// moreover, between every chunk of 'nMain' trials, there is a chunk of random 'nSep' trials from 'sep'
return chunkedAndSeparatedArray;
}
}
function sepChunkWithChunk(sep, nSep, main, nMain) { return new SepChunkWithChunk(sep, nSep, main, nMain); }
``````
in reply to: run command while MediaRecorder is recording #10687
bta
Participant

Great that worked perfectly!

#9557
bta
Participant

Thank you, this worked great!

#8316
bta
Participant

Thank you so much, this is so helpful! I find it challenging to think this way, but I’m starting to get used to it.

#8314
bta
Participant

Oh great, thanks! This is very helpful. I did not know that all JS functions are run from the start, even when the calls to those functions are made within instances of PennController `test.is`.

The one thing that I didn’t mention before is that I did want to reuse the image multiple times, which I think would just mean using the series of `test.is` statements every time I reuse the image. Is that right?
(i.e., it seems to me that all of these `newImage`s cannot have the same name —something like testerImage— because every time `newImage` is called it needs to have a unique identifier; and because of that, there’s no way to use a single line of code like `getImage("testerImage")` to call back that same image.)

in reply to: MediaRecorder in Safari #8292
bta
Participant

Great, yes, that worked! Thank you!

Viewing 6 posts - 1 through 6 (of 6 total)