Replacing "import xlrd" to JS code - creating arrays from a csv

URL of experiment: none yet

Description of the problem:

Dear code wizards,

I am trying to upload an experiment to Pavlovia that I have partly created in PsychoPy builder, but that includes some code components. I have amended some of my code according to the Wake crib sheet, but I am stuck on one particular piece of code: the import XLRD.

A bit of background: xlrd is used in a lot of python tutorials to create a big dataframe from a csv and typically looks like this:

import xlrd
infile = “file_name.xlsx”
workbook = xlrd.open_workbook(infile)
sheet = workbook.sheet_by_index(0)

With the “sheet”, you can create arrays like so:

stim_list = #creates an empty array

for rowx in range (list_start, list_end):
row = sheet.row_values(rowx)
stim_list.append(row[0]) #here, the first column of the “sheet” is appended to an empty array for every row in the specified range

Here is the problem though. I can’t use import functions in Pavlovia. I’ve looked around and found this piece of JS code that supposedly creates a master dictionary similar to the csv “sheet” described above.

expVars = {};
csvData = data.importConditions(‘stims.csv’);
for k in csvData[0]:
expVars[k] = [d[k] for d in csvData];

( I can access the dictionary like this: >expVars[‘var1’][33])

Moving on, I want to create arrays from this dictionary file. I still use the append function, but have added a piece of code at the beginning of my experiment that translates it the JS equivalent:

Array.prototype.append = .push;

I’ve also done the same for the range function

range = function (size, startAt = 0) {
return […Array(size).keys()].map(i => i + startAt);
}

Finally, my code looks like this:

expVars = ;
csvData = data.importConditions(‘stims.csv’);
for k in csvData[0]:
expVars[k] = [d[k] for d in csvData];

stim_list =
for rowx in range (list_start, list_end):
row = expVars.row_values(rowx)
stim_list.append(row[0])

When I upload this, the experiment is stuck on initialising. I suspect that the problem lies somewhere with the loop that creates the stim_list array, but I’m not sure and I don’t know how to fix this.

Any help would be greatly appreciated. I am new to all of this, so please use short words ^^.

@Menno_van_Berkel , you can use the trialHandler to handle your csv import, in both Python and JS - see the link below

Thanks! I tried this but got the following error:

Unfortunately we encountered the following error:

  • when importing condition: conditions.xlsx
  • when getting the value of resource: conditions.xlsx
  • unknown resource

This is strange because that file (spelled correctly) is in my resources, in my folder and on the pavlovia resource interface.

Ah yes I forgot to mention, you also need to add the conditions file as a resource. Go to Experiment Settings - online tab and use the “Additional Resources” box to add the spreadsheet (click the plus button). Now PsychoPy will recognise your conditions file defined in the code as a resource and send it to Pavlovia when you sync your task.

One step closer, but I’m still getting the same error message. Here’s a screenshot of my online tab (the xlsx file is not named condition.xlsx. But I’ve referred to it in the past for simplicity’s sake)

@Menno_van_Berkel , in case you have not already, you need to replace the name of the conditions file in the code, e.g.,

trials = new TrialHandler({
		psychoJS: psychoJS,
		nReps: 1, method: TrialHandler.Method.RANDOM,
		extraInfo: expInfo, originPath: undefined,
		trialList: 'court_size_stims_JS.xlsx',
		seed: undefined, name: 'trials'
	});

trialList = trials.getTrialList()

Yep, here’s a screenshot in case I’m missing something.

I have since looked at a number of similar queries, that are usually solved with a typo. I can assure you that there are no typos here (the file name is copied directly into the code).

I have also tried to run the JS script locally from the psychopy builder (just to eliminate possible causes), and I get the same error.

It is like it can not find the xlsx file, but

  • The xlsx file is in the folder which my .psyexp file is
  • The xlsx file is also in the resource subfolder
  • I have added the xlsx file in the online tab of my settings (both of the above 2 paths, just in case)
  • It is referenced correctly in the provided code

Still, every time I get:

Unfortunately we encountered the following error:

  • when importing condition: court_size_stims_JS.xlsx
  • when getting the value of resource: court_size_stims_JS.xlsx
  • unknown resource

@Menno_van_Berkel , try moving that code from the “Before Experiment” tab to the “Begin Experiment” tab. If you look at the JS code you will see where the additional resources are imported, so you need the trialhandler code to appear after that code has imported the resources, then it should find the file.

I actually had the same thought and I have since moved it to the begin experiment tab. Still no luck though.

Perhaps you need to refresh your browser cache to get the up to date code running. Still a good idea to open the JS file and make sure the code is in the right place. If no joy after this, if possible please share your project with me so I can take a look.

I don’t see any reference to the resources. I’ve given you access just now. Don’t mind the rest of the code. I’m sure I’ll have to debug the hell out of it after this gets fixed.

@Menno_van_Berkel , cannot see anything on your gitlab project, have you uploaded to Pavlovia? If so, you may need to make the project public.

Apologies, I’ve made it public now to members (you are a guest member). Hopefully that should do it.

@Menno_van_Berkel I think the issue is that your HTML output path in Experiment Settings contains the absolute path to your project. Delete the path and leave that blank, resync and try again. After removing that path, I had no problems compiling the JS with the additional resources added.

OKAY, I may have found a solution, although in a bit of a roundabout way. I’m very curious though what the problem was.

What ended up working: In builder, I have created a loop that doesn’t do anything, but that references my excel file.

This, apparently triggers the loading of my excel file, before I reference it later on in the code.