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
    				alreadyUsedMain.push(r);
    				
    				// 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
    				alreadyUsedSep.push(r);
    
    				// 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!

    in reply to: cssContainer, inline display, and before/after text #9557
    bta
    Participant

    Thank you, this worked great!

    in reply to: Getting variable from csv, based on DropDown selections #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.

    in reply to: Getting variable from csv, based on DropDown selections #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 newImages 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)