from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random doc = """ A demo of how rounds work in oTree, in the context of 'die rolling' """ class Constants(BaseConstants): name_in_url = 'csu_project_cn' players_per_group = 4 num_rounds = 2 dictator_endowment = c(300) public_good_endowment = c(20) public_good_multiplier = 2 class Subsession(BaseSubsession): def creating_session(self): self.group_randomly(fixed_id_in_group=True) # randomize to treatments def vars_for_admin_report(self): contributions = [p.contribution for p in self.get_players() if p.contribution != None] if contributions: return { 'avg_contribution': sum(contributions)/len(contributions), 'min_contribution': min(contributions), 'max_contribution': max(contributions), } else: return { 'avg_contribution': '(no data)', 'min_contribution': '(no data)', 'max_contribution': '(no data)', } class Group(BaseGroup): total_vote_p1 = models.IntegerField() total_vote_p2 = models.IntegerField() total_vote_p3 = models.IntegerField() total_vote_p4 = models.IntegerField() real_leader_offer = models.CurrencyField() total_contribution = models.IntegerField() individual_share = models.CurrencyField() total_public_good_payoffs = models.CurrencyField() group_return = models.CurrencyField() leader_average_contribution = models.CurrencyField() public_good_suggested_amount = models.IntegerField(min=0, max=Constants.public_good_endowment, label='让我们投入') def set_roles(self): self.total_vote_p1 = sum([p.vote_p1 for p in self.get_players()]) self.total_vote_p2 = sum([p.vote_p2 for p in self.get_players()]) self.total_vote_p3 = sum([p.vote_p3 for p in self.get_players()]) self.total_vote_p4 = sum([p.vote_p4 for p in self.get_players()]) max_total_vote = max(self.total_vote_p1, self.total_vote_p2, self.total_vote_p3, self. total_vote_p4) p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p3 = self.get_player_by_id(3) p4 = self.get_player_by_id(4) if self.total_vote_p1 == max_total_vote: p1.is_winner = True p2.is_winner = False p3.is_winner = False p4.is_winner = False p1.role = 'Leader' p2.role = 'Employee1' p3.role = 'Employee2' p4.role = 'Employee3' elif self.total_vote_p2 == max_total_vote: p1.is_winner = False p2.is_winner = True p3.is_winner = False p4.is_winner = False p1.role = 'Employee1' p2.role = 'Leader' p3.role = 'Employee2' p4.role = 'Employee3' elif self.total_vote_p3 == max_total_vote: p1.is_winner = False p2.is_winner = False p3.is_winner = True p4.is_winner = False p1.role = 'Employee1' p2.role = 'Employee2' p3.role = 'Leader' p4.role = 'Employee3' else: p1.is_winner = False p2.is_winner = False p3.is_winner = False p4.is_winner = True p1.role = 'Employee1' p2.role = 'Employee2' p3.role = 'Employee3' p4.role = 'Leader' def set_dictator_payoffs(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p3 = self.get_player_by_id(3) p4 = self.get_player_by_id(4) if p1.is_winner == 1: self.real_leader_offer = p1.dictator_leader_offer p1.dictator_payoffs = Constants.dictator_endowment - p1.dictator_leader_offer - p1.dictator_leader_offer - p1.dictator_leader_offer p2.dictator_payoffs = p1.dictator_leader_offer p3.dictator_payoffs = p1.dictator_leader_offer p4.dictator_payoffs = p1.dictator_leader_offer elif p2.is_winner == 1: self.real_leader_offer = p2.dictator_leader_offer p2.dictator_payoffs = Constants.dictator_endowment - p2.dictator_leader_offer - p2.dictator_leader_offer - p2.dictator_leader_offer p1.dictator_payoffs = p2.dictator_leader_offer p3.dictator_payoffs = p2.dictator_leader_offer p4.dictator_payoffs = p2.dictator_leader_offer elif p3.is_winner == 1: self.real_leader_offer = p3.dictator_leader_offer p3.dictator_payoffs = Constants.dictator_endowment - p3.dictator_leader_offer - p3.dictator_leader_offer - p3.dictator_leader_offer p2.dictator_payoffs = p3.dictator_leader_offer p1.dictator_payoffs = p3.dictator_leader_offer p4.dictator_payoffs = p3.dictator_leader_offer else: self.real_leader_offer = p4.dictator_leader_offer p4.dictator_payoffs = Constants.dictator_endowment - p4.dictator_leader_offer - p4.dictator_leader_offer - p4.dictator_leader_offer p2.dictator_payoffs = p4.dictator_leader_offer p3.dictator_payoffs = p4.dictator_leader_offer p1.dictator_payoffs = p4.dictator_leader_offer def set_public_good_payoffs(self): self.total_contribution = sum([p.contribution for p in self.get_players()]) self.individual_share = self.total_contribution * Constants.public_good_multiplier / Constants.players_per_group for p in self.get_players(): p.public_good_payoffs = (Constants.public_good_endowment - p.contribution) + self.individual_share def set_leader_average_contribution(self): for p in self.get_players(): if p.in_round(1).is_winner == 1: self.leader_average_contribution = (p.in_round(1).contribution + p.in_round(2).contribution)/2 def set_correct_estimation_payoffs(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p3 = self.get_player_by_id(3) p4 = self.get_player_by_id(4) if p1.in_round(1).is_winner == 1: self.leader_average_contribution = (p1.in_round(1).contribution + p1.in_round(2).contribution) / 2 elif p2.in_round(1).is_winner == 1: self.leader_average_contribution = (p2.in_round(1).contribution + p2.in_round(2).contribution) / 2 elif p3.in_round(1).is_winner == 1: self.leader_average_contribution = (p3.in_round(1).contribution + p3.in_round(2).contribution) / 2 elif p4.in_round(1).is_winner == 1: self.leader_average_contribution = (p4.in_round(1).contribution + p4.in_round(2).contribution) / 2 if p1.cooperation_belief == int(self.leader_average_contribution): p1.correct_estimation_payoffs = 30 elif p1.cooperation_belief == (int(self.leader_average_contribution) - 1) or p1.cooperation_belief == ( int(self.leader_average_contribution) + 1): p1.correct_estimation_payoffs = 20 elif p1.cooperation_belief == (int(self.leader_average_contribution) - 2) or p1.cooperation_belief == ( int(self.leader_average_contribution) + 2): p1.correct_estimation_payoffs = 10 else: p1.correct_estimation_payoffs = 0 if p2.cooperation_belief == int(self.leader_average_contribution): p2.correct_estimation_payoffs = 30 elif p2.cooperation_belief == (int(self.leader_average_contribution) - 1) or p2.cooperation_belief == ( int(self.leader_average_contribution) + 1): p2.correct_estimation_payoffs = 20 elif p2.cooperation_belief == (int(self.leader_average_contribution) - 2) or p2.cooperation_belief == ( int(self.leader_average_contribution) + 2): p2.correct_estimation_payoffs = 10 else: p2.correct_estimation_payoffs = 0 if p3.cooperation_belief == int(self.leader_average_contribution): p3.correct_estimation_payoffs = 30 elif p3.cooperation_belief == (int(self.leader_average_contribution) - 1) or p3.cooperation_belief == ( int(self.leader_average_contribution) + 1): p3.correct_estimation_payoffs = 20 elif p3.cooperation_belief == (int(self.leader_average_contribution) - 2) or p3.cooperation_belief == ( int(self.leader_average_contribution) + 2): p3.correct_estimation_payoffs = 10 else: p3.correct_estimation_payoffs = 0 if p4.cooperation_belief == int(self.leader_average_contribution): p4.correct_estimation_payoffs = 30 elif p4.cooperation_belief == (int(self.leader_average_contribution) - 1) or p4.cooperation_belief == ( int(self.leader_average_contribution) + 1): p4.correct_estimation_payoffs = 20 elif p1.cooperation_belief == (int(self.leader_average_contribution) - 2) or p4.cooperation_belief == ( int(self.leader_average_contribution) + 2): p4.correct_estimation_payoffs = 10 else: p4.correct_estimation_payoffs = 0 def set_payoffs(self): for p in self.get_players(): if p.is_winner == 1: p.payoffs = p.in_round(1).public_good_payoffs + p.in_round(2).public_good_payoffs + p.in_round(1).dictator_payoffs p.payoff = 5 + p.payoffs / 10 p.payoffs_convert = 5 + int(p.payoffs)/10 elif p.is_winner != 1: p.payoffs = p.in_round(1).public_good_payoffs + p.in_round( 2).public_good_payoffs + p.in_round(1).dictator_payoffs + p.correct_estimation_payoffs p.payoff = 5 + p.payoffs / 10 p.payoffs_convert = 5 + int(p.payoffs) / 10 class Player(BasePlayer): die_rolling = models.IntegerField(min=1, max=6) experiment_ID = models.IntegerField(min=1, max=24) vote_number = models.IntegerField() group_label = models.StringField() vote_p1 = models.IntegerField(label=' ', min=0, max=5) vote_p2 = models.IntegerField(label=' ', min=0, max=5) vote_p3 = models.IntegerField(label=' ', min=0, max=5) vote_p4 = models.IntegerField(label=' ', min=0, max=5) is_winner = models.BooleanField() role = models.StringField() dictator_leader_offer = models.CurrencyField( doc="""Amount dictator decided to distribute for each of the employees""", min=0, max=Constants.dictator_endowment/3, ) contribution = models.IntegerField(min=0, max=Constants.public_good_endowment) average_contribution = models.CurrencyField() cooperation_belief = models.IntegerField(min=0, max=20, label=' 你的估计是(请输入0-20之间的整数) ') public_good_payoffs = models.CurrencyField() dictator_payoffs = models.CurrencyField() payoffs = models.CurrencyField() correct_estimation_payoffs = models.IntegerField() payoffs_convert = models.FloatField() age = models.IntegerField( label='出生年份', min=1940, max=2001) gender = models.StringField( choices=['男性', '女性'], label='性别', widget=widgets.RadioSelect) grade = models.StringField( choices=['一年级', '二年级', '三年级', '四年级', '五年级'], label='你的年级', widget=widgets.RadioSelect) ethnic = models.StringField( choices=['汉族', '少数民族'], label='民族', widget=widgets.RadioSelect) major = models.StringField( label='''学院 ''' ) def group_label(self): if self.id_in_group == 1: return 'A' elif self.id_in_group == 2: return 'B' elif self.id_in_group == 3: return 'C' else: return 'D' def vote_number(self): if self.die_rolling == 1: return '1' elif self.die_rolling == 2: return '1' elif self.die_rolling == 3: return '1' elif self.die_rolling == 4: return '3' elif self.die_rolling == 5: return '5' else: return '0'