from otree.api import * import pandas as pd import random doc = """""" rent_label = "Ihre Schätzung der Miete in EUR/Monat:" rent_revision_label = "Ihre neue Schätzung der Miete in EUR/Monat:" price_revision_label = "Ihre Schätzung des gelisteten Preises in EUR:" price_ai_label = "Was denken Sie, was die KI als Listenpreis vorhersagt?
Ihre Schätzung der KI-Vorhersage in EUR:" conf_label = "Wie sicher sind Sie sich mit dieser Schätzung?\nAngabe von 1 (unsicher) bis 7 (sicher)." del_conf_label = "Wie sicher sind Sie sich mit dieser Entscheidung?\nAngabe von 1 (unsicher) bis 7 (sicher)." task_diff_label = "Wie schwierig finden Sie diese Entscheidung?\nAngabe von 1 (einfach) bis 7 (schwierig)." conf_choices = [[1, ""], [2, ""], [3, ""], [4, ""], [5, ""]] err_label = "Bitte geben Sie an, wie stark Sie die Abweichung Ihrer Schätzung vom realen Wert einschätzen.\nAngabe von 0 EUR (perfekte Schätzung) bis 1000 EUR." err_choices = [[1, "0 EUR"], [2, "200 EUR"], [3, "400 EUR"], [4, "600 EUR"], [5, "800 EUR"], [6, "1000 EUR"]] delegate_label = "Möchten Sie die Schätzung delegieren, also die Schätzung der KI übernehmen?" perc_control_label = "Bitte geben Sie Ihre Zustimmung zu folgender Aussage von 1 (trifft nicht zu) bis 7 (trifft voll zu) an." \ "
Ich verfüge über das Wissen und die Fähigkeit, diese Entscheidung zu treffen." delegate_choices = [[True, "Ich lasse die KI die Schätzung machen."], [False, "Ich mache die Schätzung selbst."]] antic_reg_label = "Wie stark würden Sie es bedauern, wenn Sie diese Entscheidung an die KI delegieren " \ "und die KI eine falsche Schätzung abgegeben hat? Angabe von 1 (gar nicht) bis 7 (sehr stark)." exp_err_label = "Was denken Sie, wie weit Ihre Schätzung vom realen Wert abweicht?
Angabe der absolute Abweichung in EUR, wobei der Wert 0 einer perfekten Schätzung entspricht." diff_label = "Wie schwierig ist Ihnen die Schätzung gefallen?\nAngabe von 1 (einfach) bis 7 (schwierig)." def_val = None blank_val = False class C(BaseConstants): NAME_IN_URL = 'immo_exp' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 CHOICES = [] # "Geschlecht", "Migrationshintergrund", "Politische Ansichten"] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass def make_field(label, blank=False): return models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7], label=label, widget=widgets.RadioSelectHorizontal, blank=blank ) def format_german_number(number, precision=0): # build format string format_str = '{{:,.{}f}}'.format(precision) # make number string number_str = format_str.format(number) # replace chars return number_str.replace(',', 'X').replace('.', ',').replace('X', '.') def add_plus_if_not_minus(string): return '+' + string if not string.startswith('-') else string def make_rank_field(label): return models.StringField(choices=C.CHOICES, label=label) def shuffle_form_fields(fields, item=1): form_fields = fields blocksize = 3 # remove items from list that are not blocks of 3 items = form_fields[0:item] del form_fields[0:item] blocks = [form_fields[i:i + blocksize] for i in range(0, len(form_fields), blocksize)] for i in items: blocks.append([i]) random.shuffle(blocks) for subblock in blocks: random.shuffle(subblock) form_fields = [formfield for subblock in blocks for formfield in subblock] return form_fields def creating_session(subsession): for player in subsession.get_players(): participant = player.participant # treatment and question/rel_task_name order randomization treatments = ["ai", "xai_glob", "xai_loc", "xai_both"] participant.treatment = random.choice(treatments) blind_first = [True, False] participant.blind_first = random.choice(blind_first) # shuffle of stages 1/2, 3, 4/5 my_indices = list(pd.read_csv("_static/global/exp_global_data.csv", index_col=0).index) random.shuffle(my_indices) participant.immoSampleExamples = my_indices[:3] participant.immoSampleDelegation = my_indices[3:7] # participant.immoSampleLast = my_indices[6] class Player(BasePlayer): # intro data is_mobile = models.BooleanField() donate_org = models.StringField(label= "", # "An welche Organisation möchten Sie Ihr in der Studie verdientes Geld spenden?", choices=["Deutscher Tierschutzbund e.V.", "SOS-Kinderdorf e.V.", "Ärzte ohne Grenzen e.V.", "Diakonie Katastrophenhilfe", "atmosfair gGmbH (Zweck: Klimaschutz)", "Ich möchte nicht spenden. Das verdiente Geld verbleibt bei der Goethe-Universität Frankfurt.", ], widget=widgets.RadioSelect ) consent = models.BooleanField(choices=["Ich möchte an der Studie teilnehmen."], label="Durch das Ankreuzen des Kästchens erkläre ich mich mit der Teilnahme an der Studie einverstanden.") # stage 2 data xai_check = models.StringField(label="Basierend auf den obigen Erklärungen der KI: " "Wie wirkt sich ein unterdurchschnittlicher Anteil Grünenwählender im " "Stadtteil tendenziell auf die Preisvorhersage aus?", choices=["Senkend", "Neutral", "Erhöhend"], widget=widgets.RadioSelectHorizontal ) perc_acc_self = models.FloatField(label=exp_err_label, min=0, default=def_val) perc_acc_ai = models.FloatField(label=exp_err_label, min=0, default=def_val) perc_understanding = make_field("Ich verstehe, wie die KI ihre Vorhersagen trifft.", blank=blank_val) perc_congruence = make_field("Die Art, wie die KI ihre Vorhersagen trifft, ist ähnlich zu meinem Vorgehen, um die Listenpreise zu schätzen.", blank=blank_val) perc_predictability = make_field("Die Vorhersagen der KI sind für mich vorhersehbar.", blank=blank_val) cog_trust1 = make_field("Diese KI ist kompetent und effektiv bei der Vorhersage des Listenpreises.", blank=blank_val) # cog_trust2 = make_field("Diese KI erfüllt ihre Aufgabe, die Kaltmiete vorherzusagen, sehr gut.", blank=True) # cog_trust3 = make_field( # "Insgesamt ist diese KI ein fähiges und kompetentes Werkzeug für die Vorhersage der Kaltmiete.", blank=True) # integ_trust1 = make_field("Diese KI gibt unvoreingenommene Empfehlungen.", blank=True) # attention check 1 # integ_trust2 = make_field("Diese KI ist unehrlich.", blank=True) # integ_trust3 = make_field("Ich halte diese KI für integer.", blank=True) # attention check 2 # emo_trust1 = make_field( # "Ich fühle mich unsicher, wenn ich mich bei meiner Vorhersage der Kaltmiete auf diese KI verlasse.", blank=True) # emo_trust2 = make_field( # "Ich fühle mich wohl, wenn ich mich bei meiner Vorhersage der Kaltmiete auf diese KI verlasse.", blank=True) # emo_trust3 = make_field( # "Ich fühle mich zufrieden, wenn ich mich bei meiner Vorhersage der Kaltmiete auf diese KI verlasse.", blank=True) # stage 3 data delegate_dec4 = models.BooleanField(label=delegate_label, choices=delegate_choices) delegate_dec5 = models.BooleanField(label=delegate_label, choices=delegate_choices) delegate_dec6 = models.BooleanField(label=delegate_label, choices=delegate_choices) delegate_dec7 = models.BooleanField(label=delegate_label, choices=delegate_choices) del_conf4 = make_field(del_conf_label, blank=blank_val) del_conf5 = make_field(del_conf_label, blank=blank_val) del_conf6 = make_field(del_conf_label, blank=blank_val) del_conf7 = make_field(del_conf_label, blank=blank_val) task_diff4 = make_field(task_diff_label, blank=blank_val) task_diff5 = make_field(task_diff_label, blank=blank_val) task_diff6 = make_field(task_diff_label, blank=blank_val) task_diff7 = make_field(task_diff_label, blank=blank_val) antic_reg4 = make_field(antic_reg_label, blank=blank_val) antic_reg5 = make_field(antic_reg_label, blank=blank_val) antic_reg6 = make_field(antic_reg_label, blank=blank_val) antic_reg7 = make_field(antic_reg_label, blank=blank_val) perc_ctrl4 = make_field(perc_control_label, blank=blank_val) perc_ctrl5 = make_field(perc_control_label, blank=blank_val) perc_ctrl6 = make_field(perc_control_label, blank=blank_val) perc_ctrl7 = make_field(perc_control_label, blank=blank_val) # stage 5 data guess4, guess5, guess6, guess7 = models.IntegerField(label=price_revision_label, min=0, default=def_val), \ models.IntegerField(label=price_revision_label, min=0, default=def_val), \ models.IntegerField(label=price_revision_label, min=0, default=def_val), \ models.IntegerField(label=price_revision_label, min=0, default=def_val) guess_ai4, guess_ai5, guess_ai6, guess_ai7 = models.IntegerField(label=price_ai_label, min=0, default=def_val), \ models.IntegerField(label=price_ai_label, min=0, default=def_val), \ models.IntegerField(label=price_ai_label, min=0, default=def_val), \ models.IntegerField(label=price_ai_label, min=0, default=def_val) # conf4 = make_field(conf_label, blank=True) # conf5 = make_field(conf_label, blank=True) # conf6 = make_field(conf_label, blank=True) # expected errors are omitted after prolific pilot (09 Jan 2024) # experr4 = models.IntegerField(label=exp_err_label, min=0, default=def_val) # experr5 = models.IntegerField(label=exp_err_label, min=0, default=def_val) # experr6 = models.IntegerField(label=exp_err_label, min=0, default=def_val) # ai_experr4 = models.IntegerField(label=exp_err_label.replace("Ihre Schätzung ", "die Schätzung der KI "), min=0, default=def_val) # ai_experr5 = models.IntegerField(label=exp_err_label.replace("Ihre Schätzung ", "die Schätzung der KI "), min=0, default=def_val) # ai_experr6 = models.IntegerField(label=exp_err_label.replace("Ihre Schätzung ", "die Schätzung der KI "), min=0, default=def_val) # diff4 = make_field(diff_label, blank=True) # diff5 = make_field(diff_label, blank=True) # diff6 = make_field(diff_label, blank=True) # stage 5 click_times4 = models.LongStringField(default="", blank=True) click_times5 = models.LongStringField(default="", blank=True) click_times6 = models.LongStringField(default="", blank=True) click_times7 = models.LongStringField(default="", blank=True) ## last stage # delegate_dec_last = models.BooleanField(label=delegate_label, choices=delegate_choices, default=def_val) # del_conf_last = make_field(del_conf_label, blank=blank_val) # task_diff_last = make_field(task_diff_label, blank=blank_val) # antic_reg_last = make_field(antic_reg_label, blank=blank_val) # last page data age = models.IntegerField(label="Wie alt sind Sie?", choices=range(16, 100)) gender = models.StringField(label="Was ist Ihr Geschlecht?", widget=widgets.RadioSelectHorizontal, choices=["Weiblich", "Männlich", "Divers"]) degree = models.StringField(label="Was ist ihr höchster akademischer Abschluss?", choices=["Hauptschulabschluss", "Realschulabschluss", "Abitur", "Bachelor", "Master", "Doktor", "anderer Abschluss"]) experience_industry = models.IntegerField( label="Wie viele Jahre Berufserfahrung in der Immobilienbranche besitzen Sie?", choices=range(0, 100)) experience_task_volume = models.IntegerField(label="Was schätzen Sie, wie viele Immobilien (sowohl Miet- als auch Kaufobjekte) " "Sie in Ihrer beruflichen Laufbahn bereits monetär bewertet haben?") experience_task_likert = models.IntegerField(label="Über wie viel " "Erfahrung in der Bewertung von Immobilien haben Sie?", widget=widgets.RadioSelectHorizontal, choices=range(0, 11)) # overconfidence1 = models.IntegerField(label="Ich denke, dass ich besser darin bin, Immobilienobjekte akkurat zu " # "bewerten als der durchschnittliche Immobilienunternehmer in Deutschland.", # widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7]) # overconfidence2 = models.IntegerField(label="Ich denke, dass ich schlauer bin als der durchschnittliche Deutsche.", # widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7]) risk_aversion = models.IntegerField(label="Im Allgemeinen, wie bereit sind Sie, Risiken einzugehen?", widget=widgets.RadioSelectHorizontal, choices=range(0, 11)) ai_familiarity = models.IntegerField(label="Ich bin mit Vorhersagesoftware vertraut, die Informationen " "bereitstellt, um menschliche Entscheidungen zu unterstützen.", widget=widgets.RadioSelectHorizontal, choices=range(0, 11)) email = models.StringField(label="Ihre E-Mail Adresse:", blank=True) class Intro(Page): form_model = 'player' @staticmethod def get_form_fields(player): if player.session.config['organization'] == "nassau" or player.session.config['organization'] == "abg": return ['is_mobile', 'donate_org', 'consent',] else: return ['is_mobile', 'consent'] class Stage2(Page): form_model = "player" @staticmethod def get_form_fields(player): if player.participant.treatment == "xai_both" or player.participant.treatment == "xai_glob": return ["xai_check"] else: return [] @staticmethod def vars_for_template(player): # read in houses for frontend houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["shap_city"] = houses["shap_city_Berlin"] + houses["shap_city_Frankfurt"] + \ houses["shap_city_Cologne"] + houses["shap_city_Dusseldorf"] + \ houses["shap_city_Hamburg"] + houses["shap_city_Munich"] + \ houses["shap_city_Stuttgart"] houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for col in houses.columns: if "shap" in col: houses[col] = houses[col].apply(format_german_number) houses[col] = houses[col].apply(add_plus_if_not_minus) houses["base_value"] = houses["base_value"].apply(format_german_number) for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] houses["pred"] = houses["pred"].apply(format_german_number) # prepare dictionary for frontend indices_to_show = player.participant.immoSampleExamples ord = 0 houses_in_order = [] for i in indices_to_show: ord += 1 focal_dic = houses[houses.index == i].to_dict('records') focal_dic[0]["ind"] = i focal_dic[0]["ord"] = ord focal_dic[0]["revision"] = "revision" + str(ord) focal_dic[0]["conf"] = "rev_conf" + str(ord) focal_dic[0]["experr"] = "rev_experr" + str(ord) houses_in_order.append(focal_dic) return dict( houses_in_order=houses_in_order, base_value=houses.iloc[0]["base_value"] ) class Stage2_questions(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["perc_acc_self", "perc_acc_ai", "perc_understanding", "perc_congruence", "perc_predictability", "cog_trust1", ] # "cog_trust2", "cog_trust3", # "integ_trust1", # "integ_trust2", "integ_trust3", # "emo_trust1", ] # "emo_trust2", "emo_trust3", ] return form_fields class Stage3(Page): pass class Stage3_h4(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["delegate_dec4", "del_conf4", "task_diff4", "antic_reg4", "perc_ctrl4"] return form_fields @staticmethod def vars_for_template(player): # prepare houses dictionary (for each player individually because of random order) houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleDelegation[0] focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class Stage3_h5(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["delegate_dec5", "del_conf5", "task_diff5", "antic_reg5", "perc_ctrl5"] return form_fields @staticmethod def vars_for_template(player): # prepare houses dictionary (for each player individually because of random order) houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleDelegation[1] focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class Stage3_h6(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["delegate_dec6", "del_conf6", "task_diff6", "antic_reg6", "perc_ctrl6"] return form_fields @staticmethod def vars_for_template(player): # prepare houses dictionary (for each player individually because of random order) houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleDelegation[2] focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class Stage3_h7(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["delegate_dec7", "del_conf7", "task_diff7", "antic_reg7", "perc_ctrl7"] return form_fields @staticmethod def vars_for_template(player): # prepare houses dictionary (for each player individually because of random order) houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleDelegation[3] focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class Stage4_h4(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["guess4", "guess_ai4",] # "ai_experr4", "experr4", ] # "conf4", "diff4", return form_fields @staticmethod def vars_for_template(player): # prepare houses dictionary (for each player individually because of random order) houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleDelegation[0] focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class Stage4_h5(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["guess5", "guess_ai5",] # "ai_experr5", "experr5", ] return form_fields @staticmethod def vars_for_template(player): houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleDelegation[1] focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class Stage4_h6(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["guess6", "guess_ai6",] # "ai_experr6", "experr6", ] return form_fields @staticmethod def vars_for_template(player): houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleDelegation[2] focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class Stage4_h7(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["guess7", "guess_ai7",] # "ai_experr6", "experr6", ] return form_fields @staticmethod def vars_for_template(player): houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleDelegation[3] focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class Stage5(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["click_times4", "click_times5", "click_times6", "click_times7", ] # "feeling_well", "feeling_regret" return form_fields @staticmethod def vars_for_template(player): # read in houses for frontend houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Köln" if h.city_Cologne else "Düsseldorf" if h.city_Dusseldorf else "Hamburg" if h.city_Hamburg else "München" if h.city_Munich else "Stuttgart" if h.city_Stuttgart else "Other" for i, h in houses.iterrows()] houses["constr_year"] = houses["constr_year"].apply(round) houses["shap_city"] = houses["shap_city_Berlin"] + houses["shap_city_Frankfurt"] + \ houses["shap_city_Cologne"] + houses["shap_city_Dusseldorf"] + \ houses["shap_city_Hamburg"] + houses["shap_city_Munich"] + \ houses["shap_city_Stuttgart"] houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for col in houses.columns: if "shap" in col: houses[col] = houses[col].apply(format_german_number) houses[col] = houses[col].apply(add_plus_if_not_minus) houses["base_value"] = houses["base_value"].apply(format_german_number) for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] # get indices of houses indices_to_show = player.participant.immoSampleDelegation # get prior guess and decision prior_player_guesses = [player.guess4, player.guess5, player.guess6, player.guess7] prior_player_decisions = [player.delegate_dec4, player.delegate_dec5, player.delegate_dec6, player.delegate_dec7] ord = 0 houses_in_order = [] for i in indices_to_show: ord += 1 focal_dic = houses[houses.index == i].to_dict('records') # check if "auszahlungsrelevant" estimate is correct if prior_player_decisions[ord - 1]: correct_estimate = abs(focal_dic[0]["pred"] / focal_dic[0]["y"] - 1) < 0.1 else: correct_estimate = abs(prior_player_guesses[ord - 1] / focal_dic[0]["y"] - 1) < 0.1 focal_dic[0]["correct_estimate"] = correct_estimate focal_dic[0]["pred"] = format_german_number(focal_dic[0]["pred"]) focal_dic[0]["y"] = format_german_number(focal_dic[0]["y"]) focal_dic[0]["ind"] = i focal_dic[0]["ord"] = ord focal_dic[0]["click_times"] = "click_times" + str(ord + 3) focal_dic[0]["guess"] = format_german_number(prior_player_guesses[ord - 1]) focal_dic[0]["delegation_dec"] = prior_player_decisions[ord - 1] houses_in_order.append(focal_dic) return dict( houses_in_order=houses_in_order, base_value=houses.iloc[0].base_value ) class StageLast(Page): form_model = "player" @staticmethod def get_form_fields(player): form_fields = ["delegate_dec_last", "del_conf_last", "task_diff_last", "antic_reg_last"] return form_fields @staticmethod def vars_for_template(player): # prepare houses dictionary (for each player individually because of random order) houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) # process house data for frontend houses["city"] = ["Berlin" if h.city_Berlin else "Frankfurt" if h.city_Frankfurt else "Other" for i, h in houses.iterrows()] houses["sqm"] = houses['sqm'].astype(str).str.replace('.', ',') houses["storey"] = ["Souterrain" if s == -1 else "Erdgeschoss" if s == 0 else str(s).replace(".0", "") + ". Stock" for s in houses.storey] houses["n_rooms"] = houses["n_rooms"].astype(str).str.replace('.0', '').replace('.', ',') for bool_col in ['balcony', ]: houses[bool_col] = ["Ja" if b == 1 else "Nein" for b in houses[bool_col]] for ord_col in ['green_share', 'unemployment']: houses[ord_col] = ["Unterdurch­schnittlich" if o == 1 else "Durch­schnittlich" if o == 2 else "Überdurch­schnittlich" for o in houses[ord_col]] index_to_show = player.participant.immoSampleLast focal_dic = houses[houses.index == index_to_show].to_dict('records')[0] focal_dic["ind"] = index_to_show return dict( house=focal_dic ) class LastPage(Page): form_model = "player" @staticmethod def get_form_fields(player): my_fields = ["age", "gender", "degree", "experience_industry", "experience_task_volume", "risk_aversion", "ai_familiarity"] if player.session.config["organization"] in ["nassau", "abg", "vonpoll", "other"]: return my_fields + ["email"] else: return my_fields class RedirectPage(Page): @staticmethod def vars_for_template(player): # get houses houses = pd.read_csv("_static/global/exp_global_data.csv", index_col=0) indices_to_check = player.participant.immoSampleDelegation # get prior guess and decision prior_player_guesses = [player.guess4, player.guess5, player.guess6, player.guess7] prior_player_decisions = [player.delegate_dec4, player.delegate_dec5, player.delegate_dec6, player.delegate_dec7] n_correct_estimates = 0 ord = 0 for i in indices_to_check: foc_house = houses[houses.index == i] # check if "auszahlungsrelevant" estimate is correct if prior_player_decisions[ord]: correct_estimate = abs(foc_house["pred"] / foc_house["y"] - 1) < 0.1 else: correct_estimate = abs(prior_player_guesses[ord] / foc_house["y"] - 1) < 0.1 if correct_estimate.all(): n_correct_estimates += 1 ord += 1 var_money = format_german_number(n_correct_estimates*0.5, precision=2) return dict( n_correct=n_correct_estimates, var_money=var_money ) page_sequence = [Intro, Stage2, Stage2_questions, Stage3, Stage3_h4, Stage3_h5, Stage3_h6, Stage3_h7, Stage4_h4, Stage4_h5, Stage4_h6, Stage4_h7, Stage5, LastPage, RedirectPage]