def set_players(self, players_list): Constants = self._Constants roles = get_roles(Constants) for i, player in enumerate(players_list, start=1): player.group = self player.id_in_group = i player._role = get_role(roles, i) db.commit()
def get_player_by_role(self, role): if get_roles(self._Constants): try: return self.player_set.get(_role=role) except django.core.exceptions.ObjectDoesNotExist: pass else: for p in self.get_players(): if p.role() == role: return p msg = f'No player with role "{role}"' raise ValueError(msg)
def get_player_by_role(self, role): if get_roles(self._Constants): try: return self.player_set.filter_by(_role=role).one() except NoResultFound: pass else: for p in self.get_players(): if p.role() == role: return p msg = f'No player with role "{role}"' raise ValueError(msg)
def create_session( session_config_name, *, num_participants, label='', room_name=None, is_mturk=False, is_demo=False, modified_session_config_fields=None, ) -> Session: num_subsessions = 0 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()) modified_config = modified_session_config_fields or {} # this is for API. don't want to mislead people # to put stuff in the session config that should be in the session. bad_keys = modified_config.keys() & NON_EDITABLE_FIELDS if bad_keys: raise Exception( f'The following session config fields are not editable: {bad_keys}' ) session_config.update(modified_config) # 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() # check that it divides evenly session_lcm = session_config.get_lcm() if num_participants is None: # most games are multiplayer, so if it's under 2, we bump it to 2 num_participants = max(session_lcm, 2) else: if num_participants % session_lcm: msg = ( 'Session Config {}: Number of participants ({}) is not a multiple ' 'of group size ({})' ).format(session_config['name'], num_participants, session_lcm) raise ValueError(msg) session = Session( config=session_config, label=label, is_demo=is_demo, num_participants=num_participants, is_mturk=is_mturk, ) db.add(session) db.commit() session_code = session.code participants = [ Participant( id_in_session=id_in_session, session=session, _session_code=session_code, ) for id_in_session in list(range(1, num_participants + 1)) ] db.add_all(participants) db.commit() # participant_values = ( # db.query(Participant) # .filter(Session.id == session.id) # .order_by('id') # .with_entities(Participant.id, Participant.code) # ).all() participant_values = ( db.query(Participant) .join(Session) .filter(Session.id == session.id) .order_by(Participant.id) .with_entities(Participant.id, Participant.code) ).all() num_pages = 0 for app_name in session_config['app_sequence']: views_module = common.get_pages_module(app_name) models_module = get_models_module(app_name) Constants: BaseConstants = models_module.Constants num_subsessions += Constants.num_rounds round_numbers = list(range(1, Constants.num_rounds + 1)) num_pages += Constants.num_rounds * len(views_module.page_sequence) Subsession = models_module.Subsession Group = models_module.Group Player = models_module.Player subsessions = [ Subsession(round_number=round_number, session=session) for round_number in round_numbers ] db.add_all(subsessions) db.commit() subsessions = ( dbq(Subsession) .filter_by(session=session) .order_by('round_number') .with_entities('id', 'round_number') ) ppg = Constants.players_per_group if ppg is None or Subsession._has_group_by_arrival_time(): ppg = num_participants num_groups_per_round = int(num_participants / ppg) groups_to_create = [] for ss_id, ss_rd in subsessions: for id_in_subsession in range(1, num_groups_per_round + 1): groups_to_create.append( Group( session=session, subsession_id=ss_id, round_number=ss_rd, id_in_subsession=id_in_subsession, ) ) db.add_all(groups_to_create) groups = ( dbq(Group).filter_by(session=session).order_by('id_in_subsession') ).all() groups_lookup = defaultdict(list) for group in groups: groups_lookup[group.subsession_id].append(group.id) players_to_create = [] for ss_id, ss_rd in subsessions: roles = get_roles(Constants) participant_index = 0 for group_id in groups_lookup[ss_id]: for id_in_group in range(1, ppg + 1): participant = participant_values[participant_index] players_to_create.append( Player( session=session, subsession_id=ss_id, round_number=ss_rd, participant_id=participant[0], group_id=group_id, id_in_group=id_in_group, _role=get_role(roles, id_in_group), ) ) participant_index += 1 # Create players db.add_all(players_to_create) dbq(Participant).filter_by(session=session).update( {Participant._max_page_index: num_pages} ) # make creating_session use the current session, # so that session.save() below doesn't overwrite everything # set earlier for subsession in session.get_subsessions(): subsession.creating_session() # 2017-09-27: moving this inside the transaction session._set_admin_report_app_names() if room_name is not None: from otree.room import ROOM_DICT room = ROOM_DICT[room_name] room.set_session(session) db.commit() return session