Help with a project - UBI experiment

128 views
Skip to first unread message

Ivan Cardoso

unread,
Oct 30, 2021, 7:09:27 AM10/30/21
to oTree help & discussion
Hi there and hope you are all well.

I have a semi complex experiment - to be fair I should have designed a simpler experiment. I'm not that experienced with otree apart from making the standard trust games.

The experiment is a sequential game divided in 2 groups. The first group is divided in 3 where players start with different levels of endowment and then play for 20 rounds (they have the choice to solve a math problem or do nothing and they only get paid if they solve correctly. The second group (treatment groups) are also in 3 groups with different endowment levels and players get paid on every round and they can also be paid if they choose to solve the maths problem.

I've actually have the game that they are playing (I've used Jonas Frey real_effort_numbers) and it does work. What I'm looking for help with is the first part of the experiment: assign players to one of the 2 initial groups (control vs treatment) at random and then create the page "would you like to work for money?.

Let me know if anyone can help with this one

Ivan Cardoso

unread,
Oct 31, 2021, 4:32:45 PM10/31/21
to oTree help & discussion
I've had a prodcutive Sunday to be honest and think I've done some progress.  I currently have the lines of code below (I'm unsure if will run as I want but for now the tests seem ok). My pages.py is a bit long and wondering if I could simplify it but theres a few things that I've not figure out yet. I've been doing this in PyCharm by the way.

1. On my pages, that 'I've defined as **return self.player.id_in_group** I would like this to show only on the first round? This should be possible. Imagine this is a script with only round == 1 which I tried but with no success. Imagine I will also need to generate a page for participants to choose the play or not to play.
2. I've tried to find a solution to give participants a binary choice between (please see the imagine attached, however, I'm not certain how to next_page if true, skip_page if false). Any pointers on this would be very much appreciated.
3. I've not figure out how to attribute the different endowments to the different participants (these are defined under my models/cosntants).
4. The last definition I need to make is the payment for every round. Players with id 1,2 and 3 do not get paid for simply being in a round but players with id 4, 5 and 6 get paid every round. This is respective of the fact of them playing the effort and on top of any other payments. Any ideas?

I'm aware of the complexity of this project.

**models.py**
from otree.api import (
    models,
    widgets,
    BaseConstants,
    BaseSubsession,
    BaseGroup,
    BasePlayer,
    Currency as c,
    currency_range,
)

class Constants(BaseConstants):
    name_in_url = 'real_effort_numbers'
    players_per_group = 6
    num_rounds = 2
    payment_per_correct_answer = 5
    endowment_id_in_group_1_and_4 = c(100)
    endowment_id_in_group_2_and_5 = c(0)
    endowment_id_in_group_3_and_6 = c(-100)
    payment_round_1_2_3 = 0
    payment_round_4_4_5 = 5

class Subsession(BaseSubsession):
    pass

class Group(BaseGroup):

    def creating_session(subsession):
        if subsession.round_number == 1:
            for player in subsession.get_groups():
                participant = player.participant
                participant.groups = random.choice([False])

class Player(BasePlayer):
    number_entered = models.IntegerField()
    sum_of_of_numbers = models.IntegerField()

**pages.py**
from otree.api import Currency as c, currency_range
from ._builtin import Page, WaitPage
from .models import Constants
import random

class control_100(Page):

    def is_displayed(self):
        return self.player.id_in_group == 1

class control_0(Page):

    def is_displayed(self):
        return self.player.id_in_group == 2

class control_minus100(Page):

    def is_displayed(self):
        return self.player.id_in_group == 3

class treatment_100(Page):

    def is_displayed(self):
        return self.player.id_in_group == 4

class treatment_0(Page):

    def is_displayed(self):
        return self.player.id_in_group == 5

class treatment_minus100(Page):

    def is_displayed(self):
        return self.player.id_in_group == 6



class AddNumbers(Page):
    timeout_seconds = 30
    form_model = "player"
    form_fields = ["number_entered"]


    def vars_for_template(self):
        number_1 = random.randint(1, 100)
        number_2 = random.randint(1, 100)
        self.player.sum_of_of_numbers = number_1 + number_2
        return {
            "number_1": number_1,
            "number_2": number_2,
        }

    def before_next_page(self):
        if self.player.sum_of_of_numbers == self.player.number_entered:
            self.player.payoff = Constants.payment_per_correct_answer

class Results(Page):
    pass

class CombinedResults(Page):
    def is_displayed(self):
        return self.round_number == Constants.num_rounds

    def vars_for_template(self):
        all_players = self.player.in_all_rounds()
        combined_payoff = 0
        for player in all_players:
            combined_payoff += player.payoff
        return {
            "combined_payoff": combined_payoff
        }


page_sequence = [control_100, control_0, control_minus100, treatment_100, treatment_0, treatment_minus100, AddNumbers, CombinedResults]
Screenshot 2021-10-31 at 20.27.01.png
Reply all
Reply to author
Forward
0 new messages