import random from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) from .machine_learning_algo import prediction_generator doc = """ This is a standard 2-player trust game where the amount sent by player 1 gets tripled. The trust game was first proposed by Berg, Dickhaut, and McCabe (1995) . """ ############################################################ # definition of constant variables ############################################################ class Constants(BaseConstants): name_in_url = 'trust_machine_learning' players_per_group = 2 num_rounds = 1 payoff_stage = random.randint(1, 2) payoff_round = random.randint(1, num_rounds) relevant_decision = random.randint(1, 2) Treatment = 1 page_sequence = random.randint(1,10) instructions_template = 'final_design_ak/instructions.html' instructions_SPD = 'final_design_ak/instructions_SPD.html' machine_learning_info = 'final_design_ak/machine_learning_info.html' # Initial amount allocated to each player endowment = 10 multiplier = 3 ############################################################ # Random assignment of subsession level, i.e. ROUND ############################################################ class Subsession(BaseSubsession): #keeping track of the current round #in round == 1 there will be no machine #in round == 2 there will be a machine #current_round = Constants.num_rounds #groupng and matching players randomly each round def creating_session(self): self.group_randomly() ############################################################ # GROUP LEVEL VARIABLES AND METHODS ############################################################ class Group(BaseGroup): #FOR METHOD ALL PLAYERS ARRIVE FUNCTIONS NEED TO BE CALLED VIA GROUPS #THEREFORE GROUP CALLS FUNCTION FOR EACH INDIVIDUAL PLAYER IN THE GROUP def set_payoffs(self): for p in self.get_players(): p.set_payoff() def functions(self): for p in self.get_players(): p.function() def functions_oppo(self): for p in self.get_players(): p.function_oppo() def set_payoffs_SPD(self): for p in self.get_players(): p.payoffs_SPD() def set_payoffs_trust_no_machine(self): for p in self.get_players(): p.payoffs_trust_no_machine() def set_payoffs_trust_machine(self): for p in self.get_players(): p.payoffs_trust_machine() ############################################################ # SUBJECT LEVEL VARIABLES AND METHODS ############################################################ class Player(BasePlayer): ############################### # SEQUENTIAL PD ############################### # SPD DECISION FIRST MOVER sent_amount_SPD = models.IntegerField( choices=[[0, 'Option A (keep your 10 points)'], [10, 'Option B (send your 10 points)']], widget=widgets.RadioSelect, label='Please make a choice' ) # SPD DECISIONS SECOND MOVER # FM DEFECTS sent_back_amount_SPD_defect = models.IntegerField( choices=[[0, 'Option A (keep your 10 points)'], [10, 'Option B (send your 10 points)']], widget=widgets.RadioSelect, label='Please make a choice' ) #FM COOPERATE sent_back_amount_SPD_coop = models.IntegerField( choices=[[0, 'Option A (keep your 10 points)'], [10, 'Option B (send your 10 points)']], widget=widgets.RadioSelect, label='Please make a choice' ) ############################### # ML APPLICATION ############################### # RELEVANT VARIABLES FOR MACHINE LEARNING APPLICATION order = models.IntegerField(initial=Constants.payoff_stage) prediction = models.IntegerField(initial=-1) prediction_oppo = models.IntegerField(initial=-1) #payoffs SPD payoff_spd = models.IntegerField(initial=-1) role_spd = models.IntegerField(initial=-1) dec_opponent_spd = models.IntegerField(initial=-1) dec_spd = models.IntegerField(initial=-1) #payoffs Trust without machine payoff_trust_no_machine = models.IntegerField(initial=-1) role_trust_no_machine = models.IntegerField(initial=-1) dec_opponent_trust_no_machine = models.IntegerField(initial=-1) dec_trust_no_machine = models.IntegerField(initial=-1) #payoffs Trust with machine payoff_trust_machine = models.IntegerField(initial=-1) role_trust_machine = models.IntegerField(initial=-1) dec_opponent_trust_machine = models.IntegerField(initial=-1) dec_trust_machine = models.IntegerField(initial=-1) #income income = models.FloatField(initial=-1) ############################### # ML QUESTIONNAIRE ############################### # QUESIONNAIRE ITEMS #NOTE: q_1 is an integer field for calucations in prediction dummy # impotant to write a function that transforms the types into the ones that the machine learning apliation needs q_1 = models.IntegerField(label='Wo sind Sie geboren?') q_2 = models.StringField(label='Haben Sie die Mathematikabitur Prüfung abgelegt?') q_3 = models.StringField(label='Q3?') q_4 = models.StringField(label='Q4?') q_5 = models.StringField(label='Q5?') q_6 = models.StringField(label='Q6?') q_7 = models.StringField(label='Q7?') q_8 = models.StringField(label='Q8?') q_9 = models.StringField(label='Q9?') ############################### # TRUST GAME NO MACHINE ############################### #FIRST MOVER DECISIONS - TRUST GAME sent_amount = models.IntegerField( choices=[[0, 'Option 1 (keep your 10 points)'], [10, 'Option 2 (send your 10 points)']], widget=widgets.RadioSelect, label='Please make a choice' ) sent_back_amount_no_machine = models.IntegerField( doc="""Amount sent back by P2 given P1 sent 1""", min=0, max=30, label='Please make a choice' ) ############################### # TRUST GAME WITH MACHINE ############################### sent_amount_with_machine = models.IntegerField( choices=[[0, 'Option 1 (keep your 10 points)'], [10, 'Option 2 (send your 10 points)']], widget=widgets.RadioSelect, label='Please make a choice' ) #SECOND MOVER DECISIONS - TRUST GAME sent_back_amount_machine_trust = models.IntegerField( doc="""Amount sent back by P2 given P1 sent 2""", min=0, max=30, label='Please make a choice' ) sent_back_amount_machine_no_trust = models.IntegerField( doc="""Amount sent back by P2 given P1 sent 3""", min=0, max=30, label='Please make a choice' ) #DETERMINING IDENTITY OF OPPONENT def other_player(self): return self.get_others_in_group()[0] #DUMMY FUNCTION FOR MAKING PREDICTIONS # 1 = TRUSTWORHTY # 0 = NOT TRUSTWORTHY #NOTE: DEPENDING ON THE NATURE OF INPUTS I NEED TO BE CAREFUL WITH CALCULATIONS def function(self): #if values are not passed on across rounds there will be a none value x = [self.q_1, self.q_2, self.q_3, self.q_4, self.q_5] # prediction gives out a value y = prediction_generator(x) #soft max if y>10: self.prediction = 1 else: self.prediction = 0 def function_oppo(self): self.prediction_oppo = self.other_player().prediction #??? def prediction_opponent(self): return self.other_player().prediction #payoffs SPD def payoffs_SPD(self): if self.id_in_group == 1: self.role_spd = 1 self.dec_spd = self.sent_amount_SPD if self.sent_amount_SPD == 0: self.dec_opponent_spd = self.other_player().sent_back_amount_SPD_defect self.payoff_spd = 10 + 2*self.other_player().sent_back_amount_SPD_defect elif self.sent_amount_SPD == 10: self.dec_opponent_spd = self.other_player().sent_back_amount_SPD_coop self.payoff_spd = 0 + 2*self.other_player().sent_back_amount_SPD_coop elif self.id_in_group == 2: self.dec_opponent_spd = self.other_player().sent_amount_SPD self.role_spd = 2 if self.other_player().sent_amount_SPD == 0: self.dec_spd = self.sent_back_amount_SPD_defect self.payoff_spd = 0 + (10-self.sent_back_amount_SPD_defect) elif self.other_player().sent_amount_SPD == 10: self.dec_spd = self.sent_back_amount_SPD_coop self.payoff_spd = 20 + (10 - self.sent_back_amount_SPD_coop) #payoffs trust no machine def payoffs_trust_no_machine(self): if self.id_in_group == 1: self.role_trust_no_machine = 1 self.dec_trust_no_machine = self.sent_amount if self.sent_amount == 0: self.dec_opponent_trust_no_machine = 0 self.payoff_trust_no_machine = 10 elif self.sent_amount == 10: self.dec_opponent_trust_no_machine = self.other_player().sent_back_amount_no_machine self.payoff_trust_no_machine = self.other_player().sent_back_amount_no_machine if self.id_in_group == 2: self.dec_opponent_trust_no_machine = self.other_player().sent_amount self.role_trust_no_machine = 2 if self.other_player().sent_amount == 0: self.dec_trust_no_machine = 0 self.payoff_trust_no_machine = 0 elif self.other_player().sent_amount == 10: self.dec_trust_no_machine = self.sent_back_amount_no_machine self.payoff_trust_no_machine = 30 - self.sent_back_amount_no_machine #payoffs machine trust def payoffs_trust_machine(self): if self.id_in_group == 1: self.role_trust_machine = 1 self.dec_trust_machine = self.sent_amount_with_machine if self.sent_amount_with_machine == 0: self.dec_opponent_trust_machine = 0 self.payoff_trust_machine = 10 elif self.sent_amount_with_machine == 10: if self.prediction_oppo == 1: self.dec_opponent_trust_machine = self.other_player().sent_back_amount_machine_trust self.payoff_trust_machine = self.other_player().sent_back_amount_machine_trust elif self.prediction_oppo == 0: self.dec_opponent_trust_machine = self.other_player().sent_back_amount_machine_no_trust self.payoff_trust_machine = self.other_player().sent_back_amount_machine_no_trust elif self.id_in_group == 2: self.dec_opponent_trust_machine = self.other_player().sent_amount_with_machine self.role_trust_machine = 2 if self.other_player().sent_amount_with_machine == 0: self.dec_trust_machine = 0 self.payoff_trust_machine = 0 elif self.other_player().sent_amount_with_machine == 10: if self.prediction == 1: self.dec_trust_machine = self.sent_back_amount_machine_trust self.payoff_trust_machine = 30 - self.sent_back_amount_machine_trust elif self.prediction == 0: self.dec_trust_machine = self.sent_back_amount_machine_no_trust self.payoff_trust_machine = 30 - self.sent_back_amount_machine_no_trust #SETTING PAYOFFS def set_payoff(self): self.income = (self.payoff_trust_machine + self.payoff_trust_no_machine + self.payoff_spd) *0.25