def get_lcm(session_config): min_multiple_list = [] for app_name in session_config["app_sequence"]: app_constants = get_app_constants(app_name) # if players_per_group is None, 0, etc. min_multiple = min_players_multiple(app_constants.players_per_group) min_multiple_list.append(min_multiple) return lcmm(*min_multiple_list)
def get_lcm(self): min_multiple_list = [] for app_name in self['app_sequence']: Constants = get_app_constants(app_name) # if players_per_group is None, 0, etc. min_multiple = Constants.players_per_group or 1 min_multiple_list.append(min_multiple) return lcmm(*min_multiple_list)
def get_lcm(session_config): min_multiple_list = [] for app_name in session_config['app_sequence']: app_constants = get_app_constants(app_name) # if players_per_group is None, 0, etc. min_multiple = min_players_multiple(app_constants.players_per_group) min_multiple_list.append(min_multiple) return lcmm(*min_multiple_list)
def create_session(session_config_name, *, label='', num_participants=None, pre_create_id=None, room_name=None, for_mturk=False, is_demo=False, edited_session_config_fields=None) -> Session: session = None num_subsessions = 0 edited_session_config_fields = edited_session_config_fields or {} try: session_config = SESSION_CONFIGS_DICT[session_config_name] except KeyError: msg = 'Session config "{}" not found in settings.SESSION_CONFIGS.' raise KeyError(msg.format(session_config_name)) from None else: # copy so that we don't mutate the original # .copy() returns a dict, so need to convert back to SessionConfig session_config = SessionConfig(session_config.copy()) session_config.update(edited_session_config_fields) # check validity and converts serialized decimal & currency values # back to their original data type (because they were serialized # when passed through channels session_config.clean() with transaction.atomic(): # 2014-5-2: i could implement this by overriding the __init__ on the # Session model, but I don't really know how that works, and it seems # to be a bit discouraged: http://goo.gl/dEXZpv # 2014-9-22: preassign to groups for demo mode. otree.db.idmap.activate_cache() session = Session.objects.create( config=session_config, label=label, _pre_create_id=pre_create_id, is_demo=is_demo, num_participants=num_participants, ) # type: Session def bulk_create(model, descriptions): model.objects.bulk_create([ model(session=session, **description) for description in descriptions ]) return model.objects.filter(session=session).order_by('pk') # check that it divides evenly session_lcm = session_config.get_lcm() if num_participants % session_lcm: msg = ('Session Config {}: Number of participants ({}) does not ' 'divide evenly into group size ({})').format( session_config['name'], num_participants, session_lcm) raise ValueError(msg) if for_mturk: session.mturk_num_participants = ( num_participants / settings.MTURK_NUM_PARTICIPANTS_MULTIPLE) # TODO: remove start_order start_order = list(range(num_participants)) if session_config.get('random_start_order'): random.shuffle(start_order) participants = bulk_create(Participant, [{ 'id_in_session': id_in_session, 'start_order': j, } for id_in_session, j in enumerate(start_order, start=1)]) ParticipantLockModel.objects.bulk_create([ ParticipantLockModel(participant_code=participant.code) for participant in participants ]) for app_name in session_config['app_sequence']: models_module = get_models_module(app_name) app_constants = get_app_constants(app_name) num_subsessions += app_constants.num_rounds round_numbers = list(range(1, app_constants.num_rounds + 1)) subs = bulk_create(models_module.Subsession, [{ 'round_number': round_number } for round_number in round_numbers]) # Create players models_module.Player.objects.bulk_create([ models_module.Player(session=session, subsession=subsession, round_number=round_number, participant=participant) for round_number, subsession in zip(round_numbers, subs) for participant in participants ]) session._create_groups_and_initialize() session.build_participant_to_player_lookups() # automatically save all objects since the cache was activated: # Player, Group, Subsession, Participant, Session otree.db.idmap.save_objects() otree.db.idmap.deactivate_cache() # 2017-09-27: moving this inside the transaction session._set_admin_report_app_names() session.save() # we don't need to mark it ready=True here...because it's in a # transaction # this should happen after session.ready = True if room_name is not None: from otree.room import ROOM_DICT room = ROOM_DICT[room_name] room.session = session return session
def create_session( session_config_name, label='', num_participants=None, _pre_create_id=None, room_name=None, for_mturk=False, use_cli_bots=False, is_demo=False, force_browser_bots=False, honor_browser_bots_config=False, bot_case_number=None): session = None use_browser_bots = False num_subsessions = 0 with transaction.atomic(): # 2014-5-2: i could implement this by overriding the __init__ on the # Session model, but I don't really know how that works, and it seems # to be a bit discouraged: http://goo.gl/dEXZpv # 2014-9-22: preassign to groups for demo mode. otree.db.idmap.activate_cache() try: session_config = SESSION_CONFIGS_DICT[session_config_name] except KeyError: msg = 'Session config "{}" not found in settings.SESSION_CONFIGS.' raise ValueError(msg.format(session_config_name)) if force_browser_bots: use_browser_bots = True elif (session_config.get('use_browser_bots') and honor_browser_bots_config): use_browser_bots = True else: use_browser_bots = False if use_browser_bots and bot_case_number is None: # choose one randomly num_bot_cases = session_config.get_num_bot_cases() # choose bot case number randomly...maybe reconsider this? # we can only run one. bot_case_number = random.choice(range(num_bot_cases)) session = Session.objects.create( config=session_config, label=label, _pre_create_id=_pre_create_id, use_browser_bots=use_browser_bots, is_demo=is_demo, _bot_case_number=bot_case_number) def bulk_create(model, descriptions): model.objects.bulk_create([ model(session=session, **description) for description in descriptions]) return model.objects.filter(session=session).order_by('pk') # check that it divides evenly session_lcm = session_config.get_lcm() if num_participants % session_lcm: msg = ( 'Session Config {}: Number of participants ({}) does not ' 'divide evenly into group size ({})' ).format(session_config['name'], num_participants, session_lcm) raise ValueError(msg) if for_mturk: session.mturk_num_participants = ( num_participants / settings.MTURK_NUM_PARTICIPANTS_MULTIPLE) start_order = list(range(num_participants)) if session_config.get('random_start_order'): random.shuffle(start_order) participants = bulk_create( Participant, [{ 'id_in_session': id_in_session, 'start_order': j, # check if id_in_session is in the bots ID list '_is_bot': use_cli_bots or use_browser_bots, } for id_in_session, j in enumerate(start_order, start=1)]) ParticipantLockModel.objects.bulk_create([ ParticipantLockModel(participant_code=participant.code) for participant in participants]) try: for app_name in session_config['app_sequence']: models_module = get_models_module(app_name) app_constants = get_app_constants(app_name) num_subsessions += app_constants.num_rounds round_numbers = list(range(1, app_constants.num_rounds + 1)) subs = bulk_create( models_module.Subsession, [{'round_number': round_number} for round_number in round_numbers]) # Create players models_module.Player.objects.bulk_create([ models_module.Player( session=session, subsession=subsession, round_number=round_number, participant=participant) for round_number, subsession in zip(round_numbers, subs) for participant in participants]) session._create_groups_and_initialize() # session.has_bots = any(p.is_bot ...) # handle case where DB has missing column or table # missing table: OperationalError: no such table: pg_subsession # missing column: OperationalError: table pg_player has no column # named contribution2 except OperationalError as exception: exception_str = str(exception) if 'table' in exception_str: ExceptionClass = type(exception) six.reraise( ExceptionClass, ExceptionClass('{} - Try resetting the database.'.format( exception_str)), sys.exc_info()[2]) raise session.build_participant_to_player_lookups() # automatically save all objects since the cache was activated: # Player, Group, Subsession, Participant, Session otree.db.idmap.save_objects() otree.db.idmap.deactivate_cache() if use_browser_bots: # what about clear_browser_bots? if session is created through # UI, when do we run that? it should be run when the session # is deleted try: num_players_total = num_participants * num_subsessions otree.bots.browser.initialize_bots( session.code, num_players_total) except: session.delete() raise session.ready = True session.save() # this should happen after session.ready = True if room_name is not None: from otree.room import ROOM_DICT room = ROOM_DICT[room_name] room.session = session return session
def create_session(session_config_name, label="", num_participants=None, special_category=None, _pre_create_id=None): # 2014-5-2: i could implement this by overriding the __init__ on the # Session model, but I don't really know how that works, and it seems to # be a bit discouraged: http://goo.gl/dEXZpv # 2014-9-22: preassign to groups for demo mode. try: session_config = get_session_configs_dict()[session_config_name] except KeyError: msg = 'Session type "{}" not found in settings.py' raise ValueError(msg.format(session_config_name)) session = Session.objects.create( config=session_config, label=label, special_category=special_category, _pre_create_id=_pre_create_id ) def bulk_create(model, descriptions): model.objects.bulk_create([model(session=session, **description) for description in descriptions]) return model.objects.filter(session=session).order_by("pk") if num_participants is None: c_special_catdemo = constants_internal.session_special_category_demo c_special_catbots = constants_internal.session_special_category_bots if special_category == c_special_catdemo: num_participants = session_config["num_demo_participants"] elif special_category == c_special_catbots: num_participants = session_config["num_bots"] # check that it divides evenly session_lcm = get_lcm(session_config) if num_participants % session_lcm: msg = "Session Config {}: Number of participants ({}) does not divide " "evenly into group size ({})" raise ValueError(msg.format(session_config["name"], num_participants, session_lcm)) start_order = range(num_participants) if session_config.get("random_start_order"): random.shuffle(start_order) participants = bulk_create( Participant, [{"id_in_session": i + 1, "start_order": j} for i, j in enumerate(start_order)] ) for participant in participants: ParticipantLockModel(participant_code=participant.code).save() for app_name in session_config["app_sequence"]: models_module = get_models_module(app_name) app_constants = get_app_constants(app_name) round_numbers = range(1, app_constants.num_rounds + 1) subs = bulk_create(models_module.Subsession, [{"round_number": round_number} for round_number in round_numbers]) # Create players models_module.Player.objects.bulk_create( [ models_module.Player( session=session, subsession=subsession, round_number=round_number, participant=participant ) for round_number, subsession in zip(round_numbers, subs) for participant in participants ] ) session._create_groups_and_initialize() session.build_participant_to_player_lookups() session.ready = True session.save() return session
def create_session(session_config_name, label='', num_participants=None, special_category=None, _pre_create_id=None): # 2014-5-2: i could implement this by overriding the __init__ on the # Session model, but I don't really know how that works, and it seems to # be a bit discouraged: http://goo.gl/dEXZpv # 2014-9-22: preassign to groups for demo mode. try: session_config = get_session_configs_dict()[session_config_name] except KeyError: msg = 'Session type "{}" not found in settings.py' raise ValueError(msg.format(session_config_name)) session = Session.objects.create( config=session_config, label=label, special_category=special_category, _pre_create_id=_pre_create_id,) def bulk_create(model, descriptions): model.objects.bulk_create([ model(session=session, **description) for description in descriptions]) return model.objects.filter(session=session).order_by('pk') if num_participants is None: c_special_catdemo = constants_internal.session_special_category_demo c_special_catbots = constants_internal.session_special_category_bots if special_category == c_special_catdemo: num_participants = session_config['num_demo_participants'] elif special_category == c_special_catbots: num_participants = session_config['num_bots'] # check that it divides evenly session_lcm = get_lcm(session_config) if num_participants % session_lcm: msg = ( 'Session Config {}: Number of participants ({}) does not divide ' 'evenly into group size ({})') raise ValueError( msg.format(session_config['name'], num_participants, session_lcm)) start_order = list(range(num_participants)) if session_config.get('random_start_order'): random.shuffle(start_order) participants = bulk_create( Participant, [{'id_in_session': i + 1, 'start_order': j} for i, j in enumerate(start_order)]) for participant in participants: ParticipantLockModel(participant_code=participant.code).save() for app_name in session_config['app_sequence']: models_module = get_models_module(app_name) app_constants = get_app_constants(app_name) round_numbers = list(range(1, app_constants.num_rounds + 1)) subs = bulk_create( models_module.Subsession, [{'round_number': round_number} for round_number in round_numbers]) # Create players models_module.Player.objects.bulk_create([ models_module.Player( session=session, subsession=subsession, round_number=round_number, participant=participant) for round_number, subsession in zip(round_numbers, subs) for participant in participants]) session._create_groups_and_initialize() session.build_participant_to_player_lookups() session.ready = True session.save() return session
def create_session( session_config_name, *, label='', num_participants=None, pre_create_id=None, room_name=None, for_mturk=False, use_cli_bots=False, is_demo=False, force_browser_bots=False, # i think bot_case_number is unused. honor_browser_bots_config=False, bot_case_number=None, edited_session_config_fields=None): session = None use_browser_bots = False num_subsessions = 0 edited_session_config_fields = edited_session_config_fields or {} with transaction.atomic(): # 2014-5-2: i could implement this by overriding the __init__ on the # Session model, but I don't really know how that works, and it seems # to be a bit discouraged: http://goo.gl/dEXZpv # 2014-9-22: preassign to groups for demo mode. otree.db.idmap.activate_cache() try: session_config = SESSION_CONFIGS_DICT[session_config_name] except KeyError: msg = 'Session config "{}" not found in settings.SESSION_CONFIGS.' raise KeyError(msg.format(session_config_name)) from None else: # copy so that we don't mutate the original # .copy() returns a dict, so need to convert back to SessionConfig session_config = SessionConfig(session_config.copy()) session_config.update(edited_session_config_fields) # check validity and converts serialized decimal & currency values # back to their original data type (because they were serialized # when passed through channels session_config.clean() if force_browser_bots: use_browser_bots = True elif (session_config.get('use_browser_bots') and honor_browser_bots_config): use_browser_bots = True else: use_browser_bots = False session = Session.objects.create( config=session_config, label=label, _pre_create_id=pre_create_id, use_browser_bots=use_browser_bots, is_demo=is_demo, num_participants=num_participants, ) # type: Session def bulk_create(model, descriptions): model.objects.bulk_create([ model(session=session, **description) for description in descriptions]) return model.objects.filter(session=session).order_by('pk') # check that it divides evenly session_lcm = session_config.get_lcm() if num_participants % session_lcm: msg = ( 'Session Config {}: Number of participants ({}) does not ' 'divide evenly into group size ({})' ).format(session_config['name'], num_participants, session_lcm) raise ValueError(msg) if for_mturk: session.mturk_num_participants = ( num_participants / settings.MTURK_NUM_PARTICIPANTS_MULTIPLE) # TODO: remove start_order start_order = list(range(num_participants)) if session_config.get('random_start_order'): random.shuffle(start_order) participants = bulk_create( Participant, [{ 'id_in_session': id_in_session, 'start_order': j, # check if id_in_session is in the bots ID list '_is_bot': use_cli_bots or use_browser_bots, } for id_in_session, j in enumerate(start_order, start=1)]) ParticipantLockModel.objects.bulk_create([ ParticipantLockModel(participant_code=participant.code) for participant in participants]) for app_name in session_config['app_sequence']: models_module = get_models_module(app_name) app_constants = get_app_constants(app_name) num_subsessions += app_constants.num_rounds round_numbers = list(range(1, app_constants.num_rounds + 1)) subs = bulk_create( models_module.Subsession, [{'round_number': round_number} for round_number in round_numbers]) # Create players models_module.Player.objects.bulk_create([ models_module.Player( session=session, subsession=subsession, round_number=round_number, participant=participant) for round_number, subsession in zip(round_numbers, subs) for participant in participants]) session._create_groups_and_initialize() session.build_participant_to_player_lookups() # automatically save all objects since the cache was activated: # Player, Group, Subsession, Participant, Session otree.db.idmap.save_objects() otree.db.idmap.deactivate_cache() if use_browser_bots: # what about clear_browser_bots? if session is created through # UI, when do we run that? it should be run when the session # is deleted try: num_players_total = num_participants * num_subsessions otree.bots.browser.initialize_bots( session_pk=session.pk, num_players_total=num_players_total, ) except: session.delete() raise session._set_admin_report_app_names() session.ready = True session.save() # this should happen after session.ready = True if room_name is not None: from otree.room import ROOM_DICT room = ROOM_DICT[room_name] room.session = session return session
def create_session( session_config_name, label='', num_participants=None, _pre_create_id=None, room_name=None, for_mturk=False, use_cli_bots=False, is_demo=False, force_browser_bots=False, honor_browser_bots_config=False, bot_case_number=None, edited_session_config_fields=None): session = None use_browser_bots = False participants = [] edited_session_config_fields = edited_session_config_fields or {} with transaction.atomic(): # 2014-5-2: i could implement this by overriding the __init__ on the # Session model, but I don't really know how that works, and it seems # to be a bit discouraged: http://goo.gl/dEXZpv # 2014-9-22: preassign to groups for demo mode. otree.db.idmap.activate_cache() try: session_config = SESSION_CONFIGS_DICT[session_config_name] except KeyError: msg = 'Session config "{}" not found in settings.SESSION_CONFIGS.' raise KeyError(msg.format(session_config_name)) from None else: # seems i need to copy and convert back to a session config # otherwise .copy() converts it to a simple dict session_config.update(edited_session_config_fields) session_config = SessionConfig(session_config.copy()) # check validity and converts serialized decimal & currency values # back to their original data type (because they were serialized # when passed through channels session_config.clean() if force_browser_bots: use_browser_bots = True elif (session_config.get('use_browser_bots') and honor_browser_bots_config): use_browser_bots = True else: use_browser_bots = False if use_browser_bots and bot_case_number is None: # choose one randomly num_bot_cases = session_config.get_num_bot_cases() # choose bot case number randomly...maybe reconsider this? # we can only run one. bot_case_number = random.choice(range(num_bot_cases)) session = Session.objects.create( config=session_config, label=label, _pre_create_id=_pre_create_id, use_browser_bots=use_browser_bots, is_demo=is_demo, _bot_case_number=bot_case_number) def bulk_create(model, descriptions): model.objects.bulk_create([ model(session=session, **description) for description in descriptions]) return model.objects.filter(session=session).order_by('pk') # check that it divides evenly session_lcm = session_config.get_lcm() if num_participants % session_lcm: msg = ( 'Session Config {}: Number of participants ({}) does not ' 'divide evenly into group size ({})' ).format(session_config['name'], num_participants, session_lcm) raise ValueError(msg) if for_mturk: session.mturk_num_participants = ( num_participants / settings.MTURK_NUM_PARTICIPANTS_MULTIPLE) start_order = list(range(num_participants)) if session_config.get('random_start_order'): random.shuffle(start_order) participants = bulk_create( Participant, [{ 'id_in_session': id_in_session, 'start_order': j, # check if id_in_session is in the bots ID list '_is_bot': use_cli_bots or use_browser_bots, } for id_in_session, j in enumerate(start_order, start=1)]) ParticipantLockModel.objects.bulk_create([ ParticipantLockModel(participant_code=participant.code) for participant in participants]) for app_name in session_config['app_sequence']: models_module = get_models_module(app_name) app_constants = get_app_constants(app_name) round_numbers = list(range(1, app_constants.num_rounds + 1)) subs = bulk_create( models_module.Subsession, [{'round_number': round_number} for round_number in round_numbers]) # Create players models_module.Player.objects.bulk_create([ models_module.Player( session=session, subsession=subsession, round_number=round_number, participant=participant) for round_number, subsession in zip(round_numbers, subs) for participant in participants]) session._create_groups_and_initialize() session.build_participant_to_player_lookups() # automatically save all objects since the cache was activated: # Player, Group, Subsession, Participant, Session otree.db.idmap.save_objects() otree.db.idmap.deactivate_cache() if use_browser_bots: # what about clear_browser_bots? if session is created through # UI, when do we run that? it should be run when the session # is deleted try: for participant in participants: otree.bots.browser.initialize_bot( participant.code) except: session.delete() raise session.ready = True session.save() # this should happen after session.ready = True if room_name is not None: from otree.room import ROOM_DICT room = ROOM_DICT[room_name] room.session = session return session
def create_session(session_config_name, label='', num_participants=None, special_category=None, _pre_create_id=None, room=None, for_mturk=False): # 2014-5-2: i could implement this by overriding the __init__ on the # Session model, but I don't really know how that works, and it seems to # be a bit discouraged: http://goo.gl/dEXZpv # 2014-9-22: preassign to groups for demo mode. otree.db.idmap.activate_cache() try: session_config = SESSION_CONFIGS_DICT[session_config_name] except KeyError: msg = 'Session type "{}" not found in settings.py' raise ValueError(msg.format(session_config_name)) session = Session.objects.create( config=session_config, label=label, special_category=special_category, _pre_create_id=_pre_create_id,) def bulk_create(model, descriptions): model.objects.bulk_create([ model(session=session, **description) for description in descriptions]) return model.objects.filter(session=session).order_by('pk') if num_participants is None: c_special_catdemo = constants_internal.session_special_category_demo c_special_catbots = constants_internal.session_special_category_bots if special_category == c_special_catdemo: num_participants = session_config['num_demo_participants'] elif special_category == c_special_catbots: num_participants = session_config['num_bots'] # check that it divides evenly session_lcm = get_lcm(session_config) if num_participants % session_lcm: msg = ( 'Session Config {}: Number of participants ({}) does not divide ' 'evenly into group size ({})') raise ValueError( msg.format(session_config['name'], num_participants, session_lcm)) if for_mturk: session.mturk_num_participants = ( num_participants / settings.MTURK_NUM_PARTICIPANTS_MULT ) start_order = list(range(num_participants)) if session_config.get('random_start_order'): random.shuffle(start_order) participants = bulk_create( Participant, [{'id_in_session': i + 1, 'start_order': j} for i, j in enumerate(start_order)]) for participant in participants: ParticipantLockModel(participant_code=participant.code).save() for app_name in session_config['app_sequence']: models_module = get_models_module(app_name) app_constants = get_app_constants(app_name) round_numbers = list(range(1, app_constants.num_rounds + 1)) subs = bulk_create( models_module.Subsession, [{'round_number': round_number} for round_number in round_numbers]) # Create players models_module.Player.objects.bulk_create([ models_module.Player( session=session, subsession=subsession, round_number=round_number, participant=participant) for round_number, subsession in zip(round_numbers, subs) for participant in participants]) session._create_groups_and_initialize() session.build_participant_to_player_lookups() if room is not None: room.session = session session.ready = True session.save() otree.db.idmap.deactivate_cache() return session