from otree.api import Currency as c, currency_range from . import models from ._builtin import Page, WaitPage from .models import Constants import random import time class Consent(Page): def is_displayed(self): return self.round_number == 1 form_model = 'player' form_fields = ['mturkID', 'accept'] def before_next_page(self): self.player.participant.vars['accept'] = self.player.accept class Welcome(Page): def is_displayed(self): return self.round_number == 1 and self.player.accept form_model = 'player' form_fields = ['attention'] class Introduction(Page): def is_displayed(self): return self.round_number == 1 and self.player.accept def before_next_page(self): # user has 6 minutes to complete as many pages as possible self.participant.vars['expiry_timestamp'] = time.time() + Constants.minutes_given * 60 class QuestionPage(Page): form_model = 'player' form_fields = ['answer'] def is_displayed(self): return self.player.participant.vars['accept'] def get_timeout_seconds(self): return self.participant.vars['expiry_timestamp'] - time.time() def vars_for_template(self): return {'image_path': 'ravens/{}.jpg'.format(self.round_number)} def before_next_page(self): if self.timeout_happened: self.player.answer = 0 self.player.ans_correct = self.player.answer == Constants.answer_keys[self.round_number - 1] self.player.participant.vars['num_correct'] += self.player.ans_correct class CharityChoice(Page): def is_displayed(self): return self.round_number == Constants.num_rounds and self.player.participant.vars['accept'] \ and not Constants.explicit form_model = 'player' form_fields = ['charity'] # class CharityChoiceAdd(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds and self.player.participant.vars['accept'] \ # and (Constants.explicit or Constants.reverse) # # form_model = 'player' # form_fields = ['charity_other'] class QuizAsk(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and Constants.ask \ and not Constants.reverse \ and self.player.participant.vars['accept'] form_model = 'player' form_fields = ['q1', 'q2', 'q3', 'q4', 'q5', 'q6'] def before_next_page(self): if (self.player.q1 != '9 in 10' or self.player.q2 != '$0.00' or self.player.q3 != '$2.50' or self.player.q4 != '$0.80' or self.player.q5 != '$2.10' or self.player.q6 != '$2.50'): self.player.comprehension_incorrect = True else: self.player.comprehension_incorrect = False # Draw card for first implementation of donation self.group.draw_card(1) # class QuizNoAsk(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and (Constants.reverse or Constants.explicit) \ # and self.player.participant.vars['accept'] # # form_model = 'player' # form_fields = ['q1', 'q2', 'q3', 'q4', 'q5', 'q6'] # # def before_next_page(self): # if (self.player.q1 != '9 in 10' or self.player.q2 != '$0.00' or self.player.q3 != '$2.50' # or self.player.q4 != '$0.80' or self.player.q5 != '$2.10' or self.player.q6 != '$2.50'): # self.player.comprehension_incorrect = True # else: # self.player.comprehension_incorrect = False # # Draw card for first implementation of donation # self.group.draw_card(1) class Incorrect(Page): def is_displayed(self): return self.participant.vars['accept'] \ and self.round_number == Constants.num_rounds \ and self.player.comprehension_incorrect # belief elicitation first before donation decision # class IncReverse(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] \ # and Constants.method == 'Inc' \ # and Constants.reverse # # form_model = 'player' # form_fields = ['inc_belief'] # # def before_next_page(self): # if self.player.inc_belief == Constants.previous_participant: # self.player.inc_payoff = Constants.donation_value # class DonationDecisionReverse(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and Constants.ask \ # and Constants.reverse \ # and self.player.participant.vars['accept'] # # form_model = 'player' # form_fields = ['donation'] # # def before_next_page(self): # if self.player.card_colour == 'GREEN': # self.player.initial_implemented = True # else: # self.player.initial_implemented = False class DonationDecision(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and Constants.ask \ and not Constants.reverse \ and self.player.participant.vars['accept'] form_model = 'player' form_fields = ['donation'] def before_next_page(self): if self.player.card_colour == 'GREEN': self.player.initial_implemented = True else: self.player.initial_implemented = False class DonationResult(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and Constants.ask \ and not Constants.reverse \ and self.player.participant.vars['accept'] # class Pilot(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] \ # and Constants.pilot # # form_model = 'player' # form_fields = ['attention_pilot'] # original order: donation then belief elicitation class NonInc(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] \ and Constants.method == 'NonInc' \ and not Constants.pilot form_model = 'player' form_fields = ['noninc_belief'] class Inc(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] \ and Constants.method == 'Inc' form_model = 'player' form_fields = ['inc_belief'] def before_next_page(self): if self.player.inc_belief == Constants.previous_participant: self.player.inc_payoff = Constants.donation_value self.player.consensus_random_number = self.player.participant.vars['consensus_random_number'] # class Karni(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] \ # and Constants.method == 'Karni' # # form_model = 'player' # form_fields = ['game_outcome1', 'game_outcome2', 'game_outcome3', 'game_outcome4', 'game_outcome5', # 'game_outcome6', 'game_outcome7', 'game_outcome8', 'game_outcome9', 'game_outcome10', # 'game_outcome11'] # # def before_next_page(self): # self.group.calculate_karni_payoff() # class KarniAdd(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] \ # and Constants.method == 'Karni' # # form_model = 'player' # form_fields = ['game_outcome1', 'game_outcome2', 'game_outcome3', 'game_outcome4', 'game_outcome5', # 'game_outcome6', 'game_outcome7', 'game_outcome8'] # # def before_next_page(self): # self.group.calculate_karni_payoff_add() class KarniExp(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] \ and Constants.method == 'Karni' form_model = 'player' form_fields = ['game_outcome1', 'game_outcome2', 'game_outcome3', 'game_outcome4', 'game_outcome5', 'game_outcome6', 'game_outcome7', 'game_outcome8', 'game_outcome9', 'game_outcome10', 'game_outcome11'] def before_next_page(self): self.group.calculate_karni_payoff() class QuizAltruism(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] \ and not self.player.initial_implemented \ and Constants.ask \ and self.player.donation form_model = 'player' form_fields = ['q7', 'q8'] def before_next_page(self): if self.player.q7 != '2 GREEN cards, 8 RED cards' or self.player.q8 != '0 in 10 chance': self.player.altruism_incorrect = True else: self.player.altruism_incorrect = False class IncorrectAltruism(Page): def is_displayed(self): return self.participant.vars['accept'] \ and self.round_number == Constants.num_rounds \ and not self.player.initial_implemented \ and Constants.ask \ and self.player.donation \ and self.player.altruism_incorrect class Altruism(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] \ and not self.player.initial_implemented \ and Constants.ask \ and self.player.donation form_model = 'player' form_fields = ['altruism'] class AltruismAmount(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] \ and not self.player.initial_implemented \ and Constants.ask \ and self.player.donation \ and self.player.altruism form_model = 'player' form_fields = ['altruism_amount'] def before_next_page(self): # Draw another card if self.player.altruism: self.group.draw_card(1 + (self.player.altruism_amount / Constants.altruism_rate)) # Implemented or not implemented if self.player.card_colour == 'GREEN' and self.player.altruism: self.player.second_implemented = True elif self.player.card_colour == 'RED' and self.player.altruism: self.player.second_implemented = False elif not self.player.altruism: self.player.second_implemented = False class AltruismResult(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] \ and not self.player.initial_implemented \ and Constants.ask \ and self.player.donation \ and self.player.altruism def vars_for_template(self): return {'remaining_payoff': Constants.participation_fee - self.player.altruism_amount, 'remaining_payoff_implemented': Constants.participation_fee - self.player.altruism_amount - c(Constants.donation_value)} # class Survey(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] # # form_model = 'player' # form_fields = ['age', 'gender', 'ethnicity', 'education', # 'political', 'income', 'subjectiveincome', 'religiosity', # 'worthiness', 'prosocial', 'carpenter', # 'instructions', 'donation_open', 'belief_open', 'altruism_open'] class SurveyAdditionalExp(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] form_model = 'player' form_fields = ['age', 'gender', 'ethnicity', 'education', 'political', 'income', 'subjectiveincome', 'religiosity', 'prosocial', 'worthiness', 'carpenter', 'total_donation', 'own_donation', 'other_aspect'] def error_message(self, values): print('values is', values) if values['total_donation'] + values['own_donation'] + values['other_aspect'] != 100: return 'The percentages assigned to each aspect of giving must add up to 100.' # calculate final payoffs def before_next_page(self): self.player.ravens_total = self.player.participant.vars['num_correct'] for p in self.subsession.get_players(): ravens_payment = Constants.participation_fee + p.participant.vars['num_correct'] * Constants.piece_rate # NonInc treatments if (not Constants.ask and Constants.method == 'NonInc') or \ (Constants.ask and not p.donation and Constants.method == 'NonInc') or \ (Constants.ask and p.donation and not p.initial_implemented and not p.altruism and Constants.method == 'NonInc'): p.participant.payoff = c(ravens_payment) elif Constants.ask and p.donation and p.initial_implemented and Constants.method == 'NonInc': p.participant.payoff = c(ravens_payment - Constants.donation_value) elif Constants.ask and p.donation and p.second_implemented and Constants.method == 'NonInc': p.participant.payoff = c(ravens_payment - Constants.donation_value - p.altruism_amount) elif (Constants.ask and p.donation and p.altruism and not p.second_implemented and Constants.method == 'NonInc'): p.participant.payoff = c(ravens_payment - p.altruism_amount) # Inc treatments if (not Constants.ask and Constants.method == 'Inc') or \ (Constants.ask and not p.donation and Constants.method == 'Inc') or \ (Constants.ask and p.donation and not p.initial_implemented and not p.altruism and Constants.method == 'Inc'): p.participant.payoff = c(ravens_payment + p.inc_payoff) elif Constants.ask and p.donation and p.initial_implemented and Constants.method == 'Inc': p.participant.payoff = c(ravens_payment + p.inc_payoff - Constants.donation_value) elif Constants.ask and p.donation and p.second_implemented and Constants.method == 'Inc': p.participant.payoff = c(ravens_payment + p.inc_payoff - Constants.donation_value - p.altruism_amount) elif (Constants.ask and p.donation and p.altruism and not p.second_implemented and Constants.method == 'Inc'): p.participant.payoff = c(ravens_payment + p.inc_payoff - p.altruism_amount) # Karni treatments if (not Constants.ask and Constants.method == 'Karni') or \ (Constants.ask and not p.donation and Constants.method == 'Karni') or \ (Constants.ask and p.donation and not p.initial_implemented and not p.altruism and Constants.method == 'Karni'): p.participant.payoff = c(ravens_payment + p.karni_payoff) elif Constants.ask and p.donation and p.initial_implemented and Constants.method == 'Karni': p.participant.payoff = c(ravens_payment + p.karni_payoff - Constants.donation_value) elif Constants.ask and p.donation and p.second_implemented and Constants.method == 'Karni': p.participant.payoff = c(ravens_payment + p.karni_payoff - Constants.donation_value - p.altruism_amount) elif (Constants.ask and p.donation and p.altruism and not p.second_implemented and Constants.method == 'Karni'): p.participant.payoff = c(ravens_payment + p.karni_payoff - p.altruism_amount) # class SurveyAdditionalExp2(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] \ # and Constants.explicit # # form_model = 'player' # form_fields = ['optimism', 'people_good', 'belief_open', 'consensus', 'instructions'] # # # class SurveyAdditionalRev2(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] \ # and Constants.reverse # # form_model = 'player' # form_fields = ['optimism', 'people_good', 'belief_open', 'donation_open', 'consensus', 'instructions'] # class SurveyAdditionalKarni(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] \ # and Constants.method == 'Karni' # # form_model = 'player' # form_fields = ['karni_optionA', 'karni_optionA_belief', 'karni_switch', 'karni_switch_other'] class Results(Page): def is_displayed(self): return self.round_number == Constants.num_rounds \ and self.player.participant.vars['accept'] \ and not Constants.reverse def vars_for_template(self): return {'ravens_payoff': Constants.piece_rate * self.participant.vars['num_correct']} # class ResultsReverse(Page): # def is_displayed(self): # return self.round_number == Constants.num_rounds \ # and self.player.participant.vars['accept'] \ # and Constants.reverse # # def vars_for_template(self): # return {'ravens_payoff': Constants.piece_rate * self.participant.vars['num_correct']} page_sequence = [ Consent, Welcome, Introduction, QuestionPage, CharityChoice, # normal order # CharityChoiceAdd, # reverse order QuizAsk, # QuizNoAsk, Incorrect, # Inc, # reverse order # CharityChoice, # reverse order DonationDecision, # normal order # DonationDecisionReverse, # reverse order DonationResult, NonInc, Inc, # for normal order # Karni, KarniExp, # Pilot, QuizAltruism, IncorrectAltruism, Altruism, AltruismAmount, AltruismResult, SurveyAdditionalExp, # SurveyAdditionalExp2, # SurveyAdditionalRev2, # SurveyAdditionalKarni, Results, # ResultsReverse ]