from otree.api import * cu = Currency doc = """ training TIME LAG """ def creating_session(subsession): if subsession.round_number != 1: subsession.group_like_round(1) class Constants(BaseConstants): name_in_url = 'training_TIMELAG' players_per_group = 4 num_rounds = 2 class Subsession(BaseSubsession): pass class Player(BasePlayer): A_value = models.FloatField(initial=0.04) B_value = models.FloatField(initial=0.02) harvest = models.IntegerField( min=0, max=50, initial=0, label="How many A-units do you want to harvest?" ) understanding = models.BooleanField( choices=[ [True, 'Yes'], [False, 'No'], ], label="Did you understand the instructions?" ) calculation = models.IntegerField( label=" 10 + 27 = ?" ) example = models.FloatField( label="If you harvest 5 units and the group harvests a total of 15 units, what is your payoff?" ) is_dropout = models.BooleanField(initial=False) revenue = models.FloatField() class Group(BaseGroup): total_harvest = models.IntegerField() A_stock_remained = models.IntegerField( min=0, max=50, initial=50, # Can I delete the initials? ) B_stock_remained = models.IntegerField( min=0, max=54, initial=50, # Can I delete the initials? ) A_growth_rate = models.IntegerField() B_growth_rate = models.IntegerField() A_new_stock = models.IntegerField( min=0, max=50, ) B_new_stock = models.IntegerField( min=0, max=54, ) def stocks_new_and_remained(group: Group): # questo potrebbe essere spostato in player e group diventa player, # anche se i gruppi comunque cambiano players = group.get_players() harvests = [p.harvest for p in players] group.total_harvest = sum(harvests) if group.round_number == 1: group.A_new_stock = 50 elif group.round_number == 2: group.A_new_stock = 50 - group.in_round(group.round_number - 1).total_harvest + group.in_round(group.round_number - 1).A_growth_rate elif group.round_number >= 3: group.A_new_stock = group.in_round(group.round_number - 1).A_stock_remained + group.in_round(group.round_number - 1).A_growth_rate if group.round_number == 1: group.B_new_stock = 50 elif group.round_number == 2: group.B_new_stock = 50 elif group.round_number == 3: group.B_new_stock = 50 - group.in_round(group.round_number - 2).total_harvest + group.in_round(group.round_number - 1).B_growth_rate elif group.round_number >= 4: group.B_new_stock = group.in_round(group.round_number - 2).B_stock_remained + group.in_round(group.round_number - 1).B_growth_rate def growth_rates(group: Group): players = group.get_players() harvests = [p.harvest for p in players] group.total_harvest = sum(harvests) if group.round_number == 2: # it was 50 group.A_stock_remained = group.A_new_stock - group.total_harvest else: group.A_stock_remained = group.A_new_stock - group.total_harvest if group.round_number == 2: group.B_stock_remained = group.B_new_stock - group.total_harvest else: group.B_stock_remained = group.B_new_stock - group.total_harvest if group.round_number == 1: if group.total_harvest == 0: group.A_growth_rate = 0 elif group.total_harvest in range(1, 6): group.A_growth_rate = 1 elif group.total_harvest in range(6, 11): group.A_growth_rate = 3 elif group.total_harvest in range(11, 16): group.A_growth_rate = 5 elif group.total_harvest in range(16, 21): group.A_growth_rate = 7 elif group.total_harvest in range(21, 26): group.A_growth_rate = 9 elif group.total_harvest in range(26, 31): group.A_growth_rate = 7 elif group.total_harvest in range(31, 36): group.A_growth_rate = 1 elif group.total_harvest in range(31, 41): group.A_growth_rate = 2 elif group.total_harvest in range(41, 46): group.A_growth_rate = 1 elif group.total_harvest in range(46, 50): group.A_growth_rate = 0 else: group.total_harvest = 49 group.A_growth_rate = 0 else: if group.A_stock_remained in range(0, 5): group.A_growth_rate = 0 elif group.A_stock_remained in range(5, 10): group.A_growth_rate = 1 elif group.A_stock_remained in range(10, 15): group.A_growth_rate = 2 elif group.A_stock_remained in range(15, 20): group.A_growth_rate = 1 elif group.A_stock_remained in range(20, 25): if group.round_number != 1 and group.in_round(group.round_number - 1).A_growth_rate == 1: group.A_growth_rate = 1 else: group.A_growth_rate = 7 elif group.A_stock_remained in range(25, 30): group.A_growth_rate = 9 elif group.A_stock_remained in range(30, 35): group.A_growth_rate = 7 elif group.A_stock_remained in range(35, 40): group.A_growth_rate = 5 elif group.A_stock_remained in range(40, 45): group.A_growth_rate = 3 elif group.A_stock_remained in range(45, 50): group.A_growth_rate = 1 else: group.A_growth_rate = 0 if group.round_number == 1: group.B_growth_rate = 3 elif group.round_number == 2: if group.total_harvest > group.A_stock_remained: group.B_growth_rate = 0 elif group.in_round(group.round_number - 1).total_harvest == 0: group.B_growth_rate = 3 elif group.in_round(group.round_number - 1).total_harvest in range(1, 6): group.B_growth_rate = 5 elif group.in_round(group.round_number - 1).total_harvest in range(6, 11): group.B_growth_rate = 9 elif group.in_round(group.round_number - 1).total_harvest in range(11, 16): group.B_growth_rate = 10 elif group.in_round(group.round_number - 1).total_harvest in range(16, 21): group.B_growth_rate = 12 elif group.in_round(group.round_number - 1).total_harvest in range(21, 26): group.B_growth_rate = 13 elif group.in_round(group.round_number - 1).total_harvest in range(26, 31): group.B_growth_rate = 10 elif group.in_round(group.round_number - 1).total_harvest in range(31, 36): group.B_growth_rate = 4 elif group.in_round(group.round_number - 1).total_harvest in range(36, 41): group.B_growth_rate = 3 elif group.in_round(group.round_number - 1).total_harvest in range(41, 46): group.B_growth_rate = 2 elif group.in_round(group.round_number - 1).total_harvest in range(46, 50): group.B_growth_rate = 1 elif group.in_round(group.round_number - 1).total_harvest >= 50: group.B_growth_rate = 0 for p in players: if group.total_harvest < group.A_stock_remained: p.revenue = p.harvest * p.A_value + group.B_growth_rate * p.B_value elif group.total_harvest >= group.A_stock_remained: p.revenue = ((p.harvest / group.total_harvest) * 49) * p.A_value + group.B_growth_rate \ * p.B_value class Grouping(WaitPage): body_text = "Please wait a few seconds so that other participants can join your group." group_by_arrival_time = True @staticmethod def is_displayed(group): return group.round_number == 1 class Introduction(Page): @staticmethod def is_displayed(group): return group.round_number == 1 timeout_seconds = 60 class Instructions(Page): @staticmethod def is_displayed(group: Group): if group.round_number == 1: return True timeout_seconds = 300 form_model = "player" form_fields = ["understanding"] class Calculating(WaitPage): after_all_players_arrive = stocks_new_and_remained class Training(Page): form_model = "player" form_fields = ["harvest"] timeout_seconds = 180 # https://otree.readthedocs.io/en/latest/multiplayer/waitpages.html?highlight=is_dropout @staticmethod def is_displayed(player: Player): group = player.group if group.A_new_stock != 0: return True else: return False def custom_export(players): # this is for custom data export # header row yield ['session', 'participant_code', 'round_number', 'id_in_group', 'payoff', 'harvest'] # I added harvest for p in players: participant = p.participant session = p.session yield [session.code, participant.code, p.round_number, p.id_in_group, p.payoff, p.harvest] class ResultsWaitPage(WaitPage): body_text = "Waiting for other participants to decide." after_all_players_arrive = growth_rates class Results(Page): timeout_seconds = 30 def vars_for_template(player: Player): all_players = player.in_all_rounds() combined_revenue = 0 for player in all_players: combined_revenue += player.revenue return dict(combined_revenue=combined_revenue) page_sequence = [Grouping, Introduction, Instructions, Calculating, Training, ResultsWaitPage, Results]