Session VI - Group Decisions
IMPRS Be Smart Summer School
2023-08-08
We have covered individual experiments so far.
Create Player
fields for the variables written in the data
Create Pages
for each page we will see and add fields with form_fields
Create/modify the templates for each page. (PageName.html
, AnotherPage.html
)
Homogenous Groups
All players have the same role.
They see the same pages.
Heterogenous Groups
Players are in some set of roles.
They see different pages based on their roles.
Aspect | Individual Task | Group Task |
---|---|---|
Pages | My own pace | Sometimes have to wait for others |
Variables / Calculations | My own variables | Need to reach other players’ variables |
PageSequence
list at the bottom but you don’t need to create a template.__init__.py
:
They are manage objects which represent players/groups/the constants and handle database entries.
Four built-in models:
Player
: Parameters that are unique for each individual.
Group
: Parameters that are unique for the group, same for each individual in the group.
Constants
: Parameters that are the same for the experiment.
Subsession
: Parameters that are same for the “subsession”. More often used to initiate some specific settings. We will see it next week.
Player
and Group
classesRemember, classes are like blueprints
They are capitalized. (Player
, Group
)
Instances of classes (objects) are not capitalized. (player
, group
)
We deal with instances in computations.
Player
and Group
classesThey have some attributes(variables)
They have some built-in functions(methods) too
We can also define top-level functions to interact with them.
We can reach from one object to another.
some_list = group.get_players()
some_list[0]
, some_list[1]
, some_list[2]
otree startapp pgg
settings.py
.Page | Description |
---|---|
Contribution |
Contribute screen |
Results |
Results screen |
Page | Description |
---|---|
Contribution |
Contribute screen |
ResultsWaitPage |
Waiting page |
Results |
Results screen |
Variable | Model | Type | |
---|---|---|---|
contribution |
Player |
CurrencyField() |
Player’s contribution |
ENDOWMENT |
C Constants |
Currency (cu ) |
Initial endowment |
MULTIPLIER |
C C |
Integer | Multiplier for contributions |
We should think of group fields as the variables that are the same for all players in the group.
total_contribution
individual_share
(not strictly necessary but useful for a cleaner calculation)
Variable | Model | Type | |
---|---|---|---|
contribution |
Player |
CurrencyField() |
Player’s contribution |
payoff |
Player |
CurrencyField() |
Player’s payoff |
ENDOWMENT |
C Constants |
Currency (cu ) |
Initial endowment |
MULTIPLIER |
C C |
Integer | Multiplier for contributions |
total_contribution |
Group |
CurrencyField() |
Total contribution of the group |
individual_share |
Group |
CurrencyField() |
Individual share of the group |
Currency
and payoff
built-in features in oTreeCurrency
payoff
fieldsettings.py
controls the conversion rate.USE_POINTS
and REAL_WORLD_CURRENCY_CODE
variables.set_payoffs
function. (name is not important)group
as an argument (as opposed to player
)group
to reach to players in the group.set_payoffs
def set_payoffs(group):
print("my function set payoffs worked!")
players = group.get_players()
contributions = []
for p in players:
contributions.append(p.contribution)
group.total_contribution = sum(contributions)
group.individual_share = group.total_contribution * C.MULTIPLIER / C.PLAYERS_PER_GROUP
for p in players:
p.payoff = C.ENDOWMENT - p.contribution + group.individual_share
set_payoffs
In the individal experiment, we triggered it by defining before_next_page
function inside a page.
This time we will trigger it from ResultsWaitPage
.
set_payoffs
in a WaitPageOption 1: Define a function and give the function name to after_all_players_arrive
attribute.
Option 2: Just give the function name to after_all_players_arrive
variable.
Templates have access to player
, group
and Constants
variables.
Your guess was {{ player.guess }}.
Your group decided on {{ group.decision }}
The reward was {{ Constants.reward }}
You will get {{session.config.participation_fee}} for participating.
You can show less digits of decimals with | to0
, |to1
, |to2
.
Results.html
{{ block title }}
Results
{{ endblock }}
{{ block content }}
<p> You contributed {{ player.contribution }} </p>
<p> The total contribution was {{ group.total_contribution }} </p>
<p> Each person got {{ group.individual_share }} from the group project </p>
<p> And your final payoff was {{ player.payoff }} </p>
{{ next_button }}
{{ endblock }}
Remember: Steps to create a new page:
Page
: Welcome(Page)
page_sequence
Take the Public Goods Game we used. Do the following:
Set the number of rounds to 3
Add a Welcome page and add some welcome messages to it. Make it visible only on the first page (hint: look at the documentation for is_displayed)
Show the contributions of other players in the group (including or excluding myself) Hint:
Path 1: You can create a list of contributions and input it into the template. Then you need to check vars_for_template in the documentation.
Path 2: You can loop over the players in the group in the template. Check {{ for p in group.get_players }} in the documentation. This is the template version of group.get_players().
Built in method is_displayed(player)
should be defined under the page class.
This method should return True
or False
(or None
)
If this method returns True
for current player, the page is displayed. Otherwise, it will not.
If there are any calculations triggered by page, they will be skipped as well.
player.round_number
is a built-in variable in oTree.group
and subsession
.{{ for p in group.get_players }}
Player {{ p.id_in_group }} contributed {{ p.contribution }}.
{{ endfor }}
Player 1 contributed 10 points. Player 2 contributed 30 points. Player 3 contributed 40 points.
{{ for p in group.get_players }}
{{ if p == player }}
You contributed {{ p.contribution }}.
{{ else }}
Player {{ p.id_in_group }} contributed {{ p.contribution }}.
{{ endif }}
{{ endfor }}
Player 1 contributed 10 points. Player 2 contributed 30 points. You contributed 40 points.
vars_for_template
{{ variable_to_show }}
class Results(Page):
def vars_for_template(player):
other_players = player.get_others_in_group()
other_contributions = [p.contribution for p in other_players]
return dict(
other_contributions=other_contributions
)
{{ other_contributions }}
[ 10, 20 ]
Prisoners’ Dilemma
Cooperate | Defect | |
---|---|---|
Cooperate | 2, 2 | 0, 3 |
Defect | 3, 0 | 1, 1 |