from django.forms import CheckboxSelectMultiple, RadioSelect from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, ) import random author = 'Monika Leszczynska' doc = """ Choosing an app and doing the task with an additional tool """ class Constants(BaseConstants): name_in_url = 'matrices' players_per_group = None task_timer = 180 decision_timer = 60 num_rounds = 25 d_total = 20 b_total = 60 total_letters = 80 matrix_rate = c(0.20) fixed_payoff = c(2.00) completion_url = "https://app.prolific.com/submissions/complete?cc=C1KY7Y81" class Subsession(BaseSubsession): def creating_session(self): n = Constants.total_letters for p in self.get_players(): indices = list(range(1, n + 1)) form_fields = ['choice_' + str(k) for k in indices] d_list = ['d'] * Constants.d_total b_list = ['b'] * Constants.b_total letters_list = d_list + b_list random.shuffle(letters_list) p.participant.vars['letters_choices'] = list(zip(indices, form_fields, letters_list)) p.participant.vars['letters_choices_made'] = [None] * n if 'treatment' in self.session.config: p.participant.vars['treatment'] = self.session.config['treatment'] else: p.participant.vars['treatment'] = random.choice(['FreeTool', 'ComplimentaryTool', 'Tool', "AlternativeVersion"]) class Group(BaseGroup): pass class Player(BasePlayer): # ----- NEW: 100 checkbox fields --------------------------------------- # They will be called choice_1, choice_2, …, choice_100 (or to _80 if you # keep Constants.total_letters = 80). Blank=True so unchecked boxes post # an empty string, which won’t fail validation. for i in range(1, Constants.total_letters + 1): locals()[f"choice_{i}"] = models.StringField(blank=True) del i # Questionnaire fields self_other = models.IntegerField(initial=None) trust = models.IntegerField(initial=None) fair_1 = models.IntegerField(choices=[-3, -2, -1, 0, 1, 2, 3], widget=widgets.RadioSelect) fair_2 = models.IntegerField(choices=[-3, -2, -1, 0, 1, 2, 3], widget=widgets.RadioSelect) fair_3 = models.IntegerField(choices=[-3, -2, -1, 0, 1, 2, 3], widget=widgets.RadioSelect) quality_1 = models.IntegerField(choices=list(range(1, 8)), widget=widgets.RadioSelect) quality_2 = models.IntegerField(choices=list(range(1, 8)), widget=widgets.RadioSelect) affect = models.StringField() mot_alert1 = models.IntegerField(choices=list(range(1, 8)), widget=widgets.RadioSelect) mot_alert2 = models.IntegerField(choices=list(range(1, 8)), widget=widgets.RadioSelect) mot_alert3 = models.IntegerField(choices=list(range(1, 8)), widget=widgets.RadioSelect) # create fields for dispositional suspiciousness measure # ---------------------------------------------------------------------------------------------------------- suspicious_1 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) suspicious_2 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) suspicious_3 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) suspicious_4 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) suspicious_5 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) suspicious_6 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) suspicious_7 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) suspicious_8 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) suspicious_9 = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect ) # Decision-making fields def make_field(label): return models.IntegerField( choices=[ [1, 'Definitely false'], [2, 'Mostly false'], [3, 'Undecided or equally true and false'], [4, 'Mostly true'], [5, 'Definitely true'], ], label=label, widget=widgets.RadioSelect, ) reciprocity_1 = make_field('I’ll never ask for help if I don’t have to, to avoid owing others.') reciprocity_2 = make_field('Usually I don’t accept favors unless I am sure I can pay back all the favors quickly.') reciprocity_3 = make_field('One should not ask for a favor from a friend if he/she is unable to pay it back.') reciprocity_4 = make_field('I avoid asking for favors if I cannot repay the favor.') reciprocity_5 = make_field('When someone offers to help me, I usually reject it if I cannot rid myself of the debt through reciprocation.') reciprocity_6 = make_field('I hesitate to ask for help because then I don’t need to think about what I might give in return.') reciprocity_7 = make_field('When I receive favors from someone, I worry about how to repay them.') reciprocity_8 = make_field('I am often afraid that I cannot reciprocate favors in time.') reciprocity_9 = make_field('I worry about what people will think of me if I fail to reciprocate the favors I received from others.') reciprocity_10 = make_field('Sometimes I think I am too concerned with reciprocating the favors.') reciprocity_11 = make_field('I’m restless and on edge when I owe someone.') # Task timing and scoring task_timer = models.IntegerField(initial=Constants.task_timer) my_page_timeout_seconds = models.IntegerField(initial=Constants.decision_timer) d_crossed = models.IntegerField(initial=0) b_crossed = models.IntegerField(initial=0) total_correct = models.IntegerField(initial=0) correct = models.IntegerField(initial=0) is_correct = models.BooleanField(initial=False) # Tool choice and payout tool = models.IntegerField(initial=None) bonus_prolific = models.CurrencyField() treatment = models.StringField() participant_vars_dump = models.LongStringField() comments = models.LongStringField(blank=True) reasons = models.LongStringField(blank=True) choice_seconds = models.FloatField() endgame = models.IntegerField(initial=0) # Methods def get_treatment(self): self.treatment = self.participant.vars.get('treatment', '') def count_effort(self): self.d_crossed = self.participant.vars['letters_choices_made'].count('d') self.b_crossed = self.participant.vars['letters_choices_made'].count('b') def check_correctness(self): if self.d_crossed == Constants.d_total and self.b_crossed == 0: self.correct = 1 self.is_correct = True else: self.correct = 0 self.is_correct = False def calculate_payoff(self): total = self.participant.vars.get("total_correct", 0) self.payoff = Constants.fixed_payoff + (total * Constants.matrix_rate) self.bonus_prolific = total * Constants.matrix_rate print(self.payoff, self.participant.vars['treatment'], self.participant.vars.get('tool')) def update_endgame_second(self): self.participant.vars['endgame_second'] = 1 print(self.participant.vars['endgame_second'])