Cumulative Payoff for other players in all rounds

582 views
Skip to first unread message

John Khoo

unread,
Apr 4, 2021, 3:12:50 AM4/4/21
to oTree help & discussion

Hi there,


I'm trying to display a cumulative payoff for all players in a Results page.

I've managed to get to this extent in the ResultsPage attachment, where the cumulative payoff for the player's own self can be displayed, but not for other players:
Snippet from Results.html:

<table class="table">
<thead>
<tr>
<th>Participant</th>
<th>Decision</th>
<th>Current Round Payoff</th>
<th>Total Payoff</th>
</tr>
</thead>
<tr>
<td>Participant {{ player.id_in_group }} {{ player.participant.label }} (You) </td>
<td>{{ player.get_decision_display }}</td>
<td>{{ player.payoff }}</td>
<td>{{ player.total_payoff }}</td>
</tr>
{% for p in player.get_others_in_group %}
<tr>
<td>Participant {{ p.id_in_group }}</td>
<td>{{ p.get_decision_display }}</td>
<td>{{ p.payoff }}</td>
<td>{{ p.total_others_payoff }}</td>
</tr>
{% endfor %}
</table>

Snippet of Results class from pages.py

class Results(Page):
# timeout_seconds = 10

def vars_for_template(self):
me = self.player
opponent = me.other_player()
return dict(
my_decision=me.decision,
opponent_decision=opponent.decision,
same_choice=me.decision == opponent.decision,
)

# method to cumulatively sums all payoff (total_payoff) for self.player in all rounds
def vars_for_template(self):
if self.round_number > 1:
cumul = sum([p.payoff for p in self.player.in_all_rounds()])
else:
cumul = self.player.payoff

self.player.total_payoff = cumul

# attempting to cumulatively sum all payoff for other players in all rounds
def vars_for_template(self):
if self.round_number > 1:
cumulothers = sum([p.payoff for p in self.player.other_player.in_all_rounds()])
else:
cumulothers = self.player.other_player.payoff
# cumulothers = [p.payoff for p in self.player.other_player]

self.player.other_player.total_others_payoff = cumulothers
I think I'm making a mistake in this section

Snippet from models.py in Player class

class Player(BasePlayer):

decision = models.BooleanField(
choices=[
[False, 'Cooperate'],
[True, 'Defect']
])

name = models.StringField(label="Please enter your name", blank=True)

total_payoff = models.CurrencyField()
total_others_payoff = models.CurrencyField()

def prev_player(self):
prev_player = self.in_round(self.round_number - 1)
print('previous payoff', prev_player.payoff)

def set_label(self):
# use player.participant.label to carry forward participant info in Pages
self.participant.label = self.name
print('participant label:', self.participant.label)

def get_name(self):
name = self.participant.label
if name is None:
name = ""
return name

def other_player(self):
return self.get_others_in_group()[0]
# do we need to add in further definitions for other_player.payoff here?

def set_payoff(self):
others_defect = sum([p.decision for p in self.get_others_in_group()])
self.payoff = 10 + 5 * self.decision - 15 * others_defect

I may need to define an additional method like def set_others_payoff where payoff for other players is calculated? But I'm unsure of how to do this.


Text in green above are what I suspect play an important role in allowing me to display p.total_others_payoff. The app will run into the error in the ErrorArResultsPage attachment when it gets to the Results page.


I'm happy to hear any suggestions you all may have on this.

Regards
John



ErrorAtResultsPage.png
ResultsPage.png

Vic vP

unread,
Apr 4, 2021, 6:20:30 AM4/4/21
to oTree help & discussion
Hi John,

I am just wondering something. Doesn't oTree store the temporary cumulative payoff for each participant under "participant.payoff"?
I am not completely sure because it could just be doing that at the end. 

A thought for displaying other participants' cumulative payoffs: Personally, I would try to store data on the group level each round. 
Can't you create currency fields on the group level each round (also perhaps cumulative)? This could be easier to access later.

Best,

Victor
Reply all
Reply to author
Forward
0 new messages