from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random author = 'Kevin Grubiak' doc = """ Your app description """ # Function needed below for stranger matching. def shifter(m): group_size_err_msg = 'This code will not correctly work for group size not equal 2' assert Constants.players_per_group == 2, group_size_err_msg m = [[i.id_in_subsession for i in l] for l in m] f_items = [i[0] for i in m] s_items = [i[1] for i in m] for i in range(Constants.num_rounds): yield [[i, j] for i, j in zip(f_items, s_items)] s_items = [s_items[-1]] + s_items[:-1] class Constants(BaseConstants): name_in_url = 'DFG_experiment' players_per_group = 2 num_rounds = 16 #review = 4 #instructions_template1 = 'DFG_experiment/a_Instructions.html' #instructions_template2 = 'DFG_experiment/a_Instructions2.html' #instructions_template3 = 'DFG_experiment/a_Instructions3.html' #instructions_template4 = 'DFG_experiment/a_Instructions4.html' #instructions_template5 = 'DFG_experiment/a_Instructions5.html' #results_template_est = 'DFG_experiment/k_Results_Est.html' # Images selected, last 4 are for reserve. images = ['Foto_14', 'Foto_26', 'Foto_10', 'Foto_40', 'Foto_17', 'Foto_16', 'Foto_8', 'Foto_29', 'Foto_39', 'Foto_2', 'Foto_31', 'Foto_38', 'Foto_22', 'Foto_12', 'Foto_27', 'Foto_19', 'Foto_7', 'Foto_11', 'Foto_21', 'Foto_32', ] # These are the correct object numbers for list above: solution = [39, 46, 61, 45, 49, 72, 32, 36, 43, 72, 59, 43, 46, 56, 53, 38, 74, 51, 46, 66, ] #images = ['Foto_2', 'Foto_8', 'Foto_10', 'Foto_12', # 'Foto_14', 'Foto_16', 'Foto_17', 'Foto_19', # 'Foto_22', 'Foto_26', 'Foto_27', 'Foto_29', # 'Foto_31', 'Foto_38', 'Foto_39', 'Foto_40', # 'Foto_7', 'Foto_11', 'Foto_21', 'Foto_32', # ] round_list = list(range(1, num_rounds+1)) #print(round_list) # The following are guesses from unbiased Auditors from the 30s pilot experiment. Foto_2_secAud = [45, 46, 47, 53, 54, 54, 55, 56, 60, 60, 60, 60, 61, 63, 64, 65, 65, 65, 67, 67, 68, 68, 68, 68, 69, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 74, 74, 74, 74, 75, 75, 76, 76, 76, 78, 80, 82, 89, 90, 97, ] Foto_8_secAud = [20, 24, 25, 25, 26, 27, 28, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 37, 37, 38, 38, 40, 47, 52, ] Foto_10_secAud = [38, 38, 47, 49, 49, 50, 50, 52, 53, 53, 54, 55, 55, 56, 56, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 64, 65, 65, 66, 66, 66, 67, 80 ] Foto_12_secAud = [32, 35, 45, 45, 45, 45, 48, 50, 50, 50, 51, 51, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 60, 60, 60, 61, 62, 62, 63, 66, 66, 67, 75, ] Foto_14_secAud = [20, 24, 25, 29, 30, 35, 35, 36, 36, 36, 36, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 43, 44, 45, 45, 45, 45, 46, 50, 50, ] Foto_16_secAud = [33, 42, 56, 60, 60, 62, 62, 62, 64, 68, 68, 68, 68, 70, 70, 70, 70, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 74, 74, 75, 75, 76, 78, 80, 82, 83, 85, 100, ] Foto_17_secAud = [20, 35, 35, 40, 40, 40, 41, 41, 42, 43, 45, 45, 45, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 51, 51, 52, 52, 52, 53, 54, 55, 55, 56, 58, 63, ] Foto_19_secAud = [25, 25, 29, 30, 30, 31, 31, 33, 34, 34, 35, 35, 35, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 43, 45, 47, 48, 49, 50, 50, 61, ] Foto_22_secAud = [36, 37, 39, 40, 40, 40, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 50, 51, 51, 52, 53, 57, 59, 60, 60, ] Foto_26_secAud = [30, 31, 34, 35, 35, 35, 36, 38, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 50, 50, 50, 50, 52, 56, 56, 57, 65, 65, ] Foto_27_secAud = [30, 32, 33, 33, 34, 40, 40, 40, 44, 45, 45, 45, 46, 47, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 56, 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, 71, ] Foto_29_secAud = [25, 28, 30, 31, 31, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 38, 38, 39, 39, 39, 39, 40, 40, 40, 41, 42, 44, ] Foto_31_secAud = [44, 45, 46, 47, 50, 50, 50, 50, 50, 52, 53, 54, 54, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 63, 64, 65, 65, 65, 67, 70, 73, 78, ] Foto_38_secAud = [33, 33, 35, 35, 38, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 47, 47, 48, 48, 48, 48, 49, 50, 50, 53, 53, ] Foto_39_secAud = [20, 25, 35, 37, 37, 38, 38, 39, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47, 48, 48, 48, 48, 48, 49, 50, 50, 50, 54, 56, ] Foto_40_secAud = [30, 30, 30, 38, 40, 40, 40, 40, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 47, 47, 48, 48, 49, 50, 52, 54, 56, 65, ] Foto_7_secAud = [38, 45, 45, 50, 50, 56, 57, 60, 60, 60, 60, 62, 62, 63, 64, 66, 66, 67, 68, 69, 70, 70, 70, 70, 72, 72, 72, 73, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 78, 78, 79, 80, 80, 80, 80, 80, 81, 81, 82, 82, 85, 88, 90, 90, 91, 93, 96, 98, 98, ] Foto_11_secAud = [25, 30, 32, 35, 38, 38, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 54, 54, 54, 54, 55, 57, 58, 60, 86, ] Foto_21_secAud = [25, 36, 38, 40, 40, 40, 40, 41, 41, 42, 42, 42, 43, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 50, 50, 53, 54, 62, ] Foto_32_secAud = [36, 38, 45, 45, 48, 48, 49, 54, 54, 55, 55, 56, 59, 60, 60, 60, 62, 62, 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, 69, 69, 69, 69, 70, 70, 70, 70, 71, 71, 72, 72, 72, 73, 73, 75, 76, 76, 78, 80, 82, 82, 86, 89, 92, ] class Subsession(BaseSubsession): # Stranger matching, second player switches to the next group every round. def creating_session(self): if self.session.config.get('stranger_matching', None) == 1: if self.round_number == 1: self.session.vars['full_data'] = [i for i in shifter(self.get_group_matrix())] fd = self.session.vars['full_data'] self.set_group_matrix(fd[self.round_number - 1]) #print(self.get_group_matrix()) #selectedRound = random.randint(1, Constants.num_rounds) if self.round_number == 1: select = random.sample(Constants.round_list, 3) selectedRound = sorted(select) #print(selectedRound) for p in self.get_players(): p.participant.vars['selectedRound'] = selectedRound[0] p.participant.vars['selectedRound2'] = selectedRound[1] p.participant.vars['selectedRound3'] = selectedRound[2] p.participant.vars['treatment'] = self.session.config.get('treatment', None) #print(p.participant.vars['selectedRound']) #self.session.vars['selectedRound'] = random.randint(1, 16) #print(self.session.vars['selectedRound']) #self.session.vars['n_instr_finished'] = 0 #print(self.session.vars['n_instr_finished']) class Group(BaseGroup): sent_amount = models.CurrencyField( min=0, max=20, doc="""Amount sent by the Estimator""", #label="Please determine the amount of your 10 Euro that you would like to transfer to the Auditor:", label="" ) transfer_accepted = models.BooleanField() Guess_6s_Pic1 = models.IntegerField(initial=0, max=100, min=20, label="Ihre Schätzung:") corr_num = models.IntegerField() prize_awarded = models.BooleanField() review_requested_est = models.BooleanField() review_requested_aud = models.BooleanField() review_requested_comp = models.BooleanField() review_happened = models.BooleanField(initial=0) chance_move = models.FloatField() image = models.StringField(initial=0) secAuditor_guess = models.IntegerField(initial=999) secAuditor_awarded = models.IntegerField(initial=999) selectedRound = models.IntegerField(initial=999) selectedRound2 = models.IntegerField(initial=999) selectedRound3 = models.IntegerField(initial=999) class Player(BasePlayer): def live_wait(self, data): if data["new_arrival"]: return_data = {"n_waiting": self.session.vars['n_instr_finished']} return {0: return_data} earnings_in_round = models.CurrencyField(initial=0) n_prizes_received = models.IntegerField() est1_transfer = models.StringField() #est2_confidence_guess = models.IntegerField() est2_confidence_guess = models.PositiveIntegerField( choices=[ [1, 'weniger häufig'], [2, 'gleich häufig'], [3, 'häufiger'], ], label="", ) overconfidence = models.IntegerField() est3_deserved = models.PositiveIntegerField( choices=[ [0, '0-mal'], [1, '1-mal'], [2, '2-mal'], [3, '3-mal'], [4, '4-mal'], [5, '5-mal'], [6, '6-mal'], [7, '7-mal'], [8, '8-mal'], [9, '9-mal'], [10, '10-mal'], [11, '11-mal'], [12, '12-mal'], [13, '13-mal'], [14, '14-mal'], [15, '15-mal'], [16, '16-mal'], ], label="", ) est_opinion_deserved_more = models.IntegerField() est4_review = models.StringField() n_prizes_awarded = models.IntegerField() aud1_transfer = models.StringField() aud2_award_expl = models.StringField() aud2_confidence_guess = models.PositiveIntegerField( choices=[ [1, 'weniger häufig'], [2, 'gleich häufig'], [3, 'häufiger'], ], label="", ) overlenience = models.IntegerField() #aud2_confidence_guess = models.IntegerField() #aud3_award_tolerance = models.IntegerField() aud3_deserved = models.PositiveIntegerField( choices=[ [0, '0-mal'], [1, '1-mal'], [2, '2-mal'], [3, '3-mal'], [4, '4-mal'], [5, '5-mal'], [6, '6-mal'], [7, '7-mal'], [8, '8-mal'], [9, '9-mal'], [10, '10-mal'], [11, '11-mal'], [12, '12-mal'], [13, '13-mal'], [14, '14-mal'], [15, '15-mal'], [16, '16-mal'], ], label="", ) aud_opinion_deserved_more = models.IntegerField() aud4_review = models.StringField() age = models.IntegerField(label='', min=13, max=99) gender = models.StringField( choices=[['Männlich', 'Männlich'], ['Weiblich', 'Weiblich'], ['Divers', 'Divers'], ['Keine Angabe', 'Keine Angabe']], label='', ) faculty = models.StringField( choices=[['Humanwissenschaften', 'Humanwissenschaften'], ['Geistes- und Kulturwissenschaften', 'Geistes- und Kulturwissenschaften'], ['Gesellschaftswissenschaften', 'Gesellschaftswissenschaften'], ['Architektur - Stadtplanung - Landschaftsplanung', 'Architektur - Stadtplanung - Landschaftsplanung'], ['Wirtschaftswissenschaften', 'Wirtschaftswissenschaften'], ['Mathematik und Naturwissenschaften', 'Mathematik und Naturwissenschaften'], ['Ökologische Agrarwissenschaften', 'Ökologische Agrarwissenschaften'], ['Bauingenieur- und Umweltingenieurwesen', 'Bauingenieur- und Umweltingenieurwesen'], ['Maschinenbau', 'Maschinenbau'], ['Elektrotechnik/Informatik', 'Elektrotechnik/Informatik'], ['Kunsthochschule Kassel', 'Kunsthochschule Kassel']], label='', ) feedback = models.StringField() Q1_first_attempt = models.IntegerField() Q2_first_attempt = models.IntegerField() Q3_first_attempt = models.IntegerField() Q4_first_attempt = models.IntegerField() Q5_first_attempt = models.IntegerField() Q6_first_attempt = models.IntegerField() Q7_first_attempt = models.IntegerField() treatment = models.IntegerField() final_tokens = models.IntegerField() final_payoff = models.FloatField() duration = models.FloatField()