from otree.api import * doc = """ Your app description """ class C(BaseConstants): import random # Change these variables: TEST_RUN = True NUM_TEST_ROUNDS = 0 # Number of test rounds played; if more than one, Announcement pages have to be adjusted! NUM_REAL_ROUNDS = 1 # Number of rounds played after the test round(s) NUM_EXP_ROUNDS = 1 # Number of real rounds in which expectations of other player's behavior are elicited # Attention: this number does not count the test rounds! # Leave these variables NAME_IN_URL = 'qlm' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = NUM_TEST_ROUNDS + NUM_REAL_ROUNDS ENDOWMENT = 25 EXCHANGE_RATE = 0.25 INV_EXCHANGE_RATE = int(1/EXCHANGE_RATE) OFFER_MAX = 17 PROB_FED_UP = 0.05 CURRENT_EMPLOYERS = [1,1,2,2,3,3] OTHER_EMPLOYERS1 = [2,2,1,1,1,1] OTHER_EMPLOYERS2 = [3,3,3,3,2,2] WORKERS_PER_PLAYER = [[1,2,3,4,5,6],[3,4,1,2,5,6],[5,6,1,2,3,4]] COLORS_WORKERS_SAME = [0,4,1,6,2,8] S=0.5 C1=12 C2=4 D1=0 D2=6 AH=2 AL=1 NUM_COLOR_FIELDS = 19 BONUS_COUNTING = 5 NUM_COMP_QUEST = 10 BONUS_COMP_QUEST = 2 TOLERANCE_EXP = 1 BONUS_EXP = 0.5 PREVIOUS_COUNTING_RBG = [1,1,1] # Counting result from the relevant previous session PAYING_ROUND = random.randint(NUM_TEST_ROUNDS+1,NUM_ROUNDS) PAYING_ROUND_REAL = PAYING_ROUND - NUM_TEST_ROUNDS def creating_session(subsession): from itertools import cycle import random from random import choice session = subsession.session subsession.round_number_real = subsession.round_number - C.NUM_TEST_ROUNDS if subsession.round_number <= C.NUM_TEST_ROUNDS: subsession.is_test_round = True # Choosing payoff relevant round #session.vars['paying_round'] = random.randint(C.NUM_TEST_ROUNDS+1,C.NUM_ROUNDS) #session.vars['paying_round_real'] = session.vars.paying_round - C.NUM_TEST_ROUNDS # Assigning half of the groups to both baseline and samecolor treatment same = cycle([True, False]) for group in subsession.get_groups(): group.samecolor = next(same) # Definition of colors subsession.session.colors = ['Red', 'Blue', 'Green', 'Orange', 'Gold', 'Pink', 'SaddleBrown', 'Purple', 'Aqua', 'Black'] subsession.session.colors_de = ['rot', 'blau', 'grün', 'orange', 'gelb', 'pink', 'beige', 'violett', 'türkis', 'schwarz'] # Color assignment, switch variables for random order of employees on the promotion page, workerids for players for player in subsession.get_players(): player.color_id = player.id_in_group-1 player.color_name = subsession.session.colors[player.color_id] player.color_de = subsession.session.colors_de[player.color_id] player.color_html = '{}'.format(player.color_name, player.color_de) add_e = '' if player.color_de[-1] == 'e' else 'e' player.color_html_akk = '{}{}{}'.format(player.color_name, player.color_de, add_e, 'n') player.color_html_fem = '{}{}'.format(player.color_name, player.color_de, add_e) player.exp_emp = C.OTHER_EMPLOYERS1[player.id_in_group] if choice([True, False]) else C.OTHER_EMPLOYERS2[player.id_in_group] # randomly draw one of the other employers as employer for expectations player.switch_emp = choice([True, False]) # switch display order of other employers? player.switch_worker12 = choice([True, False]) # switch display order of own workers? player.switch_worker34 = choice([True, False]) # switch display order of workers of other_emp1? player.switch_worker56 = choice([True, False]) # switch display order of workers of other_emp2? player.worker1_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][int(player.switch_worker12)] player.worker2_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][1 - int(player.switch_worker12)] if not(player.switch_emp): player.other_emp1_id = C.OTHER_EMPLOYERS1[player.id_in_group * 2 - 1] player.other_emp2_id = C.OTHER_EMPLOYERS2[player.id_in_group * 2 - 1] player.worker3_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][2 + int(player.switch_worker34)] player.worker4_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][3 - int(player.switch_worker34)] player.worker5_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][4 + int(player.switch_worker56)] player.worker6_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][5 - int(player.switch_worker56)] else: player.other_emp1_id = C.OTHER_EMPLOYERS2[player.id_in_group * 2 - 1] player.other_emp2_id = C.OTHER_EMPLOYERS1[player.id_in_group * 2 - 1] player.worker3_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][4 + int(player.switch_worker56)] player.worker4_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][5 - int(player.switch_worker56)] player.worker5_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][2 + int(player.switch_worker34)] player.worker6_id = C.WORKERS_PER_PLAYER[player.id_in_group - 1][3 - int(player.switch_worker34)] # Creating 6 workers for each group for group in subsession.get_groups(): for i in range(6): Worker.create( group = group, number = i+1, color_id = i+3 if group.samecolor == False else C.COLORS_WORKERS_SAME[i], current_employer = group.get_player_by_id(C.CURRENT_EMPLOYERS[i]), other_employer1 = group.get_player_by_id(C.OTHER_EMPLOYERS1[i]), other_employer2 = group.get_player_by_id(C.OTHER_EMPLOYERS2[i]), ) # Assigning same color variable for group in subsession.get_groups(): workers = Worker.filter(group = group) for worker in workers: worker.same_color = True if worker.current_employer.color_id == worker.color_id else False # Assigning colors to workers for group in subsession.get_groups(): workers = Worker.filter(group = group) for worker in workers: worker.color_name = subsession.session.colors[worker.color_id] worker.color_de = subsession.session.colors_de[worker.color_id] worker.color_html = '{}'.format(worker.color_name, worker.color_de) for player in subsession.get_players(): for i in range(4): Case.create(player = player, case_type = 0, #0 = own employees, 1 = other employer's employees case_number = i+1, worker1 = Worker.filter(group = player.group, number = player.worker1_id)[0], worker2 = Worker.filter(group = player.group, number = player.worker2_id)[0], promotion = 'promotion' + str(i+1), promotion_inv = 'promotion' + str(i+1) + 'inv', promotione = 'promotion' + str(i+1) + 'e', promotione_inv = 'promotion' + str(i+1) + 'einv', offer1 = 'offer1' + str(i+1), offer2 = 'offer2' + str(i+1), offer1e = 'offer1' + str(i+1) + 'e', offer2e = 'offer2' + str(i+1) + 'e', worker1_ability = 'hohe' if i in {0,2} else 'niedrige', worker2_ability = 'hohe' if i in {1,2} else 'niedrige') for i in range(4): Case.create(player = player, case_type = 1, #0 = own employees, 1 = other employer's employees case_number = i+1 if i<2 else i-1, worker1 = Worker.filter(group = player.group, number = player.worker3_id if i<2 else player.worker5_id)[0], worker2 = Worker.filter(group = player.group, number = player.worker4_id if i<2 else player.worker6_id)[0], promotion = 'befördert' if i in {0,2} else 'nicht befördert', promotion_inv = 'befördert' if i in {1,3} else 'nicht befördert', offer1 = ('offer3' + str(i+1)) if i<2 else ('offer5' + str(i-1)), offer2 = ('offer4' + str(i+1)) if i<2 else ('offer6' + str(i-1)), offer1e = ('offer3' + str(i+1) + 'e') if i<2 else ('offer5' + str(i-1) + 'e'), offer2e = ('offer4' + str(i+1) + 'e') if i<2 else ('offer6' + str(i-1) + 'e'), other_employer = 1 if i<2 else 2) class Subsession(BaseSubsession): round_number_real = models.IntegerField() is_test_round = models.BooleanField(initial = False) class Group(BaseGroup): samecolor = models.BooleanField() # Function to create promotion field variables def var_prom(label): return models.BooleanField( choices=[[True, 'befördern'], [False, 'nicht befördern'],], widget=widgets.RadioSelectHorizontal, label = label ) # Function to create promotion field variables def var_prom_e(label): return models.BooleanField( choices=[[True, 'befördert'], [False, 'nicht befördert'],], widget=widgets.RadioSelectHorizontal, label = label ) # Function to create offer field variables def var_offer(label): return models.FloatField( min=0, max=C.OFFER_MAX, label = label ) # Function to create comprehensve question variables def var_comp(label): return models.BooleanField( choices=[[True, 'Richtig'], [False, 'Falsch']], label = label, widget = widgets.RadioSelectHorizontal ) # Function to create closeness questions def var_close(label): return models.IntegerField( choices=[i for i in range(0,11)], label = label, widget = widgets.RadioSelectHorizontal ) class Player(BasePlayer): color_id = models.IntegerField(initial = 1) color_name = models.StringField() color_de = models.StringField() color_html = models.StringField() color_html_akk = models.StringField() color_html_fem = models.StringField() picture_count = models.IntegerField() comp_quest1 = var_comp(label='Aussage 1: Die Zuteilung der TeilnehmerInnen zu einer Farbgruppe, einem Arbeitsmarkt und einer Rolle (AN/AG) bleibt über alle {} Runden erhalten.'.format(C.NUM_ROUNDS)) comp_quest2 = var_comp(label='Aussage 2: Die Farbgruppe jedes AN und jedes AG auf einem Arbeitsmarkt ist für alle AG desselben Arbeitsmarktes sichtbar.') comp_quest3 = var_comp(label='Aussage 3: Ein AG kann die Lohnangebote für seine aktuellen AN von deren Leistungsfähigkeit abhängig machen.') comp_quest4 = var_comp(label='Aussage 4: Ein AG kann seine Lohnangebote für die aktuellen AN der anderen AG nur von ihrer Zugehörigkeit zu einer bestimmten Farbgruppe abhängig machen.') comp_quest5 = var_comp(label='Aussage 5: Wenn das höchste Angebot der beiden abwerbenden AG gleich oder niedriger ist als das Lohnangebot des aktuellen AG, wechselt der AN mit einer Wahrscheinlichkeit von {}%.'.format(C.PROB_FED_UP)) comp_quest6 = var_comp(label='Aussage 6: Die Leistungsfähigkeit eines AN wird in der ersten Runde zufällig bestimmt und bleibt dann für alle weiteren Runden gleich.') comp_quest7 = var_comp(label='Aussage 7: Ein AN arbeitet nach den Lohnangeboten auf jeden Fall für seinen aktuellen AG.') comp_quest8 = var_comp(label='Aussage 8: Die aktuellen AN eines AG sind zu Beginn jeder Runde dieselben.') comp_quest9 = var_comp(label='Aussage 9: Der erwirtschaftete Ertrag eines AN ist nur dann von seiner Leistungsfähigkeit abhängig, wenn er befördert wurde.') comp_quest10 = var_comp(label='Aussage 10: Der erwirtschaftete Ertrag eines AN ist höher, wenn er bei seinem aktuellen AG bleibt.') num_comp_correct = models.IntegerField() first_try = models.BooleanField(initial=True) promotion1 = var_prom('') promotion2 = var_prom('') promotion3 = var_prom('') promotion4 = var_prom('') promotion1inv = var_prom('') promotion2inv = var_prom('') promotion3inv = var_prom('') promotion4inv = var_prom('') promotion1e = var_prom_e('') promotion2e = var_prom_e('') promotion3e = var_prom_e('') promotion4e = var_prom_e('') promotion1einv = var_prom_e('') promotion2einv = var_prom_e('') promotion3einv = var_prom_e('') promotion4einv = var_prom_e('') offer11 = var_offer('') offer12 = var_offer('') offer13 = var_offer('') offer14 = var_offer('') offer21 = var_offer('') offer22 = var_offer('') offer23 = var_offer('') offer24 = var_offer('') offer31 = var_offer('') offer32 = var_offer('') offer41 = var_offer('') offer42 = var_offer('') offer51 = var_offer('') offer52 = var_offer('') offer61 = var_offer('') offer62 = var_offer('') offer11e = var_offer('') offer12e = var_offer('') offer13e = var_offer('') offer14e = var_offer('') offer21e = var_offer('') offer22e = var_offer('') offer23e = var_offer('') offer24e = var_offer('') offer31e = var_offer('') offer32e = var_offer('') offer41e = var_offer('') offer42e = var_offer('') offer51e = var_offer('') offer52e = var_offer('') offer61e = var_offer('') offer62e = var_offer('') quest1_1 = var_close('') quest1_2 = var_close('') quest1_3 = var_close('') quest1_4 = var_close('') quest1_5 = var_close('') quest2_1 = models.IntegerField(label='Ein Schläger und ein Ball kosten gemeinsam 1,10 Euro. Der Schläger kostet um 1,00 Euro mehr als der Ball. Wieviel Euro kostet der Ball?') quest2_2 = models.IntegerField(label='5 Maschinen brauchen 5 Minuten, um 5 Einheiten zu produzieren. Wieveile Minuten brauchen 100 Maschinen um 100 Einheiten zu produzieren?') quest2_3 = models.IntegerField(label='''In einem Teich befindet sich ein Seerosenbeet. Jeden Tag verdoppelt sich die Größe des Beets. Es dauert 48 Tage bis der ganze Teich mit Seerosen bedeckt ist. Nach wievielen Tagen ist die Hälfte des Teiches mit Seerosen bedeckt?''') quest2_4 = var_close('Wenn es um Politik geht, werden oft die Begriffe "links" und "rechts" gebraucht. Wie würden Sie sich selbst auf einer Skala von 0 (links) bis 10 (rechts) einordnen?') quest2_5 = var_close('Wie wichtig ist es Ihnen auf einer Skala von 0 (überhaupt nicht wichtig) bis 10 (sehr wichtig), dass Sie in enem Land leben, das demokratisch regiert wird?') quest2_6 = var_close('Wie schätzen Sie die Neigung anderer Menschen ein Sie ausnutzen, wenn sie die Gelegenheit dazu haben? (0 = andere sind immer fair zu mir; 10 = andere nutzen mich immer aus)') quest3_1 = models.IntegerField(label = 'Ihr Geschlecht', choices = [[1, 'weiblich'], [2, 'männlich'], [3, 'divers'], [4, 'anderes']], widget = widgets.RadioSelect) quest3_2 = models.IntegerField(label = 'Ihr Alter') quest3_3 = models.IntegerField(choices = [[1, 'Betriebswirtschaftslehre'], [2, 'Formalwissenschaften'], [3, 'Geisteswissenschaften'], [4, 'Ingenieurwissenschaften'], [5, 'Kulturwisssenschaften'], [6, 'Medizin- Gesundheits- und Pflegewissenschaften'], [7, 'Naturwissenschaften'], [8, 'Rechtswissenschaften'], [9, 'Sozialwissenschaften'], [10, 'Volkswirtschaftslehre'], [11, 'Sonstige'], [12, 'kein(e) Student(in)']], widget=widgets.RadioSelect, label = 'Welcher Kategorie ist Ihr Studiengang am ehesten zuzuordnen?') case = models.IntegerField() exp_emp = models.IntegerField() # id of employer for expectations switch_emp = models.BooleanField() other_emp1_id = models.IntegerField() other_emp2_id = models.IntegerField() switch_worker12 = models.BooleanField() switch_worker34 = models.BooleanField() switch_worker56 = models.BooleanField() worker1_id = models.IntegerField() worker2_id = models.IntegerField() worker3_id = models.IntegerField() worker4_id = models.IntegerField() worker5_id = models.IntegerField() worker6_id = models.IntegerField() payoff_round = models.FloatField(initial=C.ENDOWMENT) payoff_pay_round = models.FloatField(initial=0) payoff_final = models.FloatField(initial=0) payout = models.FloatField(initial=0) bonus_counting = models.BooleanField(initial=True) bonus_exp = models.FloatField(initial=0) class Worker(ExtraModel): group = models.Link(Group) number = models.IntegerField() color_id = models.IntegerField() color_name = models.StringField() color_de = models.StringField() color_html = models.StringField() current_employer = models.Link(Player) other_employer1 = models.Link(Player) other_employer2 = models.Link(Player) same_color = models.BooleanField(initial = False) offer1 = models.FloatField() offer2 = models.FloatField() offer3 = models.FloatField() employer = models.Link(Player) stay = models.BooleanField(initial=False) ability = models.BooleanField() promoted = models.BooleanField() productivity = models.IntegerField() wage = models.FloatField() class Offer(ExtraModel): group = models.Link(Group) employer = models.Link(Player) worker = models.Link(Worker) promoted = models.BooleanField() amount = models.FloatField() class Case(ExtraModel): player = models.Link(Player) case_type = models.IntegerField() case_number = models.IntegerField() promotion = models.StringField() promotion_inv = models.StringField() promotione = models.StringField() promotione_inv = models.StringField() offer1 = models.StringField() offer2 = models.StringField() offer1e = models.StringField() offer2e = models.StringField() worker1 = models.Link(Worker) worker2 = models.Link(Worker) worker1e = models.Link(Worker) worker2e = models.Link(Worker) worker1_ability = models.StringField() worker2_ability = models.StringField() other_employer = models.IntegerField() # Function to create offers def make_offer(player, worker_number, promoted, amount): Offer.create(group = player.group, employer = player, worker = Worker.filter(group = player.group, number = worker_number)[0], promoted = promoted, amount = amount) # Function to create worker set for pages def set_others(player: Player): worker1 = Worker.filter(group = player.group, number = player.worker1_id)[0] worker2 = Worker.filter(group = player.group, number = player.worker2_id)[0] worker3 = Worker.filter(group = player.group, number = player.worker3_id)[0] worker4 = Worker.filter(group = player.group, number = player.worker4_id)[0] worker5 = Worker.filter(group = player.group, number = player.worker5_id)[0] worker6 = Worker.filter(group = player.group, number = player.worker6_id)[0] other_emp1 = player.group.get_player_by_id(player.other_emp1_id) other_emp2 = player.group.get_player_by_id(player.other_emp2_id) return dict(worker1 = worker1, worker2 = worker2, worker3 = worker3, worker4 = worker4, worker5 = worker5, worker6 = worker6, other_emp1 = other_emp1, other_emp2 = other_emp2) # PAGES class Welcome(Page): @staticmethod def is_displayed(player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): session = player.session return dict(inv_exchange_rate = int(1/session.real_world_currency_per_point)) class ColorGroupAssignment(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class Counting(Page): form_model = 'player' form_fields = ['picture_count'] @staticmethod def is_displayed(player): return player.round_number == 1 class AnnounceInstructions(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class Instructions(Page): if C.TEST_RUN == False: timeout_seconds = 720 else: timeout_seconds = 10 @staticmethod def is_displayed(player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): session = player.session return dict() class CompQuest(Page): form_model = 'player' @staticmethod def is_displayed(player): return player.round_number == 1 form_fields = ['comp_quest1', 'comp_quest2', 'comp_quest3', 'comp_quest4', 'comp_quest5', 'comp_quest6', 'comp_quest7', 'comp_quest8', 'comp_quest9', 'comp_quest10'] @staticmethod def error_message(player: Player, values): solutions = dict(comp_quest1 = True, comp_quest2 = True, comp_quest3 = True, comp_quest4 = False, comp_quest5 = True, comp_quest6 = False, comp_quest7 = False, comp_quest8 = True, comp_quest9 = True, comp_quest10 = True) wrong_answers = [] for i in range(len(solutions)): if list(values.values())[i] != list(solutions.values())[i]: wrong_answers.append(i+1) if player.first_try == True: player.num_comp_correct = C.NUM_COMP_QUEST - len(wrong_answers) player.first_try = False if values != solutions: return_string = ', Aussage '.join(str(x) for x in wrong_answers) return f'Ihre Bewertung folgender Aussagen ist nicht korrekt: Aussage {return_string}
Bitte korrigieren Sie diese und klicken Sie noch einmal auf "Weiter"' class AnnounceRound(Page): pass class Promotion(Page): form_model = 'player' form_fields = ['promotion1', 'promotion2', 'promotion3', 'promotion4', 'promotion1inv', 'promotion2inv', 'promotion3inv', 'promotion4inv', 'offer11', 'offer12', 'offer13', 'offer14', 'offer21', 'offer22', 'offer23', 'offer24'] @staticmethod def vars_for_template(player: Player): others = set_others(player) cases = Case.filter(player = player, case_type = 0) return dict(others=others, cases=cases) @staticmethod def before_next_page(player: Player, timeout_happened): from random import choice # Collecting offers and promotions for current workers in lists offers1 = [player.offer11, player.offer12, player.offer13, player.offer14] offers2 = [player.offer21, player.offer22, player.offer23, player.offer24] promotions = [player.promotion1, player.promotion2, player.promotion3, player.promotion4] # Random decision on case player.case = choice([0,1,2,3]) # Assigning offers and promotions from current employers to workers (worker1 and worker2) worker1 = Worker.filter(group = player.group, number = player.worker1_id)[0] worker1.offer1 = offers1[player.case] worker1.promoted = promotions[player.case] worker1.ability = False if player.case in [1,3] else True worker2 = Worker.filter(group = player.group, number = player.worker2_id)[0] worker2.offer1 = offers2[player.case] worker2.promoted = not(promotions[player.case]) worker2.ability = False if player.case in [0,3] else True class Offers(Page): form_model = 'player' form_fields = ['offer31', 'offer32', 'offer41', 'offer42', 'offer51', 'offer52', 'offer61', 'offer62'] @staticmethod def vars_for_template(player: Player): others = set_others(player) cases1 = Case.filter(player = player, case_type = 1, other_employer = 1) cases2 = Case.filter(player = player, case_type = 1, other_employer = 2) return dict(others = others, cases1 = cases1, cases2 = cases2) @staticmethod def before_next_page(player: Player, timeout_happened): # Creating offers for workers of other employers (worker3,4,5,6) make_offer(player, player.worker3_id, True, player.offer31) make_offer(player, player.worker3_id, False, player.offer32) make_offer(player, player.worker4_id, True, player.offer41) make_offer(player, player.worker4_id, False, player.offer42) make_offer(player, player.worker5_id, True, player.offer51) make_offer(player, player.worker5_id, False, player.offer52) make_offer(player, player.worker6_id, True, player.offer61) make_offer(player, player.worker6_id, False, player.offer62) class AnnounceExpectations(Page): @staticmethod def is_displayed(player): return player.round_number <= C.NUM_EXP_ROUNDS class ExpectationPromotion(Page): form_model = 'player' form_fields = ['promotion1e', 'promotion2e', 'promotion3e', 'promotion4e', 'promotion1einv', 'promotion2einv', 'promotion3einv', 'promotion4einv', 'offer11e', 'offer12e', 'offer13e', 'offer14e', 'offer21e', 'offer22e', 'offer23e', 'offer24e'] @staticmethod def is_displayed(player): return player.round_number <= C.NUM_EXP_ROUNDS + C.NUM_TEST_ROUNDS @staticmethod def vars_for_template(player: Player): exp_emp = player.group.get_player_by_id(player.exp_emp) others = set_others(exp_emp) cases = Case.filter(player = exp_emp, case_type = 0) return dict(others=others, cases=cases, exp_emp=exp_emp) class ExpectationOffers(Page): form_model = 'player' form_fields = ['offer31e', 'offer32e', 'offer41e', 'offer42e', 'offer51e', 'offer52e', 'offer61e', 'offer62e'] @staticmethod def is_displayed(player): return player.round_number <= C.NUM_EXP_ROUNDS + C.NUM_TEST_ROUNDS @staticmethod def vars_for_template(player: Player): exp_emp = player.group.get_player_by_id(player.exp_emp) for other in player.get_others_in_group(): if other.id_in_group != exp_emp.id_in_group: other_emp = other others = set_others(exp_emp) cases1 = Case.filter(player = exp_emp, case_type = 1, other_employer = 1) cases2 = Case.filter(player = exp_emp, case_type = 1, other_employer = 2) return dict(others = others, cases1 = cases1, cases2 = cases2, exp_emp=exp_emp, other_emp = other_emp) class ResultsWaitPage(WaitPage): def after_all_players_arrive(group: Group): from random import random workers = Worker.filter(group = group) for worker in workers: # Identifying relevant offers from other employers (other_employer1 and other_employer2) worker.offer2 = Offer.filter(group=group, employer=worker.other_employer1, worker=worker, promoted = worker.promoted)[0].amount worker.offer3 = Offer.filter(group=group, employer=worker.other_employer2, worker=worker, promoted = worker.promoted)[0].amount # Choosing an employer if random() > C.PROB_FED_UP and worker.offer1 >= max(worker.offer2, worker.offer3): worker.employer = worker.current_employer worker.stay = True worker.wage = worker.offer1 else: if (worker.offer2 > worker.offer3) or (worker.offer2 == worker.offer3 and random() > 0.5): worker.employer = worker.other_employer1 worker.wage = worker.offer2 else: worker.employer = worker.other_employer2 worker.wage = worker.offer3 # Calculating worker productivity: (1+Si)*(ci + di*ai) worker.productivity = (1 + (C.S if worker.stay else 0)) \ * ((C.C2 if worker.promoted else C.C1) + (C.D2 if worker.promoted else C.D1) * (C.AH if worker.ability else C.AL)) # Updating employer's payoff: + worker.productivity - wage worker.employer.payoff_round += worker.productivity - worker.wage class Results(Page): form_model = 'player' @staticmethod def vars_for_template(player: Player): return dict(workers = Worker.filter(group = player.group)) class Quest1(Page): form_model = 'player' form_fields = ['quest1_1', 'quest1_2', 'quest1_3', 'quest1_4', 'quest1_5'] @staticmethod def is_displayed(player): return player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): worker1_html = Worker.filter(current_employer = player, number = player.worker1_id)[0].color_html worker2_html = Worker.filter(current_employer = player, number = player.worker2_id)[0].color_html other_emp1_html = player.group.get_player_by_id(player.other_emp1_id).color_html worker3_html = Worker.filter(group = player.group, number = player.worker1_id)[0].color_html worker4_html = Worker.filter(group = player.group, number = player.worker2_id)[0].color_html return dict( quest1_1_label = 'Wie verbunden fühlen Sie sich dem Arbeitnehmer aus der Farbgruppe {}?'.format(worker1_html), quest1_2_label = 'Wie verbunden fühlen Sie sich dem Arbeitnehmer aus der Farbgruppe {}?'.format(worker2_html), quest1_3_label = 'Wie verbunden fühlen Sie sich dem Arbeitgeber aus der Farbgruppe {}?'.format(other_emp1_html), quest1_4_label = 'Wie verbunden fühlen Sie sich dem Arbeitnehmer aus der Farbgruppe {}?'.format(worker3_html), quest1_5_label = 'Wie verbunden fühlen Sie sich dem Arbeitnehmer aus der Farbgruppe {}?'.format(worker4_html) ) class Quest2(Page): form_model = 'player' form_fields = ['quest2_1', 'quest2_2', 'quest2_3', 'quest2_4', 'quest2_5', 'quest2_6'] @staticmethod def is_displayed(player): return player.round_number == C.NUM_ROUNDS class Quest3(Page): form_model = 'player' form_fields = ['quest3_1', 'quest3_2', 'quest3_3'] @staticmethod def is_displayed(player): return player.round_number == C.NUM_ROUNDS class FinalResultsWaitPage(WaitPage): @staticmethod def is_displayed(player): return player.round_number == C.NUM_ROUNDS wait_for_all_groups = True @staticmethod def after_all_players_arrive(subsession): def compare(input1, input2): return C.BONUS_EXP if abs(input1 - input2) <= C.TOLERANCE_EXP else 0 session = subsession.session players = subsession.get_players() bonus_counting_list = [1,1,1] for player in players: # pick payoff from payoff relevant round player_in_pay_round = player.in_round(C.PAYING_ROUND) player.payoff_pay_round = player_in_pay_round.payoff_round # check expectations exp_emp = player.group.get_player_by_id(player.exp_emp) exp_emp_in_pay_round = exp_emp.in_round(C.PAYING_ROUND) player.bonus_exp += compare(player_in_pay_round.promotion1e, exp_emp_in_pay_round.promotion1) player.bonus_exp += compare(player_in_pay_round.promotion2e, exp_emp_in_pay_round.promotion2) player.bonus_exp += compare(player_in_pay_round.promotion3e, exp_emp_in_pay_round.promotion3) player.bonus_exp += compare(player_in_pay_round.promotion4e, exp_emp_in_pay_round.promotion4) player.bonus_exp += compare(player_in_pay_round.offer11e, exp_emp_in_pay_round.offer11) player.bonus_exp += compare(player_in_pay_round.offer12e, exp_emp_in_pay_round.offer12) player.bonus_exp += compare(player_in_pay_round.offer13e, exp_emp_in_pay_round.offer13) player.bonus_exp += compare(player_in_pay_round.offer14e, exp_emp_in_pay_round.offer14) player.bonus_exp += compare(player_in_pay_round.offer21e, exp_emp_in_pay_round.offer21) player.bonus_exp += compare(player_in_pay_round.offer22e, exp_emp_in_pay_round.offer22) player.bonus_exp += compare(player_in_pay_round.offer23e, exp_emp_in_pay_round.offer23) player.bonus_exp += compare(player_in_pay_round.offer24e, exp_emp_in_pay_round.offer24) player.bonus_exp += compare(player_in_pay_round.offer31e, exp_emp_in_pay_round.offer31) player.bonus_exp += compare(player_in_pay_round.offer32e, exp_emp_in_pay_round.offer32) player.bonus_exp += compare(player_in_pay_round.offer41e, exp_emp_in_pay_round.offer41) player.bonus_exp += compare(player_in_pay_round.offer42e, exp_emp_in_pay_round.offer42) player.bonus_exp += compare(player_in_pay_round.offer51e, exp_emp_in_pay_round.offer51) player.bonus_exp += compare(player_in_pay_round.offer52e, exp_emp_in_pay_round.offer52) player.bonus_exp += compare(player_in_pay_round.offer61e, exp_emp_in_pay_round.offer61) player.bonus_exp += compare(player_in_pay_round.offer62e, exp_emp_in_pay_round.offer62) # set group bonus for counting to False if count of player is false player_in_first_round = player.in_round(1) if player_in_first_round.picture_count != C.NUM_COLOR_FIELDS: bonus_counting_list[player.color_id] = False bonus_counting_list = [any(i) for i in zip(bonus_counting_list, C.PREVIOUS_COUNTING_RBG)] for player in players: # setting bonus for counting task player.bonus_counting = bonus_counting_list[player.color_id] # calculate final payoff and EUR payoff amount player.payoff_final = (player.payoff_pay_round + int(player.bonus_counting) * C.BONUS_COUNTING + player.num_comp_correct * C.BONUS_COMP_QUEST + player.bonus_exp) player.participant.payoff = cu(player.payoff_final * C.EXCHANGE_RATE) class FinalResults(Page): form_model = 'player' @staticmethod def is_displayed(player): return player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): return dict(num_exp_correct = player.bonus_exp/C.BONUS_EXP, bonus_comp_quest = player.num_comp_correct * C.BONUS_COMP_QUEST, inv_exchange_rate = int(1/player.session.real_world_currency_per_point)) class End(Page): form_model = 'player' @staticmethod def is_displayed(player): return player.round_number == C.NUM_ROUNDS page_sequence = [ Welcome, ColorGroupAssignment, Counting, AnnounceInstructions, Instructions, CompQuest, AnnounceRound, Promotion, Offers, AnnounceExpectations, ExpectationPromotion, ExpectationOffers, ResultsWaitPage, Results, Quest1, Quest2, Quest3, FinalResultsWaitPage, FinalResults ] # page_sequence = [ExpectationOffers] # AnnounceRound, Promotion, AnnounceExpectations, Expectations, ResultsWaitPage, Results, # Quest1, Quest2, Quest3, FinalResultsWaitPage, FinalResults] # page_sequence = [Counting] #cd Dropbox\Programming\otree\qlm