diff --git a/.gitignore b/.gitignore index 6a4df1c..2265696 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,10 @@ *.iws .DS_Store -tmp/ \ No newline at end of file +tmp/ + +demo/data/ +demo/events/ +data/ +events/ +__pycache__ diff --git a/.gitignore b/.gitignore index 6a4df1c..2265696 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,10 @@ *.iws .DS_Store -tmp/ \ No newline at end of file +tmp/ + +demo/data/ +demo/events/ +data/ +events/ +__pycache__ diff --git a/Pipfile b/Pipfile index 23d2206..5703ad7 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,8 @@ requests = "*" python-constraint = "*" Numberjack = "*" +expyriment = "*" +pygame = "==1.9.5.dev0" [requires] python_version = "3.7" diff --git a/.gitignore b/.gitignore index 6a4df1c..2265696 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,10 @@ *.iws .DS_Store -tmp/ \ No newline at end of file +tmp/ + +demo/data/ +demo/events/ +data/ +events/ +__pycache__ diff --git a/Pipfile b/Pipfile index 23d2206..5703ad7 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,8 @@ requests = "*" python-constraint = "*" Numberjack = "*" +expyriment = "*" +pygame = "==1.9.5.dev0" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 25ca7bf..a61b507 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "8741d50b672e81aecb9c484903354969f4b9e6834a4220355e088e83b03ec6fa" + "sha256": "bacdafb02274e91e6b626d22d4b069ff8c1321beee335721e5163494e68fa35e" }, "pipfile-spec": 6, "requires": { @@ -30,6 +30,19 @@ ], "version": "==3.0.4" }, + "expyriment": { + "hashes": [ + "sha256:2f8d859deaf1ee7a2a906764d6820ddb656a1887601f3831562e419d5e5857c0" + ], + "index": "pypi", + "version": "==0.9.0" + }, + "future": { + "hashes": [ + "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8" + ], + "version": "==0.17.1" + }, "idna": { "hashes": [ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", @@ -44,6 +57,43 @@ "index": "pypi", "version": "==1.2.0" }, + "pygame": { + "hashes": [ + "sha256:06dc92ccfea33b85f209db3d49f99a2a30c88fe9fb80fa2564cee443ece787b5", + "sha256:0919a2ec5fcb0d00518c2a5fa99858ccf22d7fbcc0e12818b317062d11386984", + "sha256:0a8c92e700e0042faefa998fa064616f330201890d6ea1c993eb3ff30ab53e99", + "sha256:220a1048ebb3d11a4d48cc4219ec8f65ca62fcafd255239478677625e8ead2e9", + "sha256:315861d2b8428f7b4d56d2c98d6c1acc18f08c77af4b129211bc036774f64be2", + "sha256:3469e87867832fe5226396626a8a6a9dac9b2e21a7819dd8cd96cf0e08bbcd41", + "sha256:54c19960180626165512d596235d75dc022d38844467cec769a8d8153fd66645", + "sha256:5ba598736ab9716f53dc943a659a9578f62acfe00c0c9c5490f3aca61d078f75", + "sha256:60ddc4f361babb30ff2d554132b1f3296490f3149d6c1c77682213563f59937a", + "sha256:6a49ab8616a9de534f1bf62c98beabf0e0bb0b6ff8917576bba22820bba3fdad", + "sha256:6d4966eeba652df2fd9a757b3fc5b29b578b47b58f991ad714471661ea2141cb", + "sha256:700d1781c999af25d11bfd1f3e158ebb660f72ebccb2040ecafe5069d0b2c0b6", + "sha256:73f4c28e894e76797b8ccaf6eb1205b433efdb803c70f489ebc3db6ac9c097e6", + "sha256:786eca2bea11abd924f3f67eb2483bcb22acff08f28dbdbf67130abe54b23797", + "sha256:7bcf586a1c51a735361ca03561979eea3180de45e6165bcdfa12878b752544af", + "sha256:82a1e93d82c1babceeb278c55012a9f5140e77665d372a6d97ec67786856d254", + "sha256:9e03589bc80a21ae951fca7659a767b7cac668289937e3756c0ab3d753cf6d24", + "sha256:aa8926a4e34fb0943abe1a8bb04a0ad82265341bf20064c0862db0a521100dfc", + "sha256:aa90689b889c417d2ac571ef2bbb5f7e735ae30c7553c60fae7508404f46c101", + "sha256:c9f8cdefee267a2e690bf17d61a8f5670b620f25a981f24781b034363a8eedc9", + "sha256:d9177afb2f46103bfc28a51fbc49ce18987a857e5c934db47b4a7030cb30fbd0", + "sha256:deb0551d4bbfb8131e2463a7fe1943bfcec5beb11acdf9c4bfa27fa5a9758d62", + "sha256:e7edfe57a5972aa9130ce9a186020a0f097e7a8e4c25e292109bdae1432b77f9", + "sha256:f0ad32efb9e26160645d62ba6cf3e5a5828dc4e82e8f41f9badfe7b685b07295" + ], + "version": "==1.9.4" + }, + "pyopengl": { + "hashes": [ + "sha256:2f3e757ded041c0c1e6175a0bb19f6e77f4063c54ad4ae0c8d3ff1a0996822b5", + "sha256:9b47c5c3a094fa518ca88aeed35ae75834d53e4285512c61879f67a48c94ddaf", + "sha256:efa4e39a49b906ccbe66758812ca81ced13a6f26931ab2ba2dba2750c016c0d0" + ], + "version": "==3.1.0" + }, "python-constraint": { "hashes": [ "sha256:501d6f17afe0032dfc6ea6c0f8acc12e44f992733f00e8538961031ef27ccb8e" diff --git a/.gitignore b/.gitignore index 6a4df1c..2265696 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,10 @@ *.iws .DS_Store -tmp/ \ No newline at end of file +tmp/ + +demo/data/ +demo/events/ +data/ +events/ +__pycache__ diff --git a/Pipfile b/Pipfile index 23d2206..5703ad7 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,8 @@ requests = "*" python-constraint = "*" Numberjack = "*" +expyriment = "*" +pygame = "==1.9.5.dev0" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 25ca7bf..a61b507 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "8741d50b672e81aecb9c484903354969f4b9e6834a4220355e088e83b03ec6fa" + "sha256": "bacdafb02274e91e6b626d22d4b069ff8c1321beee335721e5163494e68fa35e" }, "pipfile-spec": 6, "requires": { @@ -30,6 +30,19 @@ ], "version": "==3.0.4" }, + "expyriment": { + "hashes": [ + "sha256:2f8d859deaf1ee7a2a906764d6820ddb656a1887601f3831562e419d5e5857c0" + ], + "index": "pypi", + "version": "==0.9.0" + }, + "future": { + "hashes": [ + "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8" + ], + "version": "==0.17.1" + }, "idna": { "hashes": [ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", @@ -44,6 +57,43 @@ "index": "pypi", "version": "==1.2.0" }, + "pygame": { + "hashes": [ + "sha256:06dc92ccfea33b85f209db3d49f99a2a30c88fe9fb80fa2564cee443ece787b5", + "sha256:0919a2ec5fcb0d00518c2a5fa99858ccf22d7fbcc0e12818b317062d11386984", + "sha256:0a8c92e700e0042faefa998fa064616f330201890d6ea1c993eb3ff30ab53e99", + "sha256:220a1048ebb3d11a4d48cc4219ec8f65ca62fcafd255239478677625e8ead2e9", + "sha256:315861d2b8428f7b4d56d2c98d6c1acc18f08c77af4b129211bc036774f64be2", + "sha256:3469e87867832fe5226396626a8a6a9dac9b2e21a7819dd8cd96cf0e08bbcd41", + "sha256:54c19960180626165512d596235d75dc022d38844467cec769a8d8153fd66645", + "sha256:5ba598736ab9716f53dc943a659a9578f62acfe00c0c9c5490f3aca61d078f75", + "sha256:60ddc4f361babb30ff2d554132b1f3296490f3149d6c1c77682213563f59937a", + "sha256:6a49ab8616a9de534f1bf62c98beabf0e0bb0b6ff8917576bba22820bba3fdad", + "sha256:6d4966eeba652df2fd9a757b3fc5b29b578b47b58f991ad714471661ea2141cb", + "sha256:700d1781c999af25d11bfd1f3e158ebb660f72ebccb2040ecafe5069d0b2c0b6", + "sha256:73f4c28e894e76797b8ccaf6eb1205b433efdb803c70f489ebc3db6ac9c097e6", + "sha256:786eca2bea11abd924f3f67eb2483bcb22acff08f28dbdbf67130abe54b23797", + "sha256:7bcf586a1c51a735361ca03561979eea3180de45e6165bcdfa12878b752544af", + "sha256:82a1e93d82c1babceeb278c55012a9f5140e77665d372a6d97ec67786856d254", + "sha256:9e03589bc80a21ae951fca7659a767b7cac668289937e3756c0ab3d753cf6d24", + "sha256:aa8926a4e34fb0943abe1a8bb04a0ad82265341bf20064c0862db0a521100dfc", + "sha256:aa90689b889c417d2ac571ef2bbb5f7e735ae30c7553c60fae7508404f46c101", + "sha256:c9f8cdefee267a2e690bf17d61a8f5670b620f25a981f24781b034363a8eedc9", + "sha256:d9177afb2f46103bfc28a51fbc49ce18987a857e5c934db47b4a7030cb30fbd0", + "sha256:deb0551d4bbfb8131e2463a7fe1943bfcec5beb11acdf9c4bfa27fa5a9758d62", + "sha256:e7edfe57a5972aa9130ce9a186020a0f097e7a8e4c25e292109bdae1432b77f9", + "sha256:f0ad32efb9e26160645d62ba6cf3e5a5828dc4e82e8f41f9badfe7b685b07295" + ], + "version": "==1.9.4" + }, + "pyopengl": { + "hashes": [ + "sha256:2f3e757ded041c0c1e6175a0bb19f6e77f4063c54ad4ae0c8d3ff1a0996822b5", + "sha256:9b47c5c3a094fa518ca88aeed35ae75834d53e4285512c61879f67a48c94ddaf", + "sha256:efa4e39a49b906ccbe66758812ca81ced13a6f26931ab2ba2dba2750c016c0d0" + ], + "version": "==3.1.0" + }, "python-constraint": { "hashes": [ "sha256:501d6f17afe0032dfc6ea6c0f8acc12e44f992733f00e8538961031ef27ccb8e" diff --git a/demo/skewed_nback.py b/demo/skewed_nback.py new file mode 100644 index 0000000..f8ce3be --- /dev/null +++ b/demo/skewed_nback.py @@ -0,0 +1,20 @@ +import expyriment +from skewed_random import SequenceGenerator + +stimuli_list = SequenceGenerator().generate() + +exp = expyriment.control.initialize() +exp.data_variable_names = ["stimulus", "pressed_key", "rt"] + +expyriment.control.start(exp) + +for stimulus in stimuli_list: + target = expyriment.stimuli.TextLine(text=str(stimulus), text_size=200) + exp.clock.wait(500 - expyriment.stimuli.FixCross().present() - target.preload()) + target.present() + pressed_key, rt = exp.keyboard.wait([expyriment.misc.constants.K_LEFT, expyriment.misc.constants.K_RIGHT]) + exp.data.add([stimulus, pressed_key, rt]) + exp.clock.wait(1000 - expyriment.stimuli.BlankScreen().present() - target.unload()) + +expyriment.control.end("Goodbye!", goodbye_delay=1000) + diff --git a/.gitignore b/.gitignore index 6a4df1c..2265696 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,10 @@ *.iws .DS_Store -tmp/ \ No newline at end of file +tmp/ + +demo/data/ +demo/events/ +data/ +events/ +__pycache__ diff --git a/Pipfile b/Pipfile index 23d2206..5703ad7 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,8 @@ requests = "*" python-constraint = "*" Numberjack = "*" +expyriment = "*" +pygame = "==1.9.5.dev0" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 25ca7bf..a61b507 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "8741d50b672e81aecb9c484903354969f4b9e6834a4220355e088e83b03ec6fa" + "sha256": "bacdafb02274e91e6b626d22d4b069ff8c1321beee335721e5163494e68fa35e" }, "pipfile-spec": 6, "requires": { @@ -30,6 +30,19 @@ ], "version": "==3.0.4" }, + "expyriment": { + "hashes": [ + "sha256:2f8d859deaf1ee7a2a906764d6820ddb656a1887601f3831562e419d5e5857c0" + ], + "index": "pypi", + "version": "==0.9.0" + }, + "future": { + "hashes": [ + "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8" + ], + "version": "==0.17.1" + }, "idna": { "hashes": [ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", @@ -44,6 +57,43 @@ "index": "pypi", "version": "==1.2.0" }, + "pygame": { + "hashes": [ + "sha256:06dc92ccfea33b85f209db3d49f99a2a30c88fe9fb80fa2564cee443ece787b5", + "sha256:0919a2ec5fcb0d00518c2a5fa99858ccf22d7fbcc0e12818b317062d11386984", + "sha256:0a8c92e700e0042faefa998fa064616f330201890d6ea1c993eb3ff30ab53e99", + "sha256:220a1048ebb3d11a4d48cc4219ec8f65ca62fcafd255239478677625e8ead2e9", + "sha256:315861d2b8428f7b4d56d2c98d6c1acc18f08c77af4b129211bc036774f64be2", + "sha256:3469e87867832fe5226396626a8a6a9dac9b2e21a7819dd8cd96cf0e08bbcd41", + "sha256:54c19960180626165512d596235d75dc022d38844467cec769a8d8153fd66645", + "sha256:5ba598736ab9716f53dc943a659a9578f62acfe00c0c9c5490f3aca61d078f75", + "sha256:60ddc4f361babb30ff2d554132b1f3296490f3149d6c1c77682213563f59937a", + "sha256:6a49ab8616a9de534f1bf62c98beabf0e0bb0b6ff8917576bba22820bba3fdad", + "sha256:6d4966eeba652df2fd9a757b3fc5b29b578b47b58f991ad714471661ea2141cb", + "sha256:700d1781c999af25d11bfd1f3e158ebb660f72ebccb2040ecafe5069d0b2c0b6", + "sha256:73f4c28e894e76797b8ccaf6eb1205b433efdb803c70f489ebc3db6ac9c097e6", + "sha256:786eca2bea11abd924f3f67eb2483bcb22acff08f28dbdbf67130abe54b23797", + "sha256:7bcf586a1c51a735361ca03561979eea3180de45e6165bcdfa12878b752544af", + "sha256:82a1e93d82c1babceeb278c55012a9f5140e77665d372a6d97ec67786856d254", + "sha256:9e03589bc80a21ae951fca7659a767b7cac668289937e3756c0ab3d753cf6d24", + "sha256:aa8926a4e34fb0943abe1a8bb04a0ad82265341bf20064c0862db0a521100dfc", + "sha256:aa90689b889c417d2ac571ef2bbb5f7e735ae30c7553c60fae7508404f46c101", + "sha256:c9f8cdefee267a2e690bf17d61a8f5670b620f25a981f24781b034363a8eedc9", + "sha256:d9177afb2f46103bfc28a51fbc49ce18987a857e5c934db47b4a7030cb30fbd0", + "sha256:deb0551d4bbfb8131e2463a7fe1943bfcec5beb11acdf9c4bfa27fa5a9758d62", + "sha256:e7edfe57a5972aa9130ce9a186020a0f097e7a8e4c25e292109bdae1432b77f9", + "sha256:f0ad32efb9e26160645d62ba6cf3e5a5828dc4e82e8f41f9badfe7b685b07295" + ], + "version": "==1.9.4" + }, + "pyopengl": { + "hashes": [ + "sha256:2f3e757ded041c0c1e6175a0bb19f6e77f4063c54ad4ae0c8d3ff1a0996822b5", + "sha256:9b47c5c3a094fa518ca88aeed35ae75834d53e4285512c61879f67a48c94ddaf", + "sha256:efa4e39a49b906ccbe66758812ca81ced13a6f26931ab2ba2dba2750c016c0d0" + ], + "version": "==3.1.0" + }, "python-constraint": { "hashes": [ "sha256:501d6f17afe0032dfc6ea6c0f8acc12e44f992733f00e8538961031ef27ccb8e" diff --git a/demo/skewed_nback.py b/demo/skewed_nback.py new file mode 100644 index 0000000..f8ce3be --- /dev/null +++ b/demo/skewed_nback.py @@ -0,0 +1,20 @@ +import expyriment +from skewed_random import SequenceGenerator + +stimuli_list = SequenceGenerator().generate() + +exp = expyriment.control.initialize() +exp.data_variable_names = ["stimulus", "pressed_key", "rt"] + +expyriment.control.start(exp) + +for stimulus in stimuli_list: + target = expyriment.stimuli.TextLine(text=str(stimulus), text_size=200) + exp.clock.wait(500 - expyriment.stimuli.FixCross().present() - target.preload()) + target.present() + pressed_key, rt = exp.keyboard.wait([expyriment.misc.constants.K_LEFT, expyriment.misc.constants.K_RIGHT]) + exp.data.add([stimulus, pressed_key, rt]) + exp.clock.wait(1000 - expyriment.stimuli.BlankScreen().present() - target.unload()) + +expyriment.control.end("Goodbye!", goodbye_delay=1000) + diff --git a/skewed_random.py b/skewed_random.py new file mode 100644 index 0000000..a6e4ea7 --- /dev/null +++ b/skewed_random.py @@ -0,0 +1,51 @@ +import logging +import random + + +class SequenceGenerator: + """Generates random sequence of stimuli for the n-back task. Implementation is based on Ralph (2014).""" + + seq = [] + + def __init__(self, + N=2, + trials=10, # Number of total trials + alphabet=['A', 'B', 'C', 'D', 'E', 'F'], + T=2, # Number of targets + L1=1, # Number of lures (foil) similar to the (N+1)-back + L2=1 # Number of lures (foil) similar to the (N-1)-back + ): + self.N, self.alphabet, self.trials, self.T, self.L1, self.L2 = N, alphabet, trials, T, L1, L2 + self.D = trials - T - L1 - L2 + + def generate(self) -> list: + trial = 1 + self.seq = [] + while trial <= self.trials: + self.seq += self.random_stimulus(trial) + trial += 1 + return self.seq + + def random_stimulus(self, trial): + rnd = random.randint(1, self.trials - trial + 1) + T, L1, L2 = self.T, self.L1, self.L2 + if rnd <= T and len(self.seq) >= self.N: + self.T -= 1 + return self.seq[-self.N] + elif T < rnd <= T + L1 and len(self.seq) >= self.N+1: + self.L1 -= 1 + return self.seq[-(self.N+1)] + elif T + L1 < rnd <= T + L1 + L2 and len(self.seq) >= self.N-1: + self.L2 -= 1 + return self.seq[-(self.N-1)] + + # distract + self.D -= 1 + alphabet = [item for item in self.alphabet if item not in self.seq[-self.N-1:-self.N+1]] + return random.choice(alphabet) + + +if __name__ == '__main__': + generator = SequenceGenerator() + seq = generator.generate() + print('Skewed Random Sequence: %s' % ''.join(seq)) diff --git a/.gitignore b/.gitignore index 6a4df1c..2265696 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,10 @@ *.iws .DS_Store -tmp/ \ No newline at end of file +tmp/ + +demo/data/ +demo/events/ +data/ +events/ +__pycache__ diff --git a/Pipfile b/Pipfile index 23d2206..5703ad7 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,8 @@ requests = "*" python-constraint = "*" Numberjack = "*" +expyriment = "*" +pygame = "==1.9.5.dev0" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 25ca7bf..a61b507 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "8741d50b672e81aecb9c484903354969f4b9e6834a4220355e088e83b03ec6fa" + "sha256": "bacdafb02274e91e6b626d22d4b069ff8c1321beee335721e5163494e68fa35e" }, "pipfile-spec": 6, "requires": { @@ -30,6 +30,19 @@ ], "version": "==3.0.4" }, + "expyriment": { + "hashes": [ + "sha256:2f8d859deaf1ee7a2a906764d6820ddb656a1887601f3831562e419d5e5857c0" + ], + "index": "pypi", + "version": "==0.9.0" + }, + "future": { + "hashes": [ + "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8" + ], + "version": "==0.17.1" + }, "idna": { "hashes": [ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", @@ -44,6 +57,43 @@ "index": "pypi", "version": "==1.2.0" }, + "pygame": { + "hashes": [ + "sha256:06dc92ccfea33b85f209db3d49f99a2a30c88fe9fb80fa2564cee443ece787b5", + "sha256:0919a2ec5fcb0d00518c2a5fa99858ccf22d7fbcc0e12818b317062d11386984", + "sha256:0a8c92e700e0042faefa998fa064616f330201890d6ea1c993eb3ff30ab53e99", + "sha256:220a1048ebb3d11a4d48cc4219ec8f65ca62fcafd255239478677625e8ead2e9", + "sha256:315861d2b8428f7b4d56d2c98d6c1acc18f08c77af4b129211bc036774f64be2", + "sha256:3469e87867832fe5226396626a8a6a9dac9b2e21a7819dd8cd96cf0e08bbcd41", + "sha256:54c19960180626165512d596235d75dc022d38844467cec769a8d8153fd66645", + "sha256:5ba598736ab9716f53dc943a659a9578f62acfe00c0c9c5490f3aca61d078f75", + "sha256:60ddc4f361babb30ff2d554132b1f3296490f3149d6c1c77682213563f59937a", + "sha256:6a49ab8616a9de534f1bf62c98beabf0e0bb0b6ff8917576bba22820bba3fdad", + "sha256:6d4966eeba652df2fd9a757b3fc5b29b578b47b58f991ad714471661ea2141cb", + "sha256:700d1781c999af25d11bfd1f3e158ebb660f72ebccb2040ecafe5069d0b2c0b6", + "sha256:73f4c28e894e76797b8ccaf6eb1205b433efdb803c70f489ebc3db6ac9c097e6", + "sha256:786eca2bea11abd924f3f67eb2483bcb22acff08f28dbdbf67130abe54b23797", + "sha256:7bcf586a1c51a735361ca03561979eea3180de45e6165bcdfa12878b752544af", + "sha256:82a1e93d82c1babceeb278c55012a9f5140e77665d372a6d97ec67786856d254", + "sha256:9e03589bc80a21ae951fca7659a767b7cac668289937e3756c0ab3d753cf6d24", + "sha256:aa8926a4e34fb0943abe1a8bb04a0ad82265341bf20064c0862db0a521100dfc", + "sha256:aa90689b889c417d2ac571ef2bbb5f7e735ae30c7553c60fae7508404f46c101", + "sha256:c9f8cdefee267a2e690bf17d61a8f5670b620f25a981f24781b034363a8eedc9", + "sha256:d9177afb2f46103bfc28a51fbc49ce18987a857e5c934db47b4a7030cb30fbd0", + "sha256:deb0551d4bbfb8131e2463a7fe1943bfcec5beb11acdf9c4bfa27fa5a9758d62", + "sha256:e7edfe57a5972aa9130ce9a186020a0f097e7a8e4c25e292109bdae1432b77f9", + "sha256:f0ad32efb9e26160645d62ba6cf3e5a5828dc4e82e8f41f9badfe7b685b07295" + ], + "version": "==1.9.4" + }, + "pyopengl": { + "hashes": [ + "sha256:2f3e757ded041c0c1e6175a0bb19f6e77f4063c54ad4ae0c8d3ff1a0996822b5", + "sha256:9b47c5c3a094fa518ca88aeed35ae75834d53e4285512c61879f67a48c94ddaf", + "sha256:efa4e39a49b906ccbe66758812ca81ced13a6f26931ab2ba2dba2750c016c0d0" + ], + "version": "==3.1.0" + }, "python-constraint": { "hashes": [ "sha256:501d6f17afe0032dfc6ea6c0f8acc12e44f992733f00e8538961031ef27ccb8e" diff --git a/demo/skewed_nback.py b/demo/skewed_nback.py new file mode 100644 index 0000000..f8ce3be --- /dev/null +++ b/demo/skewed_nback.py @@ -0,0 +1,20 @@ +import expyriment +from skewed_random import SequenceGenerator + +stimuli_list = SequenceGenerator().generate() + +exp = expyriment.control.initialize() +exp.data_variable_names = ["stimulus", "pressed_key", "rt"] + +expyriment.control.start(exp) + +for stimulus in stimuli_list: + target = expyriment.stimuli.TextLine(text=str(stimulus), text_size=200) + exp.clock.wait(500 - expyriment.stimuli.FixCross().present() - target.preload()) + target.present() + pressed_key, rt = exp.keyboard.wait([expyriment.misc.constants.K_LEFT, expyriment.misc.constants.K_RIGHT]) + exp.data.add([stimulus, pressed_key, rt]) + exp.clock.wait(1000 - expyriment.stimuli.BlankScreen().present() - target.unload()) + +expyriment.control.end("Goodbye!", goodbye_delay=1000) + diff --git a/skewed_random.py b/skewed_random.py new file mode 100644 index 0000000..a6e4ea7 --- /dev/null +++ b/skewed_random.py @@ -0,0 +1,51 @@ +import logging +import random + + +class SequenceGenerator: + """Generates random sequence of stimuli for the n-back task. Implementation is based on Ralph (2014).""" + + seq = [] + + def __init__(self, + N=2, + trials=10, # Number of total trials + alphabet=['A', 'B', 'C', 'D', 'E', 'F'], + T=2, # Number of targets + L1=1, # Number of lures (foil) similar to the (N+1)-back + L2=1 # Number of lures (foil) similar to the (N-1)-back + ): + self.N, self.alphabet, self.trials, self.T, self.L1, self.L2 = N, alphabet, trials, T, L1, L2 + self.D = trials - T - L1 - L2 + + def generate(self) -> list: + trial = 1 + self.seq = [] + while trial <= self.trials: + self.seq += self.random_stimulus(trial) + trial += 1 + return self.seq + + def random_stimulus(self, trial): + rnd = random.randint(1, self.trials - trial + 1) + T, L1, L2 = self.T, self.L1, self.L2 + if rnd <= T and len(self.seq) >= self.N: + self.T -= 1 + return self.seq[-self.N] + elif T < rnd <= T + L1 and len(self.seq) >= self.N+1: + self.L1 -= 1 + return self.seq[-(self.N+1)] + elif T + L1 < rnd <= T + L1 + L2 and len(self.seq) >= self.N-1: + self.L2 -= 1 + return self.seq[-(self.N-1)] + + # distract + self.D -= 1 + alphabet = [item for item in self.alphabet if item not in self.seq[-self.N-1:-self.N+1]] + return random.choice(alphabet) + + +if __name__ == '__main__': + generator = SequenceGenerator() + seq = generator.generate() + print('Skewed Random Sequence: %s' % ''.join(seq)) diff --git a/skewed_random_generator.py b/skewed_random_generator.py deleted file mode 100644 index 5cae6e8..0000000 --- a/skewed_random_generator.py +++ /dev/null @@ -1,50 +0,0 @@ -import logging -import random - -class SkewedRandomGenerator: - """Generates random sequence of stimuli for the n-back task. Implementation is based on Ralph (2014).""" - - seq = [] - - def __init__(self, - N = 2, - trials = 100, # Number of total trials - alphabet=['A','B','C','D','E','F'], - T = 20, # Number of targets - L1 = 10, # Number of lures (foil) similar to the (N+1)-back - L2 = 10 # Number of lures (foil) similar to the (N-1)-back - ): - self.N, self.alphabet, self.trials, self.T, self.L1, self.L2 = N, alphabet, trials, T, L1, L2 - self.D = trials - T - L1 - L2 - - def generate(self) -> list: - trial = 1 - self.seq = [] - while trial <= self.trials: - self.seq += self.random_stimulus(trial) - trial += 1 - return self.seq - - def random_stimulus(self, trial): - rnd = random.randint(1, self.trials - trial + 1) - T, L1, L2 = self.T, self.L1, self.L2 - if rnd <= T and len(self.seq) >= self.N: - self.T -= 1 - return self.seq[-self.N] - elif T < rnd <= T + L1 and len(self.seq) >= self.N+1: - self.L1 -= 1 - return self.seq[-(self.N+1)] - elif T + L1 < rnd <= T + L1 + L2 and len(self.seq) >= self.N-1: - self.L2 -= 1 - return self.seq[-(self.N-1)] - - # distract - self.D -= 1 - alphabet = [item for item in self.alphabet if item not in self.seq[-self.N-1:-self.N+1]] - return random.choice(alphabet) - - -if __name__ == '__main__': - generator = SkewedRandomGenerator() - seq = generator.generate() - print('Skewed Random Sequence: %s' % ''.join(seq))