oTree Forum >

TypeError: Forex1.is_displayed() missing 1 required positional argument: 'group'

#1 by jrm0094

Hi, I am getting an error saying that the argument 'group' is missing from the is_displayed() function inside my Forex1 Page. Here is the code for the Forex1 Page:

class Forex1(Page):
    form_model = 'player'
    form_fields = ['initial_bid_forex']
    @staticmethod
    def is_displayed(player: Player, group: Group):
        chance = find_chance(group, player)
        if (chance == False):
            group.game_ended = True
            return False
        else:
            return True
    
    @staticmethod
    def vars_for_template(player):
        round_number = player.round_number
        price_this_round = C.PRICE[round_number + 14]
        price_last_round = C.PRICE[round_number + 13]
        delta_this_round = C.DELTA[round_number + 9]
        pc_supply_this_round = C.PC[round_number + 9]
        fiat_balance = calculate_money_balance_fiat(player)
        fiat_inflation = ((price_this_round-price_last_round)/(price_last_round))*100
        fiat_inflation = round(float(fiat_inflation), 2)
        fiat_balance = round(float(fiat_balance), 2)
        return dict(fiat_balance=fiat_balance, fiat_inflation=fiat_inflation, delta_this_round=delta_this_round,
                    pc_supply_this_round=pc_supply_this_round)

As you can see inside of the is_displayed() function near the top of the Forex1 class there are two arguments, player: Player and group: Group. I don't understand why it still says the 'group' argument is missing. 

One other thing, I do not have any models set up inside the Group class for the apps that play before this one. What I mean is app1, app2, app3, ... play in sequence. Can the problem be that otree thinks the group is missing because technically I only am using group inside the final app in the app sequence?

#2 by xindamate_xyz (edited )

If you need to access the group within is_displayed, you can do so through the player object. Adjust your is_displayed method to access the group like so:


@staticmethod
def is_displayed(player: Player):
    group = player.group
    chance = find_chance(group, player)
    if not chance:
        group.game_ended = True
        return False
    else:
        return True
        
This adjustment removes the need for the group parameter to be passed explicitly and instead accesses it through the player object, which aligns with how oTree's framework operates.


Best regards,
Tina Zheng
Visit our website https://otree.xindamate.xyz/en for more information

#3 by jrm0094

Thank you, that fixed my problem. Now I am just trying to figure out how to only call the function once all the players get to a Wait Page. I want to be able it be when all players are at this WaitPage, called AfterIntroWait, the function is called. Here is the function:

def game_ends(group, player):
    import random
    round_number = player.round_number
    chance = random.randint(0,100)
    print("Chance: ", chance)
    if (chance >= C.PROB[round_number-1]):
        group.game_ended = True
    else:
        return
        
And here is the code for the AfterIntroWait WaitPage:

class AfterIntroWait(WaitPage):
    @staticmethod
    def after_all_players_arrive(player: Player):
        the_group = player.group
        game_ends(the_group, player)
        
I am getting an error message " TypeError: AfterIntroWait.after_all_players_arrive() got an unexpected keyword argument 'group' "

I'm confused and asking this question here because this was what was going wrong last time. But I made the group variable by using player.group so I don't know what the problem can be. Any help here would be greatly appreciated, thank you.

#4 by xindamate_xyz

Try this

class AfterIntroWait(WaitPage):
    def after_all_players_arrive(self):
        # Access the group directly through self.group
        # Since 'self' refers to the instance of AfterIntroWait,
        # and WaitPage instances are associated with a group
        the_group = self.group
        
        # You need to pick a player to pass to game_ends.
        # If game_ends needs a player object for anything specific,
        # you might need to adjust this. If any player will do,
        # you can simply pick the first one.
        any_player = the_group.get_players()[0]
        
        game_ends(the_group, any_player)



Best regards,
Tina Zheng
Visit our website https://otree.xindamate.xyz/en for more information

Write a reply

Set forum username