Example Experiments

Here you can find some code examples to see Expyriment in action. All examples are fully working experiments.

Simon task

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()

Word fragment completion task

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()

Number classification task

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 * (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)

Really short example

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)

Data preprocessing

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")