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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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] = ["Unterdurchschnittlich" if o == 1 else "Durchschnittlich"
if o == 2 else "Überdurchschnittlich" 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]