from otree.api import * import time doc = """ Part 2: creating a group + timeout on wait page. """ class C(BaseConstants): NAME_IN_URL = 'smaller_group_2' PLAYERS_PER_GROUP = 5 NUM_ROUNDS = 1 matching_timeout_mins = 0.5 # max time on the waiting page smaller_group = 3 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): question1 = models.IntegerField(choices=[[1, "1"], [2, "2"], [3, "3"]], widget=widgets.RadioSelectHorizontal, label = "Question 1") question2 = models.IntegerField(choices=[[1, "1"], [2, "2"], [3, "3"]], widget=widgets.RadioSelectHorizontal, label = "Question 2") question3 = models.IntegerField(choices=[[1, "1"], [2, "2"], [3, "3"]], widget=widgets.RadioSelectHorizontal, label = "Question 3") group_size = models.IntegerField() # Functions for the waiting page def waiting_seconds(player): participant = player.participant wait = int(time.time() - participant.wait_page_arrival) print('Player', player.id_in_subsession, 'waiting for', wait, 'seconds') return wait def ranked_waiting_seconds(waiting_players): waits = [waiting_seconds(p) for p in waiting_players] return waits def group_by_arrival_time_method(subsession, waiting_players): num_waiting = len(waiting_players) subsession.session.vars['num_waiting'] = num_waiting print("number of waiting players:", num_waiting, " ", time.strftime('%X %x %Z')) if len(waiting_players) >= C.PLAYERS_PER_GROUP: for p in waiting_players: p.group_size = len(waiting_players) print('group size is', p.group_size) return waiting_players[:5] waits = ranked_waiting_seconds(waiting_players) waits.sort(reverse=False) print(waits) # Fallback to a smaller group if len(waits) == 4 and waits[3] > 60*C.matching_timeout_mins: return waiting_players if len(waits) == 3 and waits[2] > 60*C.matching_timeout_mins: return waiting_players if len(waits) == 2 and waits[1] > 60*C.matching_timeout_mins: return waiting_players if len(waits) == 1 and waits[0] > 60*C.matching_timeout_mins: return waiting_players # PAGES class Grouping_page(WaitPage): title_text = ("Please remain on this page - the task starts soon") body_text = "" group_by_arrival_time = True template_name = 'smaller_group_2/Grouping_page.html' @staticmethod def js_vars(player): return dict(arrival_time=player.participant.wait_page_arrival, current_time=time.time(), timeout_mins=C.matching_timeout_mins) @staticmethod def after_all_players_arrive(group: Group): # save each participant's current group ID so it can be accessed in the next app for p in group.get_players(): participant = p.participant participant.past_group_id = group.id group_size = len(group.get_players()) participant.group_size = group_size print(participant.group_size) @staticmethod def app_after_this_page(player: Player, upcoming_apps): if player.participant.group_size < C.smaller_group: return 'smaller_group_5' class Task(Page): @staticmethod def before_next_page(player: Player, timeout_happened): player.participant.wait_page_arrival = time.time() # print(participant.wait_page_arrival) page_sequence = [Grouping_page, Task, ]