import random from otree.api import * doc = """ Read questions from a CSV (simple version). Costly answers in statements. Akdeniz & Mathew, 2022, Normative versus prosocial underpinnings of human decision making. """ def read_csv(subsession): import csv session = subsession.session country = session.config.get("country") if country == "nl": f = open(__name__ + '/stimuli_nl.csv', encoding='utf-8-sig') rows = list(csv.DictReader(f)) # random.shuffle(rows) return rows else: f = open(__name__ + '/stimuli_tr.csv', encoding='utf-8-sig') rows = list(csv.DictReader(f)) # random.shuffle(rows) return rows class Constants(BaseConstants): name_in_url = 'part2' players_per_group = None num_rounds = 55 section2_endowment = 1250 attention_penalty = 5 treatment = 1 class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): if subsession.round_number == 1: statements = read_csv(subsession) for player in subsession.get_players(): participant = player.participant rows = statements.copy() random.shuffle(rows) participant.questionlist = rows participant.chosen_set = random.sample(range(50), 20) print('chosen set of questions is', participant.chosen_set) participant.chosen_set_final = [] participant.care = [] participant.fair = [] participant.loyal = [] participant.authority = [] participant.sanctity = [] participant.liberty = [] participant.convention = [] participant.answers_chosen_set = [] participant.chosen_set_statements = [] participant.total_cost = 0 participant.def_no_costly = 0 participant.no_costly = 0 participant.maybe_costly = 0 participant.yes_costly = 0 participant.def_yes_costly = 0 participant.care_mean = 0 participant.fair_mean = 0 participant.loyal_mean = 0 participant.authority_mean = 0 participant.sanctity_mean = 0 participant.liberty_mean = 0 participant.convention_mean = 0 participant.care_total = 0 participant.fair_total = 0 participant.loyal_total = 0 participant.authority_total = 0 participant.sanctity_total = 0 participant.liberty_total = 0 participant.convention_total = 0 for p in subsession.get_players(): participant = p.participant current_question = participant.questionlist[subsession.round_number - 1] # print('current question is', current_question) p.question = current_question['question'] # print(current_question['questionnumber']) p.questionnumber = int(current_question['questionnumber']) p.option1 = current_question['option1'] p.option2 = current_question['option2'] p.option3 = current_question['option3'] p.option4 = current_question['option4'] p.option5 = current_question['option5'] p.attention = int(current_question['attention']) p.solution = current_question['solution'] p.category = current_question['category'] p.participant.attention_counter_costly = 0 # print('here is', p.participant.attention_counter_costly) class Group(BaseGroup): pass class Player(BasePlayer): ex1 = models.CurrencyField( doc="""Answer to first example""", min=0, max=25, label="", ) ex2 = models.CurrencyField( doc="""Answer to second example""", min=0, max=25, label="", ) question = models.StringField() questionnumber = models.IntegerField() option1 = models.StringField() option2 = models.StringField() option3 = models.StringField() option4 = models.StringField() option5 = models.StringField() solution = models.StringField() category = models.StringField() choice = models.StringField(label='', widget=widgets.RadioSelect) attention = models.IntegerField() current_counter = models.IntegerField(initial=0) payment_part2 = models.FloatField() payment_part2_after_attention = models.FloatField() mean = models.FloatField(initial=0) def set_counters(self): participant = self.participant if self.questionnumber < 51: print('question number is', self.questionnumber) print('choice is', self.choice) print('category is', self.category) if self.choice == '1': participant.def_no_costly += 1 print('choice in def_no is', participant.def_no_costly) if self.category == 'care': participant.care.append(self.choice) print('participant care', participant.care) participant.care_total += 1 print('care total is', participant.care_total) if self.category == 'fair': participant.fair.append(self.choice) participant.fair_total += 1 if self.category == 'loyal': participant.loyal.append(self.choice) participant.loyal_total += 1 if self.category == 'authority': participant.authority.append(self.choice) participant.authority_total += 1 if self.category == 'sanctity': participant.sanctity.append(self.choice) participant.sanctity_total += 1 if self.category == 'liberty': participant.liberty.append(self.choice) participant.liberty_total += 1 if self.category == 'convention': participant.convention.append(self.choice) participant.convention_total += 1 if self.choice == '2': participant.no_costly += 1 if self.category == 'care': participant.care.append(self.choice) participant.care_total += 2 if self.category == 'fair': participant.fair.append(self.choice) participant.fair_total += 2 if self.category == 'loyal': participant.loyal.append(self.choice) participant.loyal_total += 2 if self.category == 'authority': participant.authority.append(self.choice) participant.authority_total += 2 if self.category == 'sanctity': participant.sanctity.append(self.choice) participant.sanctity_total += 2 if self.category == 'liberty': participant.liberty.append(self.choice) participant.liberty_total += 2 if self.category == 'convention': participant.convention.append(self.choice) participant.convention_total += 2 if self.choice == '3': participant.maybe_costly += 1 if self.category == 'care': participant.care.append(self.choice) participant.care_total += 3 if self.category == 'fair': participant.fair.append(self.choice) participant.fair_total += 3 if self.category == 'loyal': participant.loyal.append(self.choice) participant.loyal_total += 3 if self.category == 'authority': participant.authority.append(self.choice) participant.authority_total += 3 if self.category == 'sanctity': participant.sanctity.append(self.choice) participant.sanctity_total += 3 if self.category == 'liberty': participant.liberty.append(self.choice) participant.liberty_total += 3 if self.category == 'convention': participant.convention.append(self.choice) participant.convention_total += 3 if self.choice == '4': participant.yes_costly += 1 if self.category == 'care': participant.care.append(self.choice) participant.care_total += 4 if self.category == 'fair': participant.fair.append(self.choice) participant.fair_total += 4 if self.category == 'loyal': participant.loyal.append(self.choice) participant.loyal_total += 4 if self.category == 'authority': participant.authority.append(self.choice) participant.authority_total += 4 if self.category == 'sanctity': participant.sanctity.append(self.choice) participant.sanctity_total += 4 if self.category == 'liberty': participant.liberty.append(self.choice) participant.liberty_total += 4 if self.category == 'convention': participant.convention.append(self.choice) participant.convention_total += 4 if self.choice == '5': participant.def_yes_costly += 1 if self.category == 'care': participant.care.append(self.choice) participant.care_total += 5 if self.category == 'fair': participant.fair.append(self.choice) participant.fair_total += 5 if self.category == 'loyal': participant.loyal.append(self.choice) participant.loyal_total += 5 if self.category == 'authority': participant.authority.append(self.choice) participant.authority_total += 5 if self.category == 'sanctity': participant.sanctity.append(self.choice) participant.sanctity_total += 5 if self.category == 'liberty': participant.liberty.append(self.choice) participant.liberty_total += 5 if self.category == 'convention': participant.convention.append(self.choice) participant.convention_total += 5 print('categories are', participant.care_total, participant.fair_total, participant.loyal_total, participant.authority_total, participant.sanctity_total, participant.liberty_total, participant.convention_total) print('category answers are', participant.care, participant.fair, participant.loyal, participant.authority, participant.sanctity, participant.liberty, participant.convention) for i in participant.chosen_set: if self.questionnumber == i+1: print('i is', i) if self.choice == '1': participant.total_cost += 5 participant.chosen_set_final.append(self.questionnumber) # print('order in the chosen set is', participant.chosen_set_final) participant.answers_chosen_set.append('Definitely no') # print('answers in the chosen set are', participant.answers_chosen_set) participant.chosen_set_statements.append(self.question) if self.choice == '2': participant.total_cost += 10 participant.chosen_set_final.append(self.questionnumber) # print('order in the chosen set is', participant.chosen_set_final) participant.answers_chosen_set.append('No') # print('answers in the chosen set are', participant.answers_chosen_set) participant.chosen_set_statements.append(self.question) if self.choice == '3': participant.total_cost += 15 participant.chosen_set_final.append(self.questionnumber) # print('order in the chosen set is', participant.chosen_set_final) participant.answers_chosen_set.append('Maybe') # print('answers in the chosen set are', participant.answers_chosen_set) participant.chosen_set_statements.append(self.question) if self.choice == '4': participant.total_cost += 20 participant.chosen_set_final.append(self.questionnumber) # print('order in the chosen set is', participant.chosen_set_final) participant.answers_chosen_set.append('Yes') # print('answers in the chosen set are', participant.answers_chosen_set) participant.chosen_set_statements.append(self.question) if self.choice == '5': participant.total_cost += 25 participant.chosen_set_final.append(self.questionnumber) # print('order in the chosen set is', participant.chosen_set_final) participant.answers_chosen_set.append('Definitely yes') # print('answers in the chosen set are', participant.answers_chosen_set) participant.chosen_set_statements.append(self.question) print('total cost is', participant.total_cost) print('chosen set of questions', participant.chosen_set_statements) print('answers in this set', participant.answers_chosen_set) def set_payments(self): participant = self.participant self.payment_part2 = Constants.section2_endowment - participant.total_cost self.payment_part2_after_attention = (self.payment_part2 - ((participant.attention_counter_costly - 1) * Constants.attention_penalty)) self.mean = (((participant.def_no_costly * 1) + (participant.no_costly * 2) + (participant.maybe_costly * 3) + (participant.yes_costly * 4) + (participant.def_yes_costly * 5))/(Constants.num_rounds-5)) print(participant.def_no_costly, participant.no_costly, participant.maybe_costly, participant.yes_costly, participant.def_yes_costly) print('mean of responses is', self.mean) # update the divisors below!!!!!! session = self.session country = session.config.get("country") if country == "nl": participant.care_mean = participant.care_total/9 participant.fair_mean = participant.fair_total/4 participant.loyal_mean = participant.loyal_total/4 participant.authority_mean = participant.authority_total/5 participant.sanctity_mean = participant.sanctity_total/8 participant.liberty_mean = participant.liberty_total/5 participant.convention_mean = participant.convention_total/15 print(participant.care_total, 'and', participant.care_mean) print(participant.fair_total, 'and', participant.fair_mean) print(participant.loyal_total, 'and', participant.loyal_mean) print(participant.authority_total, 'and', participant.authority_mean) print(participant.sanctity_total, 'and', participant.sanctity_mean) print(participant.liberty_total, 'and', participant.liberty_mean) print(participant.convention_total, 'and', participant.convention_mean) else: participant.care_mean = participant.care_total/9 participant.fair_mean = participant.fair_total/6 participant.loyal_mean = participant.loyal_total/4 participant.authority_mean = participant.authority_total/5 participant.sanctity_mean = participant.sanctity_total/9 participant.liberty_mean = participant.liberty_total/7 participant.convention_mean = participant.convention_total/10 print(participant.care_total, 'and', participant.care_mean) print(participant.fair_total, 'and', participant.fair_mean) print(participant.loyal_total, 'and', participant.loyal_mean) print(participant.authority_total, 'and', participant.authority_mean) print(participant.sanctity_total, 'and', participant.sanctity_mean) print(participant.liberty_total, 'and', participant.liberty_mean) print(participant.convention_total, 'and', participant.convention_mean) def choice_choices(player: Player): return [ ['1', player.option1], ['2', player.option2], ['3', player.option3], ['4', player.option4], ['5', player.option5], ] def custom_export(players): # header row yield ['session', 'participant_code', 'participant_label', 'round_number', 'id_in_group', 'questionnumber', 'question', 'choice', 'attention_fail', 'def_no', 'no', 'maybe', 'yes', 'def_yes', 'total_cost', 'payment_part2', 'payment_part2_after_attention', 'chosen_set_final', 'answers_chosen_set', 'chosen_set_statements', 'mean', 'care', 'fair', 'loyal', 'authority', 'sanctity', 'liberty', 'convention', 'care_mean', 'fair_mean', 'loyal_mean', 'authority_mean', 'sanctity_mean', 'liberty_mean', 'convention_mean'] for p in players: participant = p.participant session = p.session yield [session.code, participant.code, participant.label, p.round_number, p.id_in_group, p.questionnumber, p.question, p.choice, participant.attention_counter_costly, participant.def_no_costly, participant.no_costly, participant.maybe_costly, participant.yes_costly, participant.def_yes_costly, participant.total_cost, p.payment_part2, p.payment_part2_after_attention, participant.chosen_set_final, participant.answers_chosen_set, participant.chosen_set_statements, p.mean, participant.care, participant.fair, participant.loyal, participant.authority, participant.sanctity, participant.liberty, participant.convention, participant.care_mean, participant.fair_mean, participant.loyal_mean, participant.authority_mean, participant.sanctity_mean, participant.liberty_mean, participant.convention_mean] # PAGES class Start(Page): def is_displayed(self): return self.round_number == 1 class Instructions(Page): form_model = 'player' form_fields = ['ex1', 'ex2'] def is_displayed(self): return self.round_number == 1 def error_message(self, value): if value["ex1"] != 5: return 'The first question is not answered correctly. Consult the instructions and try again.' elif value["ex2"] != 20: return 'The second question is not answered correctly. Consult the instructions and try again.' class StartTask2(Page): def is_displayed(self): return self.round_number == 1 class Task(Page): form_model = 'player' form_fields = ['choice'] def vars_for_template(self): # print('progress is', 100*(self.round_number/Constants.num_rounds)) return dict( progress=100*(self.round_number/Constants.num_rounds), ) @staticmethod def before_next_page(player: Player, timeout_happened): # print('we reach here') participant = player.participant # print('attention counter', participant.attention_counter_costly) if (player.attention == 1) and (player.choice != player.solution): # print('we reach here also') # print('player choice is', player.choice) # print('player solution is', player.solution) print('attention counter before', participant.attention_counter_costly) participant.attention_counter_costly += 1 print('attention counter after', participant.attention_counter_costly) player.current_counter = 1 # print('current counter is', player.current_counter) player.set_counters() if player.round_number == Constants.num_rounds: player.set_payments() class Attention(Page): @staticmethod def is_displayed(player): participant = player.participant return (participant.attention_counter_costly > 0) and (player.current_counter == 1) @staticmethod def vars_for_template(player): participant = player.participant return dict( attention_counter=participant.attention_counter_costly, ) @staticmethod def before_next_page(player: Player, timeout_happened): # print('updating current counter', player.current_counter) player.current_counter = 0 # print('current counter is', player.current_counter) page_sequence = [Start, Instructions, StartTask2, Task, Attention]