IAT - I need help with randomizing stimuli

Im trying to make IAT in psychopy and its almost ready.
But it is not desired for respondent to assign more than 3 words in a row to a same category.
And I dont know how to randomize stimuli in this way.
I thought of using a “correct_key”. I asked chatgpt to write me a code which would make that the same correct_key that is connected to the stimuli in excel would not show up more than 3 times in a row but nothing would work.
This is how my loop looks like rn:

Im already using short code so that when respondent assigns word to the wrong category separate window shows with text “Mistake!” and then it goes right back to the words.

Please help.

I can think of three approaches that could work here.

  1. Set up a fixed order of stimuli that meets the criteria. I don’t do this any more but you can definitely get AI help with the order creation.
  2. Set up the list of trials before the loop starts and then use a sequential loop. I demonstrate this method in my complex randomisation online demo.
  3. The easiest method would be to have a trial type counter and then end the trial early (i.e. skip) whenever the counter is greater than 3. However, you might need extra trials and end the loop after the appropriate number. Something like this in Begin Routine.
if Condition == oldCondition:
     trialCount += 1
     if trialCount >= 3:
          continueRoutine = False
     else:
          allCount += 1
else:
     trialCount = 1
     allCount += 1
if allCount == 50:
     trials.finished = True
oldCondition = Condition

The method for repeating skipped trials is called Repeat Subset on my online demos page.

Hi! Thank you a lot for your reply
however before you replied I managed with chatgpt a working code but I still have a problem with online version.
This is the JS code I’m using:
// Fisher-Yates shuffle - zamíchá pole
function shuffle(array) {
for (let i = array.length - 1; i > 0; i–) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}

// Funkce pro randomizaci trialů
function generateRandomizedTrials(trialList, isCongruent = false, maxRepeats = 3) {
let randomizedTrials = ;
let availableTrials = trialList.slice(); // Kopie seznamu trialů
let previousCorrectKey = null;
let previousStimulus = null;
let consecutiveCorrectKeyCount = 0;

while (availableTrials.length > 0) {
    shuffle(availableTrials); // Zamíchej dostupné trialy

    for (let i = 0; i < availableTrials.length; i++) {
        let trial = availableTrials[i];
        let currentCorrectKey = trial['correct_key'];
        let currentStimulus = trial['stimuli'];

        // Pravidlo 1: Stejný stimul se nesmí objevit 2x za sebou
        if (currentStimulus === previousStimulus) {
            continue;
        }

        // Pravidlo 2: Stejný correct_key se nesmí objevit více než maxRepeats za sebou
        if (currentCorrectKey === previousCorrectKey) {
            if (consecutiveCorrectKeyCount >= maxRepeats) {
                continue;
            } else {
                consecutiveCorrectKeyCount += 1;
            }
        } else {
            consecutiveCorrectKeyCount = 1;
        }

        // Pokud je soubor 'category_congruent', přizpůsob randomizaci
        if (isCongruent) {
            let currentLeftCategory1 = trial['left_category1'];
            let currentLeftCategory2 = trial['left_category2'];
            let currentRightCategory1 = trial['right_category1'];
            let currentRightCategory2 = trial['right_category2'];

            // Kontrola specifických podmínek (např. nesmí se opakovat vícekrát stejná kombinace kategorií)
            if (currentLeftCategory1 === previousStimulus || currentRightCategory1 === previousStimulus) {
                continue;
            }
        }

        // Přidáme trial do seznamu výsledků a aktualizujeme proměnné
        randomizedTrials.push(trial);
        previousCorrectKey = currentCorrectKey;
        previousStimulus = currentStimulus;
        availableTrials.splice(i, 1); // Odstraníme trial ze seznamu dostupných

        break; // Ukončíme cyklus, abychom opět zamíchali a začali od začátku
    }
}

return randomizedTrials;

}

// Funkce pro načítání CSV souborů
function loadCSV(path) {
return new Promise((resolve, reject) => {
psychoJS.serverManager.downloadResource(path)
.then((response) => {
const rows = response.split(“\n”).map(row => row.split(“,”));
const headers = rows[0];
const trials = rows.slice(1).filter(row => row.length === headers.length).map(row => {
const trial = {};
headers.forEach((header, i) => {
trial[header.trim()] = row[i].trim();
});
return trial;
});
resolve(trials);
})
.catch((error) => {
console.error(Chyba při načítání CSV souboru ${path}:, error);
reject(error);
});
});
}

// Speciální podmínka pro soubor ‘category_congruent’
let isCongruent = false;

// Promises pro načítání a randomizaci všech souborů
let trialsToRandomize = [
{‘input’: ‘categoryTEST.csv’, ‘output’: ‘randomized_categoryTEST.csv’},
{‘input’: ‘category.csv’, ‘output’: ‘randomized_category.csv’},
{‘input’: ‘category_CF.csv’, ‘output’: ‘randomized_category_CF.csv’},
{‘input’: ‘category_congruent.csv’, ‘output’: ‘randomized_category_congruent.csv’}
];

let promises = ;
for (let i = 0; i < trialsToRandomize.length; i++) {
let trialInfo = trialsToRandomize[i];
let inputPath = trialInfo[‘input’];
let outputPath = trialInfo[‘output’];

// Zkontrolujeme, zda se jedná o 'category_congruent'
if (inputPath === 'category_congruent.csv') {
    isCongruent = true;
} else {
    isCongruent = false;
}

promises.push(
    loadCSV(inputPath)
        .then(function(trialList) {
            // Spustíme randomizaci s ohledem na specifika
            let randomizedTrials = generateRandomizedTrials(trialList, isCongruent);
            console.log(`Randomizované trialy pro ${outputPath}:`, randomizedTrials);
            psychoJS.experiment.addData(outputPath, randomizedTrials);  // Volitelně pro uložení
            return randomizedTrials;
        })
        .catch(function(error) {
            console.error(`Chyba při načítání souboru ${inputPath}:`, error);
        })
);

}

// Čekáme, až budou všechny soubory zpracovány
Promise.all(promises).then(function() {
console.log(“Všechny soubory byly úspěšně randomizovány!”);
});

first 3 trials work without a problem (categoryTEST, category, category_CF)
but fourth trial does not (category_congruent) shows this error mssg:
when importing condition: randomized_category_congruent.xlsx
when getting the value of resource: randomized_category_congruent.xlsx
unknown resource

in coditions for first 3 loops i have randomized_categoryTEST.xlsx etc. and it works
but in fourth loop it does not
mby its because of a little bit different layout of an excel file?
this is how the first 3 excel sheets looks like:


this is how category_congurent looks like:

How to fix this?


sorry you cant see the top row in second picture
here it is

i tried to make new code with chatgpt that would account for different layout but it did not work


the JS code is located in “loading_1”

I’m afraid that I can’t debug extensive code, especially when AI generated and/or JavaScript.

I spotted a response not found error which usually means you should add the resource in Experiment Settings / Online / Additional resources. However, if you are trying to write a csv trials list file during the experiment then that approach won’t work online.