oTree Forum >

Payment of randomly selected round - connection between round and reward doesn't work correctly

#1 by Janina

Dear all,

I want to pay a randomly selected round in my experiment.
But I am having some trouble for the payment, if the last last round is selected. If the last round is randomly chosen, the initial set value for the reward is displayed but not the correct one.  I think it may be due to the counting or the connection between both variables. Unfortunately, I have not found a solution while trying different approaches.

This is my code:

if player.round_number == C.NUM_ROUNDS:
    random_round = random.randint(1, C.NUM_ROUNDS)
    player.selected_round = random_round
    player_in_selected_round = player.in_round(random_round)
    player.roundpayment = player_in_selected_round.reward
    
Do you know how I could fix this (maybe add some +1/-1 somewhere) or do you have another solution that would work?

I would be very grateful!

Cheers
Janina

#2 by ccrabbe

Hi Janina -

My best advice on troubleshooting things like this is to insert print statements into your python code, so that you can see the values of all your variables at each step along the way, and then check to see where they start going wrong.

For this case, I'd have one print statement for the current round number, another for the random_round, another for the roundpayment, etc.

The one thing that I can think of which may cause the situation you're describing is:  where in your project is this code snippet located?  If it's somewhere in the execution chain before you calculate "reward" then you're setting the value of "roundpayment" before you set the new value of "reward" so of course it still has its initial value.  This would only happen if random_round==C.NUM_ROUNDS.

Thanks,
--Chris

#3 by rajib_jnu

I coded like the following and it did work for me:

class Results1(Page):
   
    @staticmethod
    def before_next_page(player: Player, timeout_happened):
        import random

        participant = player.participant

        # if it's the last round
        if player.round_number == C.NUM_ROUNDS:
            random_round = random.randint(2, C.NUM_ROUNDS)             [# here I used 2 as my first round was practice round]
            participant.selected_round = random_round
            player_in_selected_round = player.in_round(random_round)
            player.payoff_final = float(player_in_selected_round.payoff)
            participant.payoff = player.payoff_final

    def vars_for_template(player: Player):
        return dict(me_in_all_rounds=player.in_all_rounds(), contribution=player.contribution, payoff=player.payoff,
                    transfer_amount = player.transfer_amount)

class Payoff(Page):
    @staticmethod
    def is_displayed(player: Player):
        return player.round_number == C.NUM_ROUNDS

#4 by Janina

Dear Chris and Rajib,

thank you very much for your help!!
It worked.

Cheers
Janina

#5 by sakib_anwar

Hi all,

I have a related question to the question above. 
I am running public goods experiment. I want to random round for payment. When I adopt the code above, my random_round is different for every player.
How do I get the same random round for every player?

My code is below:
class Results(Page):
    @staticmethod
    def before_next_page(player: Player, timeout_happened):
        import random

        participant = player.participant

        # if it's the last round
        if player.round_number == C.NUM_ROUNDS:
            random_round = random.randint(1, C.NUM_ROUNDS)
            participant.selected_round = random_round
            # player_in_selected_round = player.in_round(random_round)
            # player.payoff = C.ENDOWMENT - player_in_selected_round.give_amount
            player_in_selected_round = player.in_round(random_round)
            participant.payoff = player_in_selected_round.payoff

class FinalResults(Page):
    body_text='You finished the experiment'
    @staticmethod
    def vars_for_template(player):
        participant = player.participant
        # random_round=random.randint(1, C.NUM_ROUNDS)
        return dict (
            my_cont=player.in_round(participant.selected_round).contribution,
            tc=player.in_round(participant.selected_round).group.total_contribution,
            mypayoff=player.in_round(participant.selected_round).payoff,
            payoff_round=participant.selected_round,
            earnings=participant.payoff_plus_participation_fee()
        )

    def is_displayed(player):
        return player.round_number==C.NUM_ROUNDS

#6 by Chris_oTree

In creating_session choose a random round then assign it to all players in subsession.get_players()

#7 by sakib_anwar

Hi Chris,
Thanks for the quick response. I tried the following, but it gave the same result as before. I think this is what you suggested.
def creating_session(subsession):
    subsession.group_randomly()
    
    import random

    for p in subsession.get_players():
        p.participant.selected_round = random.randint(1, C.NUM_ROUNDS)
        
 here 'selected round' is stored in the PARTICIPANT_FIELDS. Do I need to store in SESSIONS_FIELD?
 Best,
 Sakib

Write a reply

Set forum username