def test_generate_derivations_within_trial():
    assert DerivationProcessor.generate_derivations(blk) == [
        Derivation(4, [[0, 2], [1, 3]], con_factor),
        Derivation(5, [[0, 3], [1, 2]], con_factor)
    ]

    integer = Factor("integer", ["1", "2"])
    numeral = Factor("numeral", ["I", "II"])
    text = Factor("text", ["one", "two"])

    twoConLevel = DerivedLevel("twoCon",
                               WithinTrial(two_con, [integer, numeral, text]))
    twoNotConLevel = DerivedLevel(
        "twoNotCon", WithinTrial(two_not_con, [integer, numeral, text]))
    two_con_factor = Factor("twoCon?", [twoConLevel, twoNotConLevel])

    one_two_design = [integer, numeral, text, two_con_factor]
    one_two_crossing = [integer, numeral, text]

    assert DerivationProcessor.generate_derivations(
        fully_cross_block(one_two_design, one_two_crossing, [])) == [
            Derivation(6,
                       [[0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5],
                        [1, 3, 4]], two_con_factor),
            Derivation(7, [[0, 2, 4], [1, 3, 5]], two_con_factor)
        ]
Exemplo n.º 2
0
def test_fully_cross_block_crossing_size_with_overlapping_exclude():
    # How about with two overlapping exclude constraints? Initial crossing size
    # should be 3 x 3 = 9.
    # Excluding congruent pairs will reduce that to 9 - 3 = 6
    # Then excluding red and green on top of that should make it 5.
    color = Factor("color", ["red", "blue", "green"])
    text = Factor("text", ["red", "blue", "green"])

    congruent_factor = Factor("congruent?", [
        DerivedLevel("congruent", WithinTrial(op.eq, [color, text])),
        DerivedLevel("incongruent", WithinTrial(op.ne, [color, text])),
    ])

    def illegal(color, text):
        return (color == "red" and text == "green") or color == text

    def legal(color, text):
        return not illegal(color, text)

    legal_factor = Factor("legal", [
        DerivedLevel("yes", WithinTrial(legal, [color, text])),
        DerivedLevel("no", WithinTrial(illegal, [color, text]))
    ])

    assert FullyCrossBlock(
        [color, text, congruent_factor, legal_factor],
        [[color, text]],
        [
            Exclude(congruent_factor,
                    get_level_from_name(congruent_factor,
                                        "congruent")),  # Excludes 3
            Exclude(legal_factor, get_level_from_name(legal_factor, "no"))
        ],  # Exludes 4, but 3 were already excluded
        require_complete_crossing=False).crossing_size() == 5
Exemplo n.º 3
0
def test_derived_level_validation():
    DerivedLevel(42, WithinTrial(op.eq, [color, text]))
    DerivedLevel("name", WithinTrial(lambda x: x, [color]))

    # Invalid Window
    with pytest.raises(ValueError):
        DerivedLevel("name", 42)
Exemplo n.º 4
0
def __get_response_transition() -> Factor:
    color = Factor("color", ["red", "blue", "green"])
    motion = Factor("motion", ["up", "down"])
    task = Factor("task", ["color", "motion"])

    # Response Definition
    def response_left(task, color, motion):
        return (task == "color"  and color  == "red") or \
            (task == "motion" and motion == "up")

    def response_right(task, color, motion):
        return not response_left(task, color, motion)

    response = Factor("response", [
        DerivedLevel("left", WithinTrial(response_left,
                                         [task, color, motion])),
        DerivedLevel("right", WithinTrial(response_right,
                                          [task, color, motion]))
    ])

    return Factor("response transition", [
        DerivedLevel(
            "repeat",
            Transition(lambda responses: responses[0] == responses[1],
                       [response])),
        DerivedLevel(
            "switch",
            Transition(lambda responses: responses[0] != responses[1],
                       [response]))
    ])
Exemplo n.º 5
0
def test_base_window_validation():
    # Nonfactor argument
    with pytest.raises(ValueError):
        WithinTrial(op.eq, [42])

    # Duplicated factors
    with pytest.raises(ValueError):
        DerivedLevel("name", WithinTrial(lambda x, y: x, [color, color]))
def test_generate_derivations_should_raise_error_if_some_factor_matches_multiple_levels(
):
    local_con_factor = Factor("congruent?", [
        DerivedLevel("con", WithinTrial(op.eq, [color, text])),
        DerivedLevel("inc", WithinTrial(op.eq, [color, text]))
    ])

    with pytest.raises(ValueError):
        fully_cross_block([color, text, local_con_factor], [color, text], [])
