psychopy.org | Reference | Downloads | Github

Using JSON as the condition file

Hi all,

I am trying to perform a randomization procedure on my condition file (selecting 1 row from every 4 rows). @dvbridges kindly helped me last year with the python code. Now, I am trying to do my experiment online and I converted those codes into JS. The code returns a JSON file when I run it in the Visual Studio. However I got an error when I run it in psychpy online: stim is not defined. What is my mistake? Any idea?

// at the beginning tab:
// after creating a long array named my_df:

// First, get the stimtype
var stim_no = [];
for (var i = 0; i <= Math.max.apply(Math, my_df.map(function(o) { return o.num; })); i++) {
  stim_no.push(i);
}

// create a function to shuffle a list
function shuffle(a) {
  var j, x, i;
  for (i = a.length - 1; i > 0; i--) {
      j = Math.floor(Math.random() * (i + 1));
      x = a[i];
      a[i] = a[j];
      a[j] = x;
  }
  return a;
}

var colorful_type = [1,2,3,4];
var bw_type = [1,2,3,4];
shuffle(colorful_type);
shuffle(bw_type);


// Create a blank array to append our final stimuli
const final_df = []; 


// for stims in 24
for (let i=0; i< my_df.length / 8; i++){
  stim = my_df.filter(function (el) {
    return el.num === i;}); // Get each number one by one
  clrs = stim.filter(function (el) {
    return el.type_num == 0;}); // Then get the colorful type for that number
  bws = stim.filter(function (el) {
    return el.type_num == 1;}); // Then get bw type for that number

  if (colorful_type.length !== 0) {
    stim_num = colorful_type.pop()
    stim_color = clrs.filter(function (el) {
      return el.color_num === stim_num;
    })
    stim_num = bw_type.pop()
    stim_bw = bws.filter(function (el) {
      return el.color_num === stim_num;
    })
  };
  final_df.push (stim_color);
  final_df.push (stim_bw);

  if (colorful_type.length === 0){
    var colorful_type = [1,2,3,4];
    var bw_type = [1,2,3,4];
    shuffle(colorful_type);
    shuffle(bw_type);
  };
}

const stimJSON = JSON.stringify (final_df);

Then, I ignored the randomization codes and just simply assign my array into a json:

const stimJSON = JSON.stringify (my_df);

And at the loop, I added $stimJSON as the conditions and I faced with: ReferenceError: stimJSON is not defined. How can I solve this issue, too?

Moreover, I converted my CSV file to JSON using online convertors and then copy and paste all objects into the code component because I could not load it as an external JSON file using require (). I got require is not defined error which arises from running node codes into the browser. Any recommendations for this issue would be appreciated.

Is there a reason you can’t just use the csv file (and generate your code in Builder)? I think you shouldn’t need all this hand-wrtten code

Actually, I need to show participants one row (1 color) from every 4 rows (4 different colors) of my csv file and at the end, the number of colors presented should be the same. I can create, for example, 100 csv files and assign each to one participants, but the problem is that it takes a long time for a person to run the experiment online (4 or 5 mintues).

Thus, I translate my python codes to JS however I faced several challenges that I described above.

But the selectRows option in the builder interface should allow you to choose the rows from the csv file, and these can then be set differently for each participant.

For the require is not defined error, StackOverflow says this: https://stackoverflow.com/questions/23603514/javascript-require-function-giving-referenceerror-require-is-not-defined

For stimJSON is note defined my guess is that either you define it too late inthe script or in the wrong scope for the code

1 Like

Oh, I was not aware of the selectRows option. I need to check it to see if it can solve my problem which I think it is a huge help. Especially, if we could pass a list as its argument. Thanks for suggesting that.

Hi @Omidrezaa, as Jon says, I think the ReferenceError is because you declared your variable within a function using const. I would go with using a csv file and the selectRows solution above, but if you did want to import a JSON file, I think the following should work, printing any errors to the console:

resourceList = jQuery.getJSON("resources.json")  // assuming file is called "resources.json"
  .done(function(data) {
  // parse when resources.json has successfully downloaded
  resourceObj = JSON.parse(resourceList.responseText);
  })
  .fail(function(error){
  console.log(error);
  });

Thank you @dvbridges. I listened to Jon’s advice and decided to use the selectRows facility. Thus, after the block of the JS codes which choose 1 row from every 4 rows and push them to an array of row numbers, I added two lines of codes to see if it is working:

console.log (my_rows);
console.log ('no error in your JS codes')

And here is the output:

Next, I assigned my_rows array to the selected rows argument of the loop, but I faced this error: ReferenceError: my_rows is not defined.

PS. I removed const from the beginning of my list definition, but I faced the same error.

I would appreciate it if you could give me some advice about that.

And here is the URL to my experiment:
https://run.pavlovia.org/omidghasemi21/test1/html/?__pilotToken=eccbc87e4b5ce2fe28308fd9f2a7baf3&__oauthToken=1107c244a2dd1e37075b90faa65353b668a18dbdd815ff6ce031ef6816d9bc85

@Omidrezaa I just downloaded and ran your task from Pavlovia, and it ran to the end of the task with no errors. Try refreshing your browser cache and rerunning the task.

1 Like

Yes, It worked nicely. Thank you, David and Jon :slight_smile: