Problem with random integer between python and JavaScript code

Hi everyone,

I noticed a problem with random number generation.
I am assigning a random list at the start of the experiment, and use the autoTranslate option
from python to JavaScript. Here is the code:

Python:
myLists = (“List1.xlsx”,“List2.xlsx”,“List3.xlsx”,“List4.xlsx”)
myChoice = randint(0,3)
listFile = myLists[myChoice]

JavaScript (auto-translated):
myLists = [“List1.xlsx”, “List2.xlsx”, “List3.xlsx”, “List4.xlsx”];
myChoice = (Math.floor((Math.random() * ((3 - 0) + 1))) + 0);
listFile = myLists[myChoice];

Both codes work, but lead to different results. If I do a test experiment, which draws 200 numbers,
in Python I get the following distribution:

table(myData$chosenList)
List1.xlsx List2.xlsx List3.xlsx
64 66 70

Which seems to indicate that, contrary to how randint is described, it is not inclusive (i.e., randint(0,3) only returns the option 0,1,2, but not 3. Or is there a different version of randint built into psychopy that differs from the (Math.)randint function?

However, online in piloting mode, I get:

table(myData$chosenList)
List1.xlsx List2.xlsx List3.xlsx List4.xlsx
44 52 49 55

Which indicates that (as intended) all four lists are chosen. Obviously, I want to make sure that this works,
because otherwise, I will be paying participants for nothing. I tried to change the code, so that I have similar steps in both, but ran into the problem that I could not call a floor function in PsychoPy (and I am not sure how autoTranslate will work, if I start using an import Math statement at the start of the experiment).

Sincerely,
Holger

Hi,

Please take a look at my crib sheet to see if it helps.

randint needs to be defined in Javascript and if I’ve got the wrong definition I’d like to fix it.

randint = function(min, max) {
  return Math.floor(Math.random() * (max - min) ) + min;
}

Your code seems to have an extra +1 in it.

Best wishes,

Wakefield

Hello Wakfield,

the code I posted is generated by autotranslate.
It is actually not a question of right and wrong, but how the max is defined.

Your version is excluding the maximum, with min = 0 and max = 3, it will only generate the 0,1, and 2.
(Math.random * 3-0) will generate a number in [0,3[, and floor will reduce this to either 0,1, or 2.

So your function works exacty as randint in PsychoPy, however, differently from how one would
expect randint to work (at least if one thinks about the function from the Python module random,
which is inclusive, i.e., the maximum is among the produced values).

Sincerely,
Holger

From my perspective I don’t mind whether the max value is included or excluded so long as the probabilities of each value are equal and the function works the same way in Python and JavaScript.

Hey,

Been a while since I posted here - just kind of lurking now - but I’m fairly certain that the randint is the one from numpy where it is exclusive of the max. Been in since like version 1.70.00 or something (check the changelog).

In the transpiler.py, there was a commit to fix the randint translation to remove the upper limit inclusivity (ie to make your autoTranslated code exclude the upper limit, similar to the numpy.random.randint) - this can be seen here.

I’m assuming this will make it into a future release since it was accepted so I’d plan accordingly.

Edit: I’ll also add in the pull here with notes that it was part of - here. I always just search the repo whenever something does something unexpected, see if it’s raised in any PRs, commits or issues as well as code base.

Ferenc

The auto translate doesn’t match the Python function. I’ve added my crib sheet to clarify.

Python
randint(min,maxplusone)

The auto translate produces a range which includes the max value. To suppress it write 0+randint(min,maxplusone) in your Python code.

PsychoJS

randint = function(min, maxplusone) {
  return Math.floor(Math.random() * (maxplusone - min) ) + min;
}

Hello,

I am trying to use the following code mentioned earlier in the thread:
randint = function(min, max) {
return Math.floor(Math.random() * (max - min) ) + min;
}

When I put it into a code component in psychopy it comes up with “/* Syntax Error: Fix Python code */”

I am trying to fix the error of “randint not defined” when I try to run my experiment online.

Can anyone help? I am using the 2020.2.10 version of psychopy.

That sounds like you are putting it on the Python side of an auto component not a JS component as per my crib sheet.

1 Like

You are of course quite right!
All sorted now, thank you!