def test_generate_derivations_should_produce_warning_if_some_level_is_unreachable(capsys):
    local_con_factor = Factor("congruent?", [
        DerivedLevel("con", WithinTrial(op.eq, [color, text])),
        DerivedLevel("inc", WithinTrial(op.ne, [color, text])),
        DerivedLevel("dum", WithinTrial(lambda c, t: c=='green', [color, text]))
    ])
    fully_cross_block([color, text, local_con_factor],
                      [color, text],
                      [])
    assert capsys.readouterr().out == "WARNING: There is no assignment that matches factor congruent? with level dum.\n"
Exemplo n.º 8
0
def __build_stroop_block(color_count):
    color = Factor("color", color_list[:color_count])
    text = Factor("text", color_list[:color_count])

    congruent = Factor("congruent?", [
        DerivedLevel("yes", WithinTrial(op.eq, [color, text])),
        DerivedLevel("no",  WithinTrial(op.ne, [color, text]))
    ])

    constraints = [AtMostKInARow(1, ("congruent?", "yes"))]

    return fully_cross_block([color, text, congruent], [color, text], constraints)
Exemplo n.º 9
0
def test_derived_level_validation():
    # Non-str name
    with pytest.raises(ValueError):
        DerivedLevel(42, WithinTrial(op.eq, [color, text]))

    # Invalid Window
    with pytest.raises(ValueError):
        DerivedLevel("name", 42)

    # Repeated factors in argument list.
    with pytest.raises(ValueError):
        DerivedLevel("name", WithinTrial(lambda x: x, [color, color]))
def test_generate_derivations_should_raise_error_if_fn_doesnt_return_a_boolean():
    def local_eq(color, text):
            color == text # Notice the missing return stmt

    local_con_factor = Factor("congruent?", [
        DerivedLevel("con", WithinTrial(local_eq, [color, text])),
        DerivedLevel("inc", WithinTrial(lambda c, t: not local_eq(c, t), [color, text]))
    ])

    with pytest.raises(ValueError):
        fully_cross_block([color, text, local_con_factor],
                          [color, text],
                          [])
def test_generate_sample_basic_stroop_uneven_colors(sequence_number, expected_solution):
    text = Factor("text", ["red", "blue", "green"])
    congruency = Factor("congruency", [
        DerivedLevel("congruent",   WithinTrial(op.eq, [color, text])),
        DerivedLevel("incongruent", WithinTrial(op.ne, [color, text]))
    ])

    block = fully_cross_block([color, text, congruency],
                              [color, congruency],
                              [])
    enumerator = UCSolutionEnumerator(block)
    print(enumerator.generate_sample(sequence_number))
    assert enumerator.generate_sample(sequence_number) == expected_solution
Exemplo n.º 12
0
def test_factor_validation():
    Factor("factor name", ["level 1", "level 2"])
    Factor("name", [1, 2])

    # Duplicated name
    with pytest.raises(ValueError):
        Factor("name", ["a", "b", "a"])
    with pytest.raises(ValueError):
        Factor("name", [
            DerivedLevel("a", WithinTrial(op.eq, [color, text])),
            ElseLevel("a")
        ])

    # Non-string name
    with pytest.raises(ValueError):
        Factor(56, ["level "])

    # Non-list levels
    with pytest.raises(TypeError):
        Factor("name", 42)

    # Empty list
    with pytest.raises(ValueError):
        Factor("name", [])

    # Valid level types, but not uniform.
    with pytest.raises(ValueError):
        Factor("name", ["level1", con_level])

    # Derived levels with non-uniform window types
    with pytest.raises(ValueError):
        Factor("name", [
            con_level,
            DerivedLevel("other", WithinTrial(lambda color: color, [color]))
        ])

    # Derived levels with different window arguments
    with pytest.raises(ValueError):
        Factor("name", [
            con_level,
            DerivedLevel(
                "other",
                Transition(lambda colors: colors[0] == colors[1], [color]))
        ])
