oTree Forum >

Displaying information of players to all the players in the session

#1 by AB_123

Hi there,

Belated happy new year. I have been trying to solve this problem for three days but to no avail. This is the second time I am coding an experiment on oTree, so I am still relatively new to this.  What I have been trying to do is to reveal certain information on the players if they consent to do so to all the players in that session. The information does not reveal the identities of the players, the information is just on donations of the players. However, what is happening is that each player can see information on their individual donations but they can't see the information of other players in the session who have consented. It will be great of you can help me. The codes I am using are below:

class C(BaseConstants):
    NAME_IN_URL = 'donation_status'
    PLAYERS_PER_GROUP = None
    NUM_ROUNDS = 1
    ENDOWMENT = 10
    
class DataCollector:
    @staticmethod
    def collect_player_data(session):
        participants = session.get_participants()
        data = []  # List to collect players' data

        for participant in participants:
            player = participant.get_players()[0]  # Access the player object correctly
            if player.anonymity:
                player_data = {
                    'charities': player.charities,
                    'donation_willing': player.donation_willing,
                }
                data.append(player_data)

        return {
            'players': data
        }

class Player(BasePlayer):
    
    charities = models.StringField(
        choices=['0', '1', '2', '3', '4', '5', 'More than 5'],
        label='On average, how many charities do you donate to annually?',
        widget=widgets.RadioSelect,
    )
   
    donation_willing = models.StringField(
        choices=['£0', '£1', '£2', '£3', '£4', '£5', '£6', '£7', '£8', '£9', '£10'],
        label='Out of £10, how much do you plan to donate today to the charity?',
        widget=widgets.RadioSelect,
    )
    anonymity = models.BooleanField(
        label="Would you like to reveal the number of charitable organisations you donate to annually  and how much you "
              "plan to donate today to the other participants in this session. Your decision will be revealed after "
              "the participants have made their donations.",
        choices=[
            [True, "Yes"],
            [False, "No"],
        ],
        widget=widgets.RadioSelect,
    )
    
    @staticmethod
    def vars_for_template(session):
        return DataCollector.collect_player_data(session)


# PAGES
class Donations(Page):
    form_model = 'player'
    form_fields = ['charities', 'donation_freq', 'donation_amount', 'donation_willing', 'anonymity']
    
class Anonymity(Page):
    form_model = 'player'
    form_fields = ['charities', 'donation_willing']
    
 And then, in the html page, the code is:
 {% extends "global/Page.html" %}
{% block content %}
    <table border="1">
        <thead>
            <tr>
                <th>Number of charitable organisations the participant donate to annually on average</th>
                <th>Amount of money participant plans to donate today to the charity</th>
            </tr>
        </thead>
        <tbody>
                <tr>
                    <td>{{ player.charities }}</td>
                    <td>{{ player.donation_willing }}</td>
                </tr>
        </tbody>
    </table>
{% endblock %}

#2 by woodsd42

Put in some print statements in the collect_player_data() function - this should indicate where the problems lie.

See https://otree.readthedocs.io/en/latest/tutorial/part2.html?roubleshoot-with-print#troubleshoot-with-print

#3 by BonnEconLab

Your code is incorrect in several places: (1) the definition of collect_player_data, (2) the use of vars_for_template, and (3) the variables that you use in the HTML template to create the table.

Here is code that works (also attached as a ZIP file) according to my testing (I set `num_demo_participants = 3` in the settings.py file):


#######################
####  __init__.py  ####
#######################


from otree.api import *


doc = """
Displaying information of players to all the players in the session (https://www.otreehub.com/forum/1300/)
"""


class C(BaseConstants):

    NAME_IN_URL = 'donation_status'
    PLAYERS_PER_GROUP = None
    NUM_ROUNDS = 3
    ENDOWMENT = 10


class Subsession(BaseSubsession):

    pass


class Group(BaseGroup):

    pass


class DataCollector:

    @staticmethod
    #def collect_player_data(session):
        #participants = session.get_participants()
        #for participant in participants:
            #player = participant.get_players()[0]  # Access the player object correctly
            # This works only if there is no more than a single round.
    def collect_player_data(subsession):
        all_players = subsession.get_players()
        data = []  # List to collect players' data
        for player in all_players:
            print(player)
            if player.anonymity == False:
                player_data = {
                    'id': player.id_in_subsession,
                    'charities': player.charities,
                    'donation_willing': player.donation_willing,
                }
            else:
                player_data = {
                    'id': player.id_in_subsession,
                    'charities': 'Not disclosed',
                    'donation_willing': 'Not disclosed',
                }
            data.append(player_data)
        return {
            'players': data,
        }


class Player(BasePlayer):
    
    charities = models.StringField(
        choices=['0', '1', '2', '3', '4', '5', 'More than 5'],
        label='On average, how many charities do you donate to annually?',
        widget=widgets.RadioSelectHorizontal,
    )  
    donation_willing = models.StringField(
        choices=['£0', '£1', '£2', '£3', '£4', '£5', '£6', '£7', '£8', '£9', '£10'],
        label='Out of £10, how much do you plan to donate today to the charity?',
        widget=widgets.RadioSelectHorizontal,
    )
    anonymity = models.BooleanField(
        label=
            'Would you like to reveal the number of charitable organisations you donate to annually and how much you '
            'plan to donate today to the other participants in this session? Your decision will be revealed after '
            'the participants have made their donations.',
        choices=[
            [False, 'Yes'],
            [True, 'No'],
        ],
        widget=widgets.RadioSelectHorizontal,
    )
    donation_freq = models.IntegerField(
        choices=range(0, 5),
        label='How often do you intend to donate to the charity?',
        widget=widgets.RadioSelectHorizontal,
    )
    donation_amount = models.IntegerField(
        choices=[[x, '£' + str(x)] for x in range(0, 11)],
        label='How much will you actually donate to the charity?',
        widget=widgets.RadioSelectHorizontal,
    )


# PAGES


class Donations(Page):

    form_model = 'player'
    form_fields = ['charities', 'donation_freq', 'donation_amount', 'donation_willing', 'anonymity']


class ResultsWaitPage(WaitPage):

    pass


class Results(Page):

    @staticmethod
    def vars_for_template(player):
        return DataCollector.collect_player_data(player.subsession)


# PAGE SEQUENCE


page_sequence = [
    Donations,
    ResultsWaitPage,
    Results,
]


########################
####  Results.html  ####
########################


{{ block title }}

Overview of all players’ decisions

{{ endblock }}


{{ block content }}

<table class="table">
    <thead>
        <tr>
            <th class="col-2 ps-0">Participant ID</th>
            <th class="col-4">Number of charitable organisations the participant donates to annually on average</th>
            <th class="col-4">Amount of money participant plans to donate today to the charity</th>
        </tr>
    </thead>
    <tbody>
        {% for player_info in players %}
            <tr>
                <td class="ps-0">{{ player_info.id }}
                    {% if player.id_in_subsession == player_info.id %}
                        (you)
                    {% endif %}
                </td>
                <td>{{ player_info.charities }}</td>
                <td>{{ player_info.donation_willing }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<p>{{ next_button }}</p>

{{ endblock }}

#4 by AB_123

@BonnEconLab Thank you so much, it worked. I was under the impression from my reading that I can only use subsession when my experiment has multiple rounds. I suppose I was wrong.
@woodsd42 Thank you so much for your advice. I think I should start using the print function more. I was not sure how to use it. But now that I know, I will try using it more often.

Write a reply

Set forum username