from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random import pandas as pd import itertools author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'payment' players_per_group = 10 num_rounds = 1 df = pd.read_csv('_static/game_parameters.csv') class Subsession(BaseSubsession): def creating_session(self): # total number of rounds for the decision tasks, set to 13 in Constants in actual experiment!! available_rounds = [i + 1 for i in range(self.session.config['total_rounds'])] num_rounds_for_payment = self.session.config['num_rounds_for_payment'] num_others_in_group = self.session.config['num_others'] for p in self.get_players(): # randomly select the payment rounds p.participant.vars['payment_rounds'] = random.sample(available_rounds, num_rounds_for_payment) # randomly select group members others_index = [i for i in range(Constants.players_per_group - 1)] p.participant.vars['payment_others_index'] = itertools.cycle( [random.sample(others_index, num_others_in_group) for i in range(num_rounds_for_payment)]) p.participant.vars['random_number'] = random.randint(0, 100) # if p.participant.id_in_session == 1: # p.participant.vars['work_history'] = [[1, True], [2, False], [4, True], [5, False], [3, True]] # elif p.participant.id_in_session == 2: # p.participant.vars['work_history'] = [[5, True], [4, False], [3, True], [1, True], [2, True]] # else: # p.participant.vars['work_history'] = [[1, True], [5, False], [4, False], [3, True], [2, True]] class Group(BaseGroup): pass class Player(BasePlayer): round_selected = models.LongStringField() work_choices = models.LongStringField() infection = models.LongStringField() payoffs_selected = models.LongStringField() matched_other_id = models.LongStringField() def set_payoff(self): # print('my work history in payment app is', self.participant.vars['work_history']) # randomly select the payment_rounds payment_rounds = self.participant.vars['payment_rounds'] payment_rounds.sort() # print('Participant', self.participant.id_in_session, 'Payment rounds are', payment_rounds) # get the others in the session pool = self.get_others_in_group() # print('the number of others in the group is', len(pool)) # for each of the selected rounds, calculate payoff my_work_choices = [] my_num_others_work = [] my_is_infected = [] my_payoffs = [] my_matched_others_id = [] for r in payment_rounds: # for each selected rounds, randomly select other members from the pool index = next(self.participant.vars['payment_others_index']) # print('The index for others in group are:', index) others = [pool[i] for i in index] # for p in others: # print('my other group members\' work history in payment app is', p.participant.vars['work_history']) others_participant_id = [p.participant.id_in_session for p in others] my_matched_others_id.append(others_participant_id) ### longer way to do the nested loop to find out others in the group # others_work_choices = [] # for p in others: # for period in p.participant.vars['work_history']: # if period[0] == r: # others_work_choices.append(period[1]) others_work_choices = [period[1] for p in others for period in p.participant.vars['work_history'] if period[0] == r] num_work = sum(others_work_choices) my_num_others_work.append(num_work) selected_row = Constants.df[ (Constants.df['round number'] == r) & (Constants.df['no of people working'] == num_work)] # print('my work history in payment app is', self.participant.vars['work_history']) my_work = [period[1] for period in self.participant.vars['work_history'] if period[0] == r][0] # print('I choose to work', my_work) my_work_choices.append(my_work) if my_work: probability = selected_row['prob'].values number = self.participant.vars['random_number'] if number > probability * 100: pay = selected_row['payoff not infected'].values.tolist() my_is_infected.append(False) # print('Participant', self.participant.id_in_session, 'in round', r, 'worked and is not infected. ' # 'The payoff is', pay) else: pay = selected_row['payoff infected'].values.tolist() my_is_infected.append(True) # print('Participant', self.participant.id_in_session, 'in round', r, 'worked and is infected. ' # 'The payoff is', pay) else: pay = selected_row['payoff home'].values.tolist() my_is_infected.append('NA') # print('Participant', self.participant.id_in_session, 'in round', r, 'stay home. ' # 'The payoff is', pay) # print('my payoff in round ', r, ' is', pay[0]) my_payoffs.append(pay[0]) self.payoff = sum(my_payoffs) return payment_rounds, my_work_choices, my_num_others_work, my_is_infected, my_payoffs, my_matched_others_id def set_initial_value(self): self.round_selected = '' self.work_choices = '' self.infection = '' self.payoffs_selected = '' self.matched_other_id = '' def set_participant_payoff(self): if self.participant.payoff.to_real_world_currency(self.session) + self.session.config['participation_fee'] < 0: self.participant.payoff = c(- self.session.config['participation_fee'] \ / self.session.config['real_world_currency_per_point'])