Exemplo n.º 13
0
def test_derived_level_get_dependent_cross_product():
    assert [((tup[0][0].factor_name, tup[0][1].external_name),
             (tup[1][0].factor_name, tup[1][1].external_name))
            for tup in con_level.get_dependent_cross_product()
            ] == [(('color', 'red'), ('text', 'red')),
                  (('color', 'red'), ('text', 'blue')),
                  (('color', 'blue'), ('text', 'red')),
                  (('color', 'blue'), ('text', 'blue'))]

    integer = Factor("integer", ["1", "2"])
    numeral = Factor("numeral", ["I", "II"])
    text = Factor("text", ["one", "two"])
    two_con_level = DerivedLevel(
        "twoCon", WithinTrial(lambda x: x, [integer, numeral, text]))
    assert [((tup[0][0].factor_name, tup[0][1].external_name),
             (tup[1][0].factor_name, tup[1][1].external_name),
             (tup[2][0].factor_name, tup[2][1].external_name))
            for tup in two_con_level.get_dependent_cross_product()
            ] == [(('integer', '1'), ('numeral', 'I'), ('text', 'one')),
                  (('integer', '1'), ('numeral', 'I'), ('text', 'two')),
                  (('integer', '1'), ('numeral', 'II'), ('text', 'one')),
                  (('integer', '1'), ('numeral', 'II'), ('text', 'two')),
                  (('integer', '2'), ('numeral', 'I'), ('text', 'one')),
                  (('integer', '2'), ('numeral', 'I'), ('text', 'two')),
                  (('integer', '2'), ('numeral', 'II'), ('text', 'one')),
                  (('integer', '2'), ('numeral', 'II'), ('text', 'two'))]

    mixed_level = DerivedLevel(
        "mixed",
        WithinTrial(lambda x: x, [
            Factor("color", ["red", "blue", "green"]),
            Factor("boolean", ["true", "false"])
        ]))
    assert [((tup[0][0].factor_name, tup[0][1].external_name),
             (tup[1][0].factor_name, tup[1][1].external_name))
            for tup in mixed_level.get_dependent_cross_product()
            ] == [(('color', 'red'), ('boolean', 'true')),
                  (('color', 'red'), ('boolean', 'false')),
                  (('color', 'blue'), ('boolean', 'true')),
                  (('color', 'blue'), ('boolean', 'false')),
                  (('color', 'green'), ('boolean', 'true')),
                  (('color', 'green'), ('boolean', 'false'))]
def test_shift_window():
    assert DerivationProcessor.shift_window([[0, 0], [1, 1]],
                                            WithinTrial(lambda x: x, None),
                                            0) == [[0, 0], [1, 1]]
    assert DerivationProcessor.shift_window([[0, 0], [1, 1]],
                                            Transition(lambda x: x, None),
                                            4) == [[0, 4], [1, 5]]
    assert DerivationProcessor.shift_window([[0, 2, 4], [1, 3, 5]],
                                            Window(lambda x: x, [1, 2], 2, 3),
                                            6) == [[0, 8, 16], [1, 9, 17]]
    assert DerivationProcessor.shift_window([[1, 1, 1, 1], [2, 2, 2, 2]], Window(lambda x: x, [1, 2], 2, 4), 10) == \
        [[1, 11, 21, 31], [2, 12, 22, 32]]
Exemplo n.º 15
0
def test_exclude_with_reduced_crossing():
    color = Factor("color", ["red", "blue", "green"])
    text = Factor("text", ["red", "blue"])

    def illegal_stimulus(color, text):
        return color == "green" and text == "blue"

    def legal_stimulus(color, text):
        return not illegal_stimulus(color, text)

    stimulus_configuration = Factor("stimulus configuration", [
        DerivedLevel("legal", WithinTrial(legal_stimulus, [color, text])),
        DerivedLevel("illegal", WithinTrial(illegal_stimulus, [color, text]))
    ])

    c = Exclude(stimulus_configuration,
                get_level_from_name(stimulus_configuration, "illegal"))
    block = fully_cross_block([color, text, stimulus_configuration],
                              [color, text], [c],
                              require_complete_crossing=False)

    backend_request = BackendRequest(0)
    c.apply(block, backend_request)
    assert backend_request.cnfs == [And([-7, -14, -21, -28, -35])]
Exemplo n.º 16
0
                             deviantMovementObject):
    return (deviantColorObject != deviantOrientationObject) and (
        deviantColorObject != deviantMovementObject) and (
            deviantOrientationObject != deviantMovementObject)


def illegalObjectConfiguration(deviantColorObject, deviantOrientationObject,
                               deviantMovementObject):
    return not legalObjectConfiguration(
        deviantColorObject, deviantOrientationObject, deviantMovementObject)


