from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import itertools from random import shuffle # author = 'Dan Way' doc = """ Project selection """ class Constants(BaseConstants): name_in_url = 'project_selection' players_per_group = 2 num_rounds = 1 kc1_correct = 'c' kc2_correct = 'True' kc3_correct = 'd' kc4_RI_correct = 'a' kc4_ROI_correct = 'a' kc4_NI_correct = 'a' kc5_RI_correct = 'b' kc5_ROI_correct = 'b' kc5_NI_correct = 'b' kc6_correct = 'b' kc7_correct = 'a' class Subsession(BaseSubsession): def creating_session(self): if 'condition' in self.session.config: for g in self.get_groups(): p1 = g.get_player_by_id(1) p2 = g.get_player_by_id(2) p1.participant.vars['condition'] = self.session.config['condition'] p2.participant.vars['condition'] = self.session.config['condition'] p1.participant.vars['counterbal'] = 1 # Counterbalance in case we need it p2.participant.vars['counterbal'] = 2 else: conditions = itertools.cycle([1, 2]) counterbal = itertools.cycle([1, 2]) for g in self.get_groups(): # g.condition = next(conditions) p1 = g.get_player_by_id(1) p2 = g.get_player_by_id(2) p1.participant.vars['condition'] = next(conditions) p2.participant.vars['condition'] = p1.participant.vars['condition'] p1.participant.vars['counterbal'] = next(counterbal) p2.participant.vars['counterbal'] = next(counterbal) class Group(BaseGroup): pass class Project(models.Model): project_id = models.IntegerField() outcome_id = models.IntegerField() outcome_raw = models.IntegerField() outcome_ri = models.IntegerField() # For ROI, integer is fine since the percent sign can just be added when displayed outcome_roi = models.IntegerField() # Bonus is redundant, but might as well store that here for now outcome_bonus = models.IntegerField() def project_results(self, projectid, outcomeid): return self.objects.filter(project_id = projectid, outcome_id = outcomeid) class Gamble(models.Model): gamble_id = models.IntegerField() gamble_choice = models.CharField() outcome_id = models.IntegerField() outcome_raw = models.IntegerField() def gamble_results(self, gambleid, gamblechoice, outcomeid): return self.objects.filter(gamble_id = gambleid, gamble_choice = gamblechoice, outcome_id = outcomeid) class DecodeStrings(models.Model): id = models.IntegerField(null=False,primary_key=True) letters = models.CharField(max_length=50) numbers = models.CharField(max_length=50) def decode_results(self, s_id): return self.objects.filter(id = s_id) class Player(BasePlayer): condition = models.IntegerField() informed_consent = models.CharField(initial=None, choices=[('Yes', 'Yes'), ('No', 'No')], verbose_name='', widget=widgets.RadioSelect()) kc1 = models.CharField(initial=None, choices=[('a', 'a. 2'), ('b', 'b. 4'), ('c', 'c. 5')], verbose_name='', widget=widgets.RadioSelect()) def kc1_correct(self): return self.kc1 == Constants.kc1_correct kc2 = models.CharField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) def kc2_correct(self): return self.kc2 == Constants.kc1_correct kc3 = models.CharField(initial=None, choices=[('a', 'a. $0.00-$0.20'), ('b', 'b. $0.00-$0.80'), ('c', 'c. $0.00-$1.20'), ('d', 'd. $0.00-$2.00')], verbose_name='', widget=widgets.RadioSelect()) def kc3_correct(self): return self.kc3 == Constants.kc3_correct kc4_RI = models.CharField(initial=None, choices=[('a', 'a. Residual income'), ('b', 'b. Net cash flows'), ('c', 'c. Return on investment')], verbose_name='', widget=widgets.RadioSelect()) def kc4_RI_correct(self): return self.kc4_RI == Constants.kc4_RI_correct kc4_ROI = models.CharField(initial=None, choices=[('a', 'a. Return on investment'), ('b', 'b. Net cash flows'), ('c', 'c. Residual income')], verbose_name='', widget=widgets.RadioSelect()) def kc4_ROI_correct(self): return self.kc4_ROI == Constants.kc4_ROI_correct kc4_NI = models.CharField(initial=None, choices=[('a', 'a. Net income'), ('b', 'b. Net cash flows'), ('c', 'c. Return on investment')], verbose_name='', widget=widgets.RadioSelect()) def kc4_NI_correct(self): return self.kc4_NI == Constants.kc4_NI_correct kc5_RI = models.CharField(initial=None, choices=[('a', 'a. Income generated by project - $700'), ('b', 'b. Income generated by project – (Required rate of return × Investment in project)'), ('c', 'c. Income generated by project × 10%')], verbose_name='', widget=widgets.RadioSelect()) def kc5_RI_correct(self): return self.kc5_RI == Constants.kc5_RI_correct kc5_ROI = models.CharField(initial=None, choices=[('a', 'a. Income generated by project × $700'), ('b', 'b. (Income generated by project / Investment in project) × 100(%)'), ('c', 'c. Income generated by project × 10%')], verbose_name='', widget=widgets.RadioSelect()) def kc5_ROI_correct(self): return self.kc5_ROI == Constants.kc5_ROI_correct kc6 = models.CharField(initial=None, choices=[('a', 'a. $0.40'), ('b', 'b. $0.60'), ('c', 'c. $0.80'), ('d', 'd. $1.00')], verbose_name='', widget=widgets.RadioSelect()) def kc6_correct(self): return self.kc6 == Constants.kc6_correct kc7 = models.CharField(initial=None, choices=[('a', 'a. $0.20'), ('b', 'b. $0.40'), ('c', 'c. $0.60'), ('d', 'd. $0.80')], verbose_name='', widget=widgets.RadioSelect()) def kc7_correct(self): return self.kc7 == Constants.kc7_correct num_attempted_1 = models.IntegerField() num_decoded_1 = models.IntegerField() num_attempted_2 = models.IntegerField() num_decoded_2 = models.IntegerField() num_attempted_3 = models.IntegerField() num_decoded_3 = models.IntegerField() num_attempted_4 = models.IntegerField() num_decoded_4 = models.IntegerField() num_attempted_5 = models.IntegerField() num_decoded_5 = models.IntegerField() work_time_1 = models.CharField() work_time_2 = models.CharField() work_time_3 = models.CharField() work_time_4 = models.CharField() work_time_5 = models.CharField() # "Baseline" project is denoted as project 1, so that I can keep integer fields p1v2 = models.IntegerField() p3v4 = models.IntegerField() p1v5 = models.IntegerField() p2v3 = models.IntegerField() p3v5 = models.IntegerField() # ... p1v2a = models.IntegerField() p3v4a = models.IntegerField() p1v5a = models.IntegerField() p2v3a = models.IntegerField() p3v5a = models.IntegerField() p1v2_time = models.CharField() p3v4_time = models.CharField() p1v5_time = models.CharField() p2v3_time = models.CharField() p3v5_time = models.CharField() # New fields for getting them paid on all 10 project selections implemented_project_1 = models.IntegerField() implemented_project_2 = models.IntegerField() implemented_project_3 = models.IntegerField() implemented_project_4 = models.IntegerField() implemented_project_5 = models.IntegerField() impl_project_outcome_1 = models.IntegerField() impl_project_outcome_2 = models.IntegerField() impl_project_outcome_3 = models.IntegerField() impl_project_outcome_4 = models.IntegerField() impl_project_outcome_5 = models.IntegerField() raw_outcome_1 = models.IntegerField() raw_outcome_2 = models.IntegerField() raw_outcome_3 = models.IntegerField() raw_outcome_4 = models.IntegerField() raw_outcome_5 = models.IntegerField() pm_outcome_1 = models.IntegerField() pm_outcome_2 = models.IntegerField() pm_outcome_3 = models.IntegerField() pm_outcome_4 = models.IntegerField() pm_outcome_5 = models.IntegerField() bonus_outcome_1 = models.CharField() bonus_outcome_2 = models.CharField() bonus_outcome_3 = models.CharField() bonus_outcome_4 = models.CharField() bonus_outcome_5 = models.CharField() total_bonus = models.CharField() total_comp = models.CharField() pair_order = models.CharField() peq_gamble1 = models.CharField() peq_gamble2 = models.CharField() peq_gamble3 = models.CharField() peq_gamble4 = models.CharField() peq_gamble5 = models.CharField() peq_gamble6 = models.CharField() peq_gamble7 = models.CharField() peq_gamble8 = models.CharField() peq_gamble9 = models.CharField() peq_gamble10 = models.CharField() paid_gamble = models.IntegerField() paid_gamble_choice = models.CharField() paid_gamble_outcome = models.IntegerField() bonus_outcome_peq = models.CharField() peq_decoding_difficulty = models.CharField(initial=None, choices=[('0', '0 = Not at all.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Extremely difficult.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) peq_choice_enjoyment = models.CharField(initial=None, choices=[('0', '0 = Not at all.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = A great deal.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) peq_choice_difficulty = models.CharField(initial=None, choices=[('0', '0 = Not at all - there was always a clear "best" choice for me.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Somewhat difficult - some pairs had a clear "best" choice.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Extremely difficult - there was never a clear "best" choice for me.')], verbose_name='') peq_threshold_salience = models.CharField(initial=None, choices=[('-5', '-5 = Strongly disagree.'), ('-4', '-4'), ('-3', '-3'), ('-2', '-2'), ('-1', '-1'), ('0', '0 = Neither agree nor disagree.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Strongly agree.')], verbose_name='') peq_importance_max_payoff = models.CharField(initial=None, choices=[('0', '0 = Not at all important.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Somewhat important.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Very important.')], verbose_name='') peq_importance_max_odds = models.CharField(initial=None, choices=[('0', '0 = Not at all important.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Somewhat important.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Very important.')], verbose_name='') peq_importance_min_payoff = models.CharField(initial=None, choices=[('0', '0 = Not at all important.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Somewhat important.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Very important.')], verbose_name='') peq_importance_min_odds = models.CharField(initial=None, choices=[('0', '0 = Not at all important.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Somewhat important.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Very important.')], verbose_name='') peq_importance_likely_payoff = models.CharField(initial=None, choices=[('0', '0 = Not at all important.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Somewhat important.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Very important.')], verbose_name='') peq_importance_bonus_proportion = models.CharField(initial=None, choices=[('0', '0 = Not at all important.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Somewhat important.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Very important.')], verbose_name='') peq_expected_bonus = models.FloatField(verbose_name='') peq_open_ended = models.TextField(verbose_name = '') peq_turk_income = models.CharField(initial=None, choices=[('0', '0 = My work on MTurk is for fun or interest only - I ' 'don`t rely on it for income.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = My work on MTurk supplements my household`s' ' primary income.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = My work on MTurk generates a significant' ' portion of my household`s total income.')], verbose_name='') peq_risk_attitude = models.CharField(initial=None, choices=[('0', '0 = I`m not at all willing to take risks.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = I`m somewhat willing to take risks.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = I`m very willing to take risks.')], verbose_name='') peq_affect_excited = models.CharField(initial=None, choices=[('0', '0 = Not at all.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Moderately.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Extremely.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) peq_affect_upset = models.CharField(initial=None, choices=[('0', '0 = Not at all.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Moderately.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Extremely.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) peq_affect_proud = models.CharField(initial=None, choices=[('0', '0 = Not at all.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Moderately.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Extremely.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) peq_affect_irritable = models.CharField(initial=None, choices=[('0', '0 = Not at all.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Moderately.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Extremely.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) peq_affect_inspired = models.CharField(initial=None, choices=[('0', '0 = Not at all.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Moderately.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Extremely.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) peq_affect_nervous = models.CharField(initial=None, choices=[('0', '0 = Not at all.'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5 = Moderately.'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10 = Extremely.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) peq_gender = models.CharField(initial=None, choices=[('1', 'Male'), ('2', 'Female')], verbose_name='', widget=widgets.RadioSelect()) peq_age_range = models.CharField(initial=None, choices=[('1', '18-24'), ('2', '25-34'), ('3', '35-44'), ('4', '45-54'), ('5', '55-64'), ('6', '65 and older')], verbose_name='') peq_work_experience = models.IntegerField(verbose_name='') peq_education = models.CharField(initial=None, choices=[('1', 'Less than high school'), ('2', 'High school graduate'), ('3', 'Some college'), ('4', '2 year degree'), ('5', '4 year degree'), ('6', 'Graduate degree')], verbose_name='') peq_accounting = models.CharField(initial=None, choices=[('0', '0'), ('1', '1 or 2'), ('3', '3 or more')], verbose_name='', widget=widgets.RadioSelect()) worker_id = models.CharField(initial='e') mturk_dupe = models.IntegerField()