from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'hidden_group' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 1 LEADER_ROLE = 'leader' F1_ROLE = 'follower 1' F2_ROLE = 'follower 2' class Subsession(BaseSubsession): pass def make_q(label): return models.CurrencyField(label=label, min=0, max=100, initial=0) class Group(BaseGroup): T_1 = make_q("Jammed") T_2 = make_q("Worn") T_3 = make_q("Dislocated") T_4 = make_q("Unplugged") D_1 = make_q("Type A") D_2 = make_q("Type B") D_3 = make_q("Type C") D_4 = make_q("Type D") W_1 = make_q("Red") W_2 = make_q("Blue") W_3 = make_q("Yellow") W_4 = make_q("Black") class Player(BasePlayer): pass # PAGES class WaitPage1(WaitPage): wait_for_all_groups = True class WaitPage2(WaitPage): wait_for_all_groups = True class Gr_Intro_p1(Page): pass class Gr_Intro_p2(Page): pass class Gr_Intro_L_p1(Page): @staticmethod def is_displayed(player: Player): return player.role == C.LEADER_ROLE class Gr_Intro_L_p2(Page): @staticmethod def is_displayed(player: Player): return player.role == C.LEADER_ROLE class Gr_Intro_L_p3(Page): @staticmethod def is_displayed(player: Player): return player.role == C.LEADER_ROLE class Gr_Intro_F_p1(Page): @staticmethod def is_displayed(player: Player): return player.role != C.LEADER_ROLE class Gr_Intro_F_p2(Page): @staticmethod def is_displayed(player: Player): return player.role != C.LEADER_ROLE class Gr_Intro_F_p3(Page): @staticmethod def is_displayed(player: Player): return player.role != C.LEADER_ROLE class Gr_pre_clue(Page): pass class clues_L(Page): @staticmethod def is_displayed(player: Player): return player.role == C.LEADER_ROLE class clues_F1(Page): @staticmethod def is_displayed(player: Player): return player.role == C.F1_ROLE class clues_F2(Page): @staticmethod def is_displayed(player: Player): return player.role == C.F2_ROLE class all_gather(Page): pass class L_input(Page): form_model = 'group' form_fields = ['T_1', 'T_2', 'T_3', 'T_4', 'D_1', 'D_2', 'D_3', 'D_4', 'W_1', 'W_2', 'W_3', 'W_4'] @staticmethod def is_displayed(player: Player): return player.role == C.LEADER_ROLE @staticmethod def error_message(player: Player, values): # since 'values' is a dict, you could also do sum(values.values()) if ((values['T_1'] + values['T_2'] + values['T_3'] + values['T_4']) or (values['D_1'] + values['D_2'] + values['D_3'] + values['D_4']) or (values['W_1'] + values['W_2'] + values['W_3'] + values['W_4'])) != (100 or 99.9): return 'The total needs to add to 100 (or 99.9 in case of an equal split between 3)' page_sequence = [WaitPage1, Gr_Intro_p1, Gr_Intro_p2, Gr_Intro_F_p1, Gr_Intro_F_p2, Gr_Intro_F_p3, Gr_Intro_L_p1, Gr_Intro_L_p2, Gr_Intro_L_p3, WaitPage2, Gr_pre_clue, clues_L, clues_F1, clues_F2, all_gather, L_input]