illegalLevel = DerivedLevel(
    "illegal",
    WithinTrial(
        illegalObjectConfiguration,
        [deviantColorObject, deviantOrientationObject, deviantMovementObject]))
legalLevel = DerivedLevel(
    "legal",
    WithinTrial(
        legalObjectConfiguration,
        [deviantColorObject, deviantOrientationObject, deviantMovementObject]))

objectConfiguration = Factor("object configuration",
                             [illegalLevel, legalLevel])

# DEFINE TASK AND TASK TRANSITION

task = Factor("task", ["color task", "movement task", "orientation task"])

Exemplo n.º 17
0
# DEFINE STIMULUS FACTORS

colorCoherence      = Factor("color coherence",  ["0.3", "0.53", "0.76", "1.0"])
motionCoherence     = Factor("motion coherence", ["0.3", "0.53", "0.76", "1.0"])
color      = Factor("color direction", ["red", "blue"])
motion      = Factor("motion direction", ["up", "down"])

# DEFINE RESPONSE FACTORS

def leftResponse(stimulusDimension):
    return (stimulusDimension == "red" or stimulusDimension == "up")

def rightResponse(stimulusDimension):
    return (stimulusDimension == "blue" or stimulusDimension == "down")

leftColorResponseLevel = DerivedLevel("-1", WithinTrial(leftResponse,   [color]))
rightColorResponseLevel = DerivedLevel("1", WithinTrial(rightResponse,   [color]))

leftMotionResponseLevel = DerivedLevel("-1", WithinTrial(leftResponse,   [motion]))
rightMotionResponseLevel = DerivedLevel("1", WithinTrial(rightResponse,   [motion]))

colorResponse = Factor("correct color response", [
    leftColorResponseLevel,
    rightColorResponseLevel
])

print("[SWEETPEA]: GENERATED COLOR RESPONSE FACTOR")

motionResponse = Factor("correct motion response", [
    leftMotionResponseLevel,
    rightMotionResponseLevel
from sweetpea.server import build_cnf

color = Factor("color", ["red", "blue", "green"])
word = Factor("motion", ["red", "blue"])


def illegal_stimulus(color, word):
    return color == "green" and word == "blue"


def legal_stimulus(color, word):
    return not illegal_stimulus(color, word)


stimulus_configuration = Factor("stimulus configuration", [
    DerivedLevel("legal", WithinTrial(legal_stimulus, [color, word])),
    DerivedLevel("illegal", WithinTrial(illegal_stimulus, [color, word]))
])

constraints = [
    exclude(stimulus_configuration,
            get_level_from_name(stimulus_configuration, "illegal"))
]

design = [color, word, stimulus_configuration]
crossing = [color, word]


def test_no_solutions_without_override_flag():
    block = fully_cross_block(design, crossing, constraints)
    experiments = synthesize_trials_non_uniform(block, 500)
Exemplo n.º 19
0
import operator as op

from sweetpea import fully_cross_block
from sweetpea.primitives import Factor, DerivedLevel, WithinTrial

color_list = ["red", "orange", "yellow", "green", "blue", "indigo"]
color = Factor("color", color_list)
text = Factor("text", color_list)
congruency = Factor("congruency", [
    DerivedLevel("congruent", WithinTrial(op.eq, [color, text])),
    DerivedLevel("incongruent", WithinTrial(op.ne, [color, text]))
])

design = [color, text, congruency]
crossing = [color, text]
block = fully_cross_block(design, crossing, [])

# ASSERT COUNT = 371993326789901217467999448150835200000000
Exemplo n.º 20
0
def test_else_level():
    color = Factor("color", ["red", "blue"])
    text = Factor("text", ["red", "blue"])

    conLevel = DerivedLevel("con", WithinTrial(op.eq, [color, text]))
    conFactor = Factor("congruent?", [conLevel, ElseLevel("inc")])
Exemplo n.º 21
0
color = Factor("color", ["red", "blue", "green"])
text = Factor("text", ["red", "blue", "green"])

# Global keyword needed to make this work when the tests exec() this file
global correct_order


def correct_order(color, text):
    return (color == "red"   and text == "blue") or \
           (color == "blue"  and text == "green") or \
           (color == "green" and text == "red")


global incorrect_order


def incorrect_order(color, text):
    return not correct_order(color, text)


order = Factor("order", [
    DerivedLevel("correct", WithinTrial(correct_order, [color, text])),
    DerivedLevel("incorrect", WithinTrial(incorrect_order, [color, text]))
])

design = [color, text, order]
crossing = [color, order]
block = fully_cross_block(design, crossing, [])

# ASSERT COUNT = 5760
Exemplo n.º 22
0
# Make SweetPea visible regardless of whether it's been installed.
import sys
sys.path.append("..")

import operator
from sweetpea.primitives import Factor, DerivedLevel, WithinTrial, Transition
from sweetpea import fully_cross_block, synthesize_trials_non_uniform, print_experiments, at_most_k_in_a_row, exclude

color_list = ["red", "green", "blue"]

color = Factor("color", color_list)
word = Factor("word", color_list)

congruent = DerivedLevel("con", WithinTrial(operator.eq, [color, word]))
incongruent = DerivedLevel("inc", WithinTrial(operator.ne, [color, word]))

congruence = Factor("congruence", [congruent, incongruent])

one_con_at_a_time = at_most_k_in_a_row(1, (congruence, congruent))


def one_diff(colors, words):
    if (colors[0] == colors[1]):
        return words[0] != words[1]
    else:
        return words[0] == words[1]


def both_diff(colors, words):
    return not one_diff(colors, words)
color = Factor("color", ["red", "blue"])
motion = Factor("motion", ["up", "down"])
task = Factor("task", ["color", "motion"])


def color_motion_congruent(color, motion):
    return ((color == "red") and (motion == "up")) or \
           ((color == "blue") and (motion == "down"))


def color_motion_incongruent(color, motion):
    return not color_motion_congruent(color, motion)


congruency = Factor("congruency", [
    DerivedLevel("con", WithinTrial(color_motion_congruent, [color, motion])),
    DerivedLevel("inc", WithinTrial(color_motion_incongruent, [color, motion]))
])

block = fully_cross_block([congruency, color, motion, task],
                          [color, motion, task], [])


def test_fully_cross_with_three_factors():
    (expected_cnf, _) = to_cnf_tseitin(
        And([
            Iff(65, And([3, 5, 7])),
            Iff(66, And([3, 5, 8])),
            Iff(67, And([3, 6, 7])),
            Iff(68, And([3, 6, 8])),
            Iff(69, And([4, 5, 7])),
Exemplo n.º 24
0
motionCoherence = Factor("motion coherence", ["0.3", "0.53", "0.76", "1.0"])
color = Factor("color direction", ["red", "blue"])
motion = Factor("motion direction", ["up", "down"])

# DEFINE RESPONSE FACTORS


def leftResponse(stimulusDimension):
    return (stimulusDimension == "red" or stimulusDimension == "up")


def rightResponse(stimulusDimension):
    return (stimulusDimension == "blue" or stimulusDimension == "down")


leftColorResponseLevel = DerivedLevel("-1", WithinTrial(leftResponse, [color]))
rightColorResponseLevel = DerivedLevel("1",
                                       WithinTrial(rightResponse, [color]))

leftMotionResponseLevel = DerivedLevel("-1",
                                       WithinTrial(leftResponse, [motion]))
rightMotionResponseLevel = DerivedLevel("1",
                                        WithinTrial(rightResponse, [motion]))

colorResponse = Factor("correct color response",
                       [leftColorResponseLevel, rightColorResponseLevel])

motionResponse = Factor("correct motion response",
                        [leftMotionResponseLevel, rightMotionResponseLevel])

# DEFINE CONGRUENCY FACTOR
        return False


"""
btw, this is the same as:
def response_left(task, color, motion):
    return (task == color && color == red) || (task == motion && motion == up)
"""


def response_right(task, color, motion):
    return not response_left(task, color, motion)


response = Factor("response", [
    derived_level("left", WithinTrial(response_left, [task, color, motion])),
    derived_level("right", WithinTrial(response_right, [task, color, motion]))
])
"""
          congruency (congruent, incongruent): dependent Factor.
if current color == red  & current motion == up then response = congruent
if current color == blue & current motion == down then response = congruent
.
if current color == red & current  motion == down then response = incongruent
if current color == blue & current  motion == up then response = incongruent
"""


def congruent(color, motion):
    return ((color == "red") and (motion == "up")) or ((color == "blue") and
                                                       (motion == "down"))
import operator as op
import pytest

from sweetpea.primitives import Factor, DerivedLevel, WithinTrial, Transition
from sweetpea.constraints import at_most_k_in_a_row, exactly_k_in_a_row
from sweetpea.sampling_strategies.guided import GuidedSamplingStrategy
from sweetpea import fully_cross_block, synthesize_trials
from sweetpea.tests.test_utils import get_level_from_name

# Basic setup
color_list = ["red", "blue"]
color = Factor("color", color_list)
text = Factor("text", color_list)

# Congruent Factor
con_level = DerivedLevel("con", WithinTrial(op.eq, [color, text]))
inc_level = DerivedLevel("inc", WithinTrial(op.ne, [color, text]))
con_factor = Factor("congruent?", [con_level, inc_level])

design = [color, text, con_factor]
crossing = [color, text]
constraints = []

block = fully_cross_block(design, crossing, constraints)


def test_guided_sampling_works():
    trials = synthesize_trials(block,
                               5,
                               sampling_strategy=GuidedSamplingStrategy)
Exemplo n.º 27
0
left    = Factor("left", ["0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"])
right    = Factor("right", ["0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"])

# ALL POSSIBLE COMBINATIONS


# DEFINE CONGRUENCY FACTOR

def congruent_stimulus(left, right):
    return left[0] == right[0] and left[1] == right[1]

def incongruent_stimulus(left, right):
    return not congruent_stimulus(left, right)

cong_stimulus = DerivedLevel("cong_stimulus", WithinTrial(congruent_stimulus, [left, right]))
incong_stimulus = DerivedLevel("incong_stimulus", WithinTrial(incongruent_stimulus, [left, right]))

stimulus = Factor("stimulus", [
    cong_stimulus,
    incong_stimulus
])

# DEFINE CONGRUENCY FACTOR

def congruent_context(left, right):
    return left[2] == right[2] and left[3] == right[3]

def incongruent_context(left, right):
    return not congruent_context(left, right)
Exemplo n.º 28
0
color = Factor("color", ["red", "blue", "green", "brown"])
word = Factor("motion", ["red", "blue", "green", "brown"])

# congruency factor


def congruent(color, word):
    return color == word


def incongruent(color, word):
    return not congruent(color, word)


conLevel = DerivedLevel("con", WithinTrial(congruent, [color, word]))
incLevel = DerivedLevel("inc", WithinTrial(incongruent, [color, word]))

congruency = Factor("congruency", [conLevel, incLevel])

# response factor


def response_up(color):
    return color == "red"


def response_down(color):
    return color == "blue"

Exemplo n.º 29
0
color = Factor("color", ["red", "blue"])
motion = Factor("motion", ["up", "down"])
task = Factor("task", ["color", "motion"])


def color_motion_congruent(color, motion):
    return ((color == "red") and (motion == "up")) or \
           ((color == "blue") and (motion == "down"))


def color_motion_incongruent(color, motion):
    return not color_motion_congruent(color, motion)


congruency = Factor("congruency", [
    DerivedLevel("con", WithinTrial(color_motion_congruent, [color, motion])),
    DerivedLevel("inc", WithinTrial(color_motion_incongruent, [color, motion]))
])


def response_left(task, color, motion):
    return (task == "color"  and color  == "red") or \
        (task == "motion" and motion == "up")


def response_right(task, color, motion):
    return not response_left(task, color, motion)


response = Factor("response", [
    DerivedLevel("left", WithinTrial(response_left, [task, color, motion])),
import operator as op
import pytest

from sweetpea import fully_cross_block
from sweetpea.primitives import Factor, DerivedLevel, WithinTrial
from sweetpea.design_partitions import DesignPartitions

color = Factor("color", ["red", "blue"])
text = Factor("text", ["red", "blue"])
congruency = Factor("congruency", [
    DerivedLevel("congruent", WithinTrial(op.eq, [color, text])),
    DerivedLevel("incongruent", WithinTrial(op.ne, [color, text]))
])
color_red = Factor("color red", [
    DerivedLevel("yes", WithinTrial(lambda c: c == "red", [color])),
    DerivedLevel("no", WithinTrial(lambda c: c != "red", [color]))
])

design = [color, text, congruency, color_red]
crossing = [color, congruency]
block = fully_cross_block(design, crossing, [])


def test_get_crossed_factors():
    partitions = DesignPartitions(block)
    assert partitions.get_crossed_factors() == crossing


def test_get_crossed_factors_derived():
    partitions = DesignPartitions(block)
    assert partitions.get_crossed_factors_derived() == [congruency]