Pavlovia: How to implement the range function?

Hi everybody!
My experiment is stuck on “Initializing the experiment” and I think, I found the problem.
I’m using a range function and as I read in the crib sheet (https://docs.google.com/document/d/13jp0QAqQeFlYSjeZS0fDInvgaDzBXjGQNe4VNKbbNHQ/edit#heading=h.xamc2didaojg), the auto translation does not work. My problem is, that I don’t get the “correct version” of the crib sheet to run.

I want to draw items out of two different lists depending on the accuracy of the current trial to create a variable ITI (intertrial interval so that the time passing by from the prior to the next trial depends on the accuracy). This is how my Python code looks like (which works fine offline):

#Determine random ITI depending on accuracy of the current trial
step_size = 1
start_val_correct = 1
end_val_correct = 3
start_val_wrong = 9
end_val_wrong = 12

l_correct = range(start_val_correct, end_val_correct, step_size)
l_wrong = range(start_val_wrong, end_val_wrong, step_size)

#shuffle list
import random
ITI_correct_big = random.choice(l_correct)
ITI_wrong_big = random.choice(l_wrong)

ITI_correct = ITI_correct_big/10
ITI_wrong = ITI_wrong_big/10

As you can see the lists to choose from vary either from 1 to 3 or from 9 to 12 with step size 1.

Here is what I tried to implement the correct function of the crib sheet using these forum entries

But it’s not working, still stuck on “initializing the experiment”:

var ITI_correct, ITI_correct_big, ITI_wrong, ITI_wrong_big, end_val_correct, end_val_wrong, l_correct, l_wrong, start_val_correct, start_val_wrong, step_size;
step_size = 1;
start_val_correct = 1;
end_val_correct = 3;
start_val_wrong = 9;
end_val_wrong = 12;
range_corr = function range(size, startAt = 1) {
    return [...Array(3).keys()];
}
range_wrong = function range(size, startAt = 9) {
    return [...Array(12).keys()];
}
random = Math.random;
ITI_correct_big = random.choice(range_corr);
ITI_wrong_big = random.choice(range_wrong);
ITI_correct = (ITI_correct_big / 10);
ITI_wrong = (ITI_wrong_big / 10);

I also tried to work around the range function by creating a list of the elements, so that the random function can pick from the list directly. But it’s not working either.

range_corr, range_wrong, random, ITI_correct, ITI_wrong;
range_corr = [0.1, 0.2, 0.3];
range_wrong = [0.9, 1.0, 1.1, 1.2];
random = Math.random;
ITI_correct = random.choice(range_corr);
ITI_wrong = random.choice(range_wrong);

Additionally, I found this post: Code conversion Jittered ITI in PsychoJS
I added my code accordingly, but I’m still stuck on the initializing (all is in Begin Routine now).

iti_correct, iti_wrong;
randint = function(min, maxplusone) {
    return Math.floor(Math.random() * (maxplusone - min) ) + min;
}
round = function(num, n=0) {
    return +(Math.round(num + ("e+" + n))  + ("e-" + n));
}
iti_correct = (randint(0, 201)+100)/1000;
iti_correct = Math.round(iti_correct(iti_correct, 1);
iti_wrong = (randint(0, 301)+900)/1000;
iti_wrong = Math.round(iti_wrong(iti_wrong, 1);
if ((mt_key_resp_t1.corr && mt_key_resp_t2.corr)) {
    mt_iti_dur = iti_correct;
} else {
    mt_iti_dur = iti_wrong;
}

How do I correctly implement the range function or the drawing from the list in JavaScript? Any help is highly appreciated!
Thanks!

Hi There,

I use this function at the start of my experiment - hopefully it works for you!

// we use range() in python so make equivilent in JS
function range(size, startAt = 0) {
    return [...Array(size).keys()].map(i => i + startAt);
}

Becca

1 Like

Hi Becca!
Thanks for your answer. I found this code in the crib sheet as well but I don’t know exactly how to implement it. I tried it and it didn’t work but as I said, I’m not sure whether I implemented it correctly.
Are size and startAt placeholders? Do I simply use the normal range() after setting your code in the Begin of Experiment code component?

Thanks in advance!

Aha (Yes I just noticed this was already on the crib sheet too!).

OK, to implement it.

In your first routine add a code component and select type to just be ‘JS’ then paste this code in there. You should then later be able to call range as you would normally.

Becca :slight_smile:

1 Like

Hi Becca!
Thanks so much! Now the range function seems to be working perfectly fine.

But the random function doesn’t. I get the error messages that choice of random.choice(l_correct) is undefined. If I only put random(l_correct), I receive an unspecific JavaScript error.
How do I exactly implement the correct version of random? And can I use .choice with it or is there an alternative to randomly choose out the list I created with the random function?

Cheers, Inga :slight_smile:

Yes, so random.choice doesn’t exist in JS. There are two solutions to this (I recommend the second but I will outline both for clarity:

  1. Try adding a JS function that performs a similar function to random.choice in JS.
function choose(choices) {
  var index = Math.floor(Math.random() * choices.length);
  return choices[index];
}

then in any cases where you have used ‘random.choice’ in code components, change code type to ‘both’ and replace ‘random.choice’ with ‘choose’

  1. Use shuffle (outlined on crib sheet) and then to randomly select call something like:
myList = [1, 2, 3]
shuffle(myList)
myPick = myList[0]

I recommend the second because then you can keep later code components as code type auto->JS (which is nicer in the long run).

Hope this helps,
Becca

2 Likes

Great, thanks! I implemented your second solution but I’m still running in an unspecified JavaScrip error. Any suggestions?

Begin Experiment:
iti_correct_list, iti_wrong_list;
iti_correct_list = [0.1, 0.2, 0.3]
iti_wrong_list = [0.9, 1.0, 1.1, 1.2]
shuffle = util.shuffle;

Begin Routine:
if ((mt_key_resp_t1.corr && mt_key_resp_t2.corr)) {
    shuffle(iti_correct_list)
    mt_iti_dur = iti_correct_list[0]
} else {
    shuffle(iti_wrong_list)
    mt_iti_dur = iti_wrong_list[0]
}

Now, that you told me to simply create lists, I didn’t use the range function anymore.

Thanks in advance!

Are you using auto translate? You seem to have missing semi-colons.

I’m assuming the keyboard components are from previous routines.

No, I didn’t use auto translate for this one.
Thanks for the hint with the semi-colons (I’m really sorry, but I haven’t worked with JS so far, so it’s not straight forward for me…). I changed my code and added the semi-colons but I’m still running into an unspecified JS error… Any other mistakes you can see?

Begin Experiment:
iti_correct_list, iti_wrong_list, shuffle;
iti_correct_list = [0.1, 0.2, 0.3];
iti_wrong_list = [0.9, 1.0, 1.1, 1.2];
shuffle = util.shuffle;

Begin Routine:
if ((mt_key_resp_t1.corr && mt_key_resp_t2.corr)) {
    shuffle(iti_correct_list);
    mt_iti_dur = iti_correct_list[0];
} else {
    shuffle(iti_wrong_list);
    mt_iti_dur = iti_wrong_list[0];
}

Yes, the keyboard components are from the previous routine which I built with the builder, no coding there.

I don’t understand your first line of code. I don’t use anything like that to pre-declare variables.

I would recommend coding in Python where possible, since then the auto translate checks your syntax as you go.

Okay! I did so, now my code is the following (offline it works perfectly fine, online I still receive the unspecified JS error though…)

Begin Experiment:
iti_correct_list = [0.1, 0.2, 0.3];
iti_wrong_list = [0.9, 1.0, 1.1, 1.2];
shuffle = util.shuffle;

Begin Routine:
if ((mt_key_resp_t1.corr && mt_key_resp_t2.corr)) {
    shuffle(iti_correct_list);
    mt_iti_dur = iti_correct_list[0];
} else {
    shuffle(iti_wrong_list);
    mt_iti_dur = iti_wrong_list[0];
}

Thanks for all the helpful comments btw!! Really appreciated!

Next thing is to check the browser console in case you can get a line number or more specific error message. If the experiment starts then using print/console log in your code can also show how far it gets before crashing.

I’ve previously come across two reasons for an unspecified javascript error: a text element with a decimal size (e.g. .1) when the units are in pixels and setting an image as unspecified.

1 Like

Thanks sooo sooo much @Becca and @wakecarter!
I finally got it to run! I used the code above and set the size of the text element to 20 instead of .1 (because my units are in pixels)! So grateful that you helped me out!!

1 Like

pleased you have a solution!