mirror of
https://github.com/jspsych/jsPsych.git
synced 2025-05-10 19:20:55 +00:00
add setSeed
to randomization
This commit is contained in:
parent
512ea0115e
commit
83b1ba291f
@ -1,4 +1,20 @@
|
||||
import rw from "random-words";
|
||||
import seedrandom from "seedrandom";
|
||||
|
||||
/**
|
||||
* Uses the `seedrandom` package to replace Math.random() with a seedable PRNG.
|
||||
*
|
||||
* @param seed An optional seed. If none is given, a random seed will be generated.
|
||||
* @returns The seed value.
|
||||
*/
|
||||
export function setSeed(seed?) {
|
||||
if (!seed) {
|
||||
const prng = seedrandom();
|
||||
seed = prng.int32();
|
||||
}
|
||||
seedrandom(seed, { global: true });
|
||||
return seed;
|
||||
}
|
||||
|
||||
export function repeat(array, repetitions, unpack = false) {
|
||||
const arr_isArray = Array.isArray(array);
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
randomID,
|
||||
randomInt,
|
||||
repeat,
|
||||
setSeed,
|
||||
shuffle,
|
||||
shuffleAlternateGroups,
|
||||
shuffleNoRepeats,
|
||||
@ -165,3 +166,20 @@ describe("randomInt", () => {
|
||||
}).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe("setSeed", () => {
|
||||
test("Replaces Math.random() with seedable RNG", () => {
|
||||
setSeed(12603);
|
||||
|
||||
const r1_1 = Math.random();
|
||||
const r1_2 = Math.random();
|
||||
|
||||
setSeed(12603);
|
||||
|
||||
const r2_1 = Math.random();
|
||||
const r2_2 = Math.random();
|
||||
|
||||
expect(r1_1).toEqual(r2_1);
|
||||
expect(r1_2).toEqual(r2_2);
|
||||
});
|
||||
});
|
||||
|
93
packages/jspsych/tests/randomization/setseed.test.ts
Normal file
93
packages/jspsych/tests/randomization/setseed.test.ts
Normal file
@ -0,0 +1,93 @@
|
||||
// this file is to test that jsPsych.randomization.setSeed works in context
|
||||
|
||||
import htmlKeyboardResponse from "@jspsych/plugin-html-keyboard-response";
|
||||
import { pressKey, startTimeline } from "@jspsych/test-utils";
|
||||
|
||||
import { initJsPsych } from "../../src";
|
||||
|
||||
describe("setSeed generates predictable randomization", () => {
|
||||
test("timeline variable randomization is preserved", async () => {
|
||||
const jsPsych = initJsPsych();
|
||||
|
||||
const seed = jsPsych.randomization.setSeed();
|
||||
|
||||
const { getData } = await startTimeline(
|
||||
[
|
||||
{
|
||||
timeline: [
|
||||
{
|
||||
type: htmlKeyboardResponse,
|
||||
stimulus: "this is html",
|
||||
data: {
|
||||
i: jsPsych.timelineVariable("i"),
|
||||
},
|
||||
},
|
||||
],
|
||||
timeline_variables: [
|
||||
{ i: 0 },
|
||||
{ i: 1 },
|
||||
{ i: 2 },
|
||||
{ i: 3 },
|
||||
{ i: 4 },
|
||||
{ i: 5 },
|
||||
{ i: 6 },
|
||||
{ i: 7 },
|
||||
{ i: 8 },
|
||||
],
|
||||
randomize_order: true,
|
||||
},
|
||||
],
|
||||
jsPsych
|
||||
);
|
||||
|
||||
for (let i = 0; i < 9; i++) {
|
||||
pressKey(" ");
|
||||
}
|
||||
|
||||
const data_run_1 = getData().readOnly();
|
||||
|
||||
const jsPsych_run2 = initJsPsych();
|
||||
|
||||
jsPsych_run2.randomization.setSeed(seed);
|
||||
|
||||
const { getData: getData2 } = await startTimeline(
|
||||
[
|
||||
{
|
||||
timeline: [
|
||||
{
|
||||
type: htmlKeyboardResponse,
|
||||
stimulus: "this is html",
|
||||
data: {
|
||||
i: jsPsych_run2.timelineVariable("i"),
|
||||
},
|
||||
},
|
||||
],
|
||||
timeline_variables: [
|
||||
{ i: 0 },
|
||||
{ i: 1 },
|
||||
{ i: 2 },
|
||||
{ i: 3 },
|
||||
{ i: 4 },
|
||||
{ i: 5 },
|
||||
{ i: 6 },
|
||||
{ i: 7 },
|
||||
{ i: 8 },
|
||||
],
|
||||
randomize_order: true,
|
||||
},
|
||||
],
|
||||
jsPsych_run2
|
||||
);
|
||||
|
||||
for (let i = 0; i < 9; i++) {
|
||||
pressKey(" ");
|
||||
}
|
||||
|
||||
const data_run_2 = getData2().readOnly();
|
||||
|
||||
console.log(data_run_1.values());
|
||||
console.log(data_run_2.values());
|
||||
|
||||
expect(data_run_1.select("i").values).toEqual(data_run_2.select("i").values);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user