Here you can find some code examples to see Expyriment in action. All examples are fully working experiments.
An experiment to asses a spatial stimulus-response compatibility effect (see wikipedia).
#!/usr/bin/env python
"""
A simple behavioural task to asses a Simon effect.
See also:
http://en.wikipedia.org/wiki/Simon_effect
"""
from expyriment import design, control, stimuli, io, misc
# Create and initialize an Experiment
exp = design.Experiment("Simon Task")
control.initialize(exp)
# Define and preload standard stimuli
fixcross = stimuli.FixCross()
fixcross.preload()
# Create IO
#response_device = io.EventButtonBox(io.SerialPort("/dev/ttyS1"))
response_device = exp.keyboard
# Create design
for task in ["left key for green", "left key for red"]:
b = design.Block()
b.set_factor("Response", task)
for where in [["left", -300], ["right", 300]]:
for what in [["red", misc.constants.C_RED],
["green", misc.constants.C_GREEN]]:
t = design.Trial()
t.set_factor("Position", where[0])
t.set_factor("Colour", what[0])
s = stimuli.Rectangle([50, 50], position=[where[1], 0],
colour=what[1])
t.add_stimulus(s)
b.add_trial(t, copies=20)
b.shuffle_trials()
exp.add_block(b)
exp.add_bws_factor("ResponseMapping", [1, 2])
exp.data_variable_names = ["Position", "Button", "RT"]
# Start Experiment
control.start()
exp.permute_blocks(misc.constants.P_BALANCED_LATIN_SQUARE)
for block in exp.blocks:
stimuli.TextScreen("Instructions", block.get_factor("Response")).present()
response_device.wait()
for trial in block.trials:
fixcross.present()
exp.clock.wait(1000 - trial.stimuli[0].preload())
trial.stimuli[0].present()
button, rt = response_device.wait()
exp.data.add([trial.get_factor("Position"), button, rt])
# End Experiment
control.end()
Task as used for instance in Weldon, 1991. The script read in a stimulus list file (demo stimulus list).
#!/usr/bin/env python
"""
Word fragment completion task as used in the study of Weldon (1991).
Stimulus list: "word_fragment_completion_stimuluslist.csv"!
Weldon, M. S. (1991). Mechanisms underlying priming on
perceptual tests. Journal of Experimental Psychology: Learning, Memory, and
Cognition, 17, 526-541.
"""
import csv
from expyriment import design, control, stimuli, io, misc
control.set_develop_mode(True)
#### read in wordlist file and make design
exp = design.Experiment("word fragment completion test")
block = design.Block()
with open("word_fragment_completion_stimuluslist.csv", "rb") as f:
reader = csv.reader(f)
for row in reader:
trial = design.Trial()
trial.set_factor("word", row[0].strip())
trial.set_factor("fragment", row[1].strip())
block.add_trial(trial)
block.shuffle_trials()
exp.add_block(block)
exp.add_data_variable_names(["word", "fragment", "RT", "RT2", "answer"])
control.initialize(exp)
#prepare some stimuli
fixcross = stimuli.FixCross(line_width=1)
fixcross.preload()
blank = stimuli.BlankScreen()
blank.preload()
txt_input = io.TextInput("")
control.start(exp)
#run experiment
for trial in exp.blocks[0].trials:
#present blank inter-trial-screen and prepare stimulus
blank.present()
fragment = ""
for c in trial.get_factor("fragment").upper():
fragment += c + " "
target = stimuli.TextLine(fragment.strip())
target.preload()
exp.clock.wait(1000)
#present fixcross
fixcross.present()
exp.clock.wait(500)
#present target
target.present()
key, rt = exp.keyboard.wait(misc.constants.K_SPACE)
#ask response
exp.clock.reset_stopwatch()
answer = txt_input.get()
rt2 = exp.clock.stopwatch_time
#process answer and save data
blank.present()
answer = answer.strip()
exp.data.add([trial.get_factor("word"), trial.get_factor("fragment"),
rt, rt2, answer])
target.unload()
control.end()
A full experiment to access SNARC and SNARC-like effects in a number and a letter classification task (e.g., Gevers, Reynvoer, & Fias (2003)) with two response mappings, error feedback and between-subject factors.
#!/usr/bin/env python
"""
A parity judgment task to assess the SNARC effect.
See e.g.:
Gevers, W., Reynvoet, B., & Fias, W. (2003). The mental representation of
ordinal sequences is spatially organized. Cognition, 87(3), B87-95.
"""
from expyriment import design, control, stimuli
from expyriment.misc import constants
control.set_develop_mode(False)
########### DESIGN ####################
exp = design.Experiment(name="SNARC")
# Design: 2 response mappings x 8 stimuli x 10 repetitions
for response_mapping in ["left_odd", "right_odd"]:
block = design.Block()
block.set_factor("mapping", response_mapping)
#add trials to block
for digit in [1, 2, 3, 4, 6, 7, 8, 9]:
trial = design.Trial()
trial.set_factor("digit", digit)
block.add_trial(trial, copies=10)
block.shuffle_trials()
exp.add_block(block)
exp.add_experiment_info("This a just a SNARC experiment.")
#add between subject factors
exp.add_bws_factor('mapping_order', ['left_odd_first', 'right_odd_first'])
#prepare data output
exp.data_variable_names = ["block", "mapping", "trial", "digit", "ISI",
"btn", "RT", "error"]
#set further variables
t_fixcross = 500
min_max_ISI = [200, 750] # [min, max] inter_stimulus interval
ITI = 1000
t_error_screen = 1000
no_training_trials = 10
######### INITIALIZE ##############
control.initialize(exp)
# Prepare and preload some stimuli
blankscreen = stimuli.BlankScreen()
blankscreen.preload()
fixcross = stimuli.FixCross()
fixcross.preload()
error_beep = stimuli.Tone(duration=200, frequency=2000)
error_beep.preload()
#define a trial
def run_trial(cnt, trial):
# present Fixation cross and prepare trial in the meantime
fixcross.present()
exp.clock.reset_stopwatch()
ISI = design.randomize.rand_int(min_max_ISI[0], min_max_ISI[1])
digit = trial.get_factor("digit")
target = stimuli.TextLine(text=str(digit), text_size=60)
target.preload()
exp.clock.wait(t_fixcross - exp.clock.stopwatch_time)
#present blankscreen for a random interval
blankscreen.present()
exp.clock.wait(ISI)
# Present target & record button response
target.present()
btn, rt = exp.keyboard.wait([constants.K_LEFT, constants.K_RIGHT])
#Error feedback if required
if block.get_factor("mapping") == "left_odd":
error = (digit % 2 == 0 and btn == constants.K_LEFT) or \
(digit % 2 == 1 and btn == constants.K_RIGHT)
else:
error = (digit % 2 == 1 and btn == constants.K_LEFT) or \
(digit % 2 == 0 and btn == constants.K_RIGHT)
if error:
error_beep.present()
#write data and clean up while inter-trial-interval
blankscreen.present()
exp.clock.reset_stopwatch()
exp.data.add([block.id, block.get_factor("mapping"),
cnt, target.text, ISI,
btn, rt, int(error)])
exp.data.save()
target.unload()
exp.clock.wait(ITI - exp.clock.stopwatch_time)
######### START ##############
control.start(exp)
# permute block order across subjects
if exp.get_permuted_bws_factor_condition('mapping_order') == "right_odd_first":
exp.swap_blocks(0, 1)
# Run the actual experiment
for block in exp.blocks:
# Show instruction screen
if block.get_factor("mapping") == "left_odd":
instruction = "Press LEFT arrow key for ODD\n" + \
"and RIGHT arrow key for EVEN numbers."
else:
instruction = "Press RIGHT arrow key for ODD\n" + \
"and LEFT arrow key for EVEN numbers."
stimuli.TextScreen("Indicate the parity of the numbers", instruction +
"\n\nPress space bar to start training.").present()
exp.keyboard.wait(constants.K_SPACE)
#training trials
for cnt in range(0, no_training_trials):
trial = block.get_random_trial()
run_trial(-1 * cnt, trial)#training trails has negative trial numbers
# Show instruction screen
stimuli.TextScreen("Attention!", instruction +
"\n\nThe experimental block starts now.").present()
exp.keyboard.wait(constants.K_SPACE)
# experimental trials
for cnt, trial in enumerate(block.trials):
run_trial(cnt, trial)
####### END EXPERIMENT ########
control.end(goodbye_text="Thank you very much for participating in our experiment",
goodbye_delay=5000)
Expyriment is efficient!. See here a very short example of an functioning experiment in less than 20 lines of pure code.
#!/usr/bin/env python
"""
A very short example experiment in 16 lines of pure code.
Participants have to indicate the parity of digits by pressing
the left arrow key for odd and the right arrow key for even numbers.
"""
from expyriment import control, stimuli, design, misc
digit_list = [1, 2, 3, 4, 6, 7, 8, 9]*12
design.randomize.shuffle_list(digit_list)
exp = control.initialize()
exp.data_variable_names = ["digit", "btn", "rt", "error"]
control.start(exp)
for digit in digit_list:
target = stimuli.TextLine(text=str(digit), text_size=80)
exp.clock.wait(500 - stimuli.FixCross().present() - target.preload())
target.present()
button, rt = exp.keyboard.wait([misc.constants.K_LEFT, misc.constants.K_RIGHT])
error = (button == misc.constants.K_LEFT) == digit%2
if error: stimuli.Tone(duration=200, frequency=2000).play()
exp.data.add([digit, button, rt, int(error)])
exp.clock.wait(1000 - stimuli.BlankScreen().present() - target.unload())
control.end(goodbye_text="Thank you very much...", goodbye_delay=2000)
Preprocessing the data of the SNARC experiment for further statistical analysis.
#!/usr/bin/env python
"""
Example analysis script for snarc_experiment.py
The current script produces two files for different analysis of the SNARC
effect (ANOVA vs. slopes analysis) using mean and median RTs
"""
from expyriment.misc import data_preprocessing, constants
agg = data_preprocessing.Aggregator(data_folder="./data/",
file_name="snarc_experiment")
agg.set_subject_variables(["mapping_order"])
agg.set_computed_variables(["parity = digit % 2", #0:odd, 1:even
"size = digit > 5", #0:small, 1:large
"space = btn == {0}".format(constants.K_RIGHT) #0:left, 1:right
])
# RTs: space x size
agg.set_exclusions(["RT > 1000", "RT < 200", "error == 1", "trial<0"])
agg.set_dependent_variables(["mean(RT)"])
agg.set_independent_variables(["size", "space"])
print agg
agg.aggregate(output_file="rt_size_space.csv")
# RTs: slopes analysis
agg.set_independent_variables(["digit"])
agg.aggregate(output_file="rt_digits.csv")