# Path: speriment/utils.py
# class IDGenerator:
#     '''Creates an object to generate unique IDs for experimental components. You
#     should create exactly one per experiment so that all IDs in that experiment
#     will be distinct.
# 
#     Usage:
#     with make_experiment(IDGenerator()):
#         <experiment code>
#     '''
# 
#     def __init__(self, seed = -1):
#         '''seed: optional, an integer to start making IDs at.'''
#         self.current_id = seed
# 
#     def _current(self):
#         return self.current_id
# 
#     def _next_id(self):
#         '''Takes no arguments and returns a string, which is a new unique ID.'''
#         self.current_id += 1
#         return str(self.current_id)
# 
# def at_most_one(obj, attributes):
#     found = [attribute for attribute in attributes if hasattr(obj, attribute)]
#     if len(found) > 1:
#         raise ValueError, '''{} must have at most one of the following attributes:
# 
# {}
# 
# but it has:
# 
# {}.'''.format(obj, attributes, found)


from speriment.utils import IDGenerator, at_most_one
import copy
        variable: string or integer, optional. Like a variable x, it doesn't
        matter what you call it, it just matters whether another variable has
        the same name or a different one. If you give two SampleFroms the same
        bank and variable, they will sample the same value for a given
        participant (but likely different values for different participants). If
        you give them the same bank and different variables, they will sample
        different values.

        not_variable: string or integer, optional. If you give two SampleFroms
        the same bank and give one variable x and the other not_variable x, they
        will not sample the same value. not_variable is ignored if you give
        a variable.

        field: string, optional. Use with a bank made up of dictionaries where
        each dictionary has the same keys. field is the key you want to access.
        If you SampleFrom a bank of dictionaries that all contain x and y keys,
        and field is x, you will get one of the x values.

        with_replacement: boolean, optional. Defaults to False. Invalid when
        variable or not_variable is given. False is a shorthand
        for giving this SampleFrom a variable that is not used elsewhere in the
        experiment. Thus, False means this SampleFrom will not sample the same
        value as another SampleFrom on the same bank that has a variable,
        not_variable, or with_replacement set to False. True is a shorthand for
        "pick anything at all." Thus, a True setting on one SampleFrom overrides
        False settings on other SampleFroms on the same bank: they may sample
        the same value.
        '''
        self.bank = bank
        if bank not in SampleFrom._id_generators:

# Path: speriment/utils.py
# class IDGenerator:
#     '''Creates an object to generate unique IDs for experimental components. You
#     should create exactly one per experiment so that all IDs in that experiment
#     will be distinct.
# 
#     Usage:
#     with make_experiment(IDGenerator()):
#         <experiment code>
#     '''
# 
#     def __init__(self, seed = -1):
#         '''seed: optional, an integer to start making IDs at.'''
#         self.current_id = seed
# 
#     def _current(self):
#         return self.current_id
# 
#     def _next_id(self):
#         '''Takes no arguments and returns a string, which is a new unique ID.'''
#         self.current_id += 1
#         return str(self.current_id)
# 
# def at_most_one(obj, attributes):
#     found = [attribute for attribute in attributes if hasattr(obj, attribute)]
#     if len(found) > 1:
#         raise ValueError, '''{} must have at most one of the following attributes:
# 
# {}
# 
# but it has:
# 
# {}.'''.format(obj, attributes, found)


# Path: speriment/components/sample_from.py
from speriment.utils import IDGenerator, at_most_one
import copy

        variable: string or integer, optional. Like a variable x, it doesn't
        matter what you call it, it just matters whether another variable has
        the same name or a different one. If you give two SampleFroms the same
        bank and variable, they will sample the same value for a given
        participant (but likely different values for different participants). If
        you give them the same bank and different variables, they will sample
        different values.

        not_variable: string or integer, optional. If you give two SampleFroms
        the same bank and give one variable x and the other not_variable x, they
        will not sample the same value. not_variable is ignored if you give
        a variable.

        field: string, optional. Use with a bank made up of dictionaries where
        each dictionary has the same keys. field is the key you want to access.
        If you SampleFrom a bank of dictionaries that all contain x and y keys,
        and field is x, you will get one of the x values.

        with_replacement: boolean, optional. Defaults to False. Invalid when
        variable or not_variable is given. False is a shorthand
        for giving this SampleFrom a variable that is not used elsewhere in the
        experiment. Thus, False means this SampleFrom will not sample the same
        value as another SampleFrom on the same bank that has a variable,
        not_variable, or with_replacement set to False. True is a shorthand for
        "pick anything at all." Thus, a True setting on one SampleFrom overrides
        False settings on other SampleFroms on the same bank: they may sample
        the same value.
        '''
        self.bank = bank
        if bank not in SampleFrom._id_generators:

            SampleFrom._id_generators[bank] = IDGenerator()