# ============================================================================= # situations_config/__init__.py # # Central definition of all options and situations used across the experiment. # # HOW TO EDIT: # 1. Add rows to _ALLOC_ROWS or _LOTTERY_ROWS to define options. # 2. Add rows to _ALLOC_SITUATIONS or _LOTTERY_SITUATIONS to define situations. # Everything below the "── Auto-build ──" lines is generated automatically. # ============================================================================= import json import random STARTING_AMOUNT = 10 # Shared endowment for all allocation options (MU) # ============================================================================= # OPTIONS # ============================================================================= # --- Allocation options --- # own_payoff is derived automatically as STARTING_AMOUNT - transfer # # ( option_id, transfer, multiplier ) _ALLOC_ROWS = [ ("o_DG1", 3, 2), ("o_DG2", 5, 2), ("o_DG3", 10, 2), ("o_DG4", 3, 2.5), ("o_DG5", 5, 2.5), ("o_DG6", 0, 2), ("o_DG7", 1, 2), ("o_DG8", 7, 2), ("o_DG9", 6, 2), ("o_DG10", 2, 2), ("o_DG11", 2, 1.8), ("o_DG12", 2, 2.5), ("o_DG13", 3, 2.2), ("o_DG14", 3, 2.5), ("o_DG15", 4, 2), ("o_DG16", 4, 2.5), ("o_DG17", 5, 1.8), ("o_DG18", 5, 2.2), ("o_DG19", 7, 2.5), ("o_DG20", 8, 2), ("o_DG21", 9, 2.5), # add more rows here ... ] # --- Lottery options --- # # ( option_id, left_outcome, right_outcome, probability_left ) _LOTTERY_ROWS = [ ("o_LT1", 10, 0, 1.0), ("o_LT2", 11, 9, 0.5), ("o_LT3", 13, 8, 0.5), ("o_LT4", 17, 7, 0.5), ("o_LT5", 12, 9, 0.8), ("o_LT6", 15, 5, 0.8), ("o_LT7", 9, 9, 1.0), ("o_LT8", 9.5, 9.5, 1.0), ("o_LT9", 10.5, 10.5, 1.0), ("o_LT10", 11, 9, 0.4), ("o_LT11", 11, 9, 0.6), ("o_LT12", 11, 11, 1.0), ("o_LT13", 13, 8, 0.4), ("o_LT14", 13, 8, 0.6), ("o_LT15", 14, 4, 0.8), ("o_LT16", 14, 9, 0.8), ("o_LT17", 16, 8, 0.5), ("o_LT18", 18, 6, 0.5), # add more rows here ... ] # ── Auto-build OPTIONS dict ─────────────────────────────────────────────────── OPTIONS = {} for (oid, transfer, mult) in _ALLOC_ROWS: OPTIONS[oid] = { "option_id": oid, "type": "allocation", "own_payoff": STARTING_AMOUNT - transfer, "transfer": transfer, "multiplier": mult, } for (oid, l_out, r_out, p_left) in _LOTTERY_ROWS: OPTIONS[oid] = { "option_id": oid, "type": "lottery", "left_outcome": l_out, "right_outcome": r_out, "probability_left": p_left, } # ============================================================================= # SITUATIONS # ============================================================================= # Each situation pairs option A with option B. # Which one appears on the left/right is randomised at runtime. # --- Allocation situations --- # # ( situation_id, option_A, option_B, set, # norm_chosen_A_gr10, norm_chosen_A_gr8, norm_chosen_A_gr6, # modal_app_a_gr10, modal_app_b_gr10, # modal_app_a_gr8, modal_app_b_gr8, # modal_app_a_gr6, modal_app_b_gr6 ) # # norm_chosen_A_grX = number of people in group X who chose option A (out of 10) # modal_app_a_grX = modal appropriateness rating for option A in group X (1–4) # modal_app_b_grX = modal appropriateness rating for option B in group X (1–4) # Appropriateness ratings are None for threshold situations (not elicited) # Tied modes are represented as "2|3" etc. _ALLOC_SITUATIONS = [ ("s_DG1", "o_DG1", "o_DG8", "threshold", 10, 9, 9, None, None, None, None, None, None), ("s_DG2", "o_DG1", "o_DG3", "threshold", 9, 8, 8, None, None, None, None, None, None), ("s_DG3", "o_DG1", "o_DG4", "threshold", 1, 2, 2, None, None, None, None, None, None), ("s_DG4", "o_DG1", "o_DG5", "threshold", 10, 8, 8, None, None, None, None, None, None), ("s_DG5", "o_DG1", "o_DG6", "threshold", 1, 3, 4, None, None, None, None, None, None), ("s_DG6", "o_DG2", "o_DG3", "threshold", 10, 10, 10, None, None, None, None, None, None), ("s_DG7", "o_DG2", "o_DG4", "threshold", 0, 0, 0, None, None, None, None, None, None), ("s_DG8", "o_DG2", "o_DG5", "threshold", 1, 3, 4, None, None, None, None, None, None), ("s_DG9", "o_DG2", "o_DG7", "threshold", 0, 3, 3, None, None, None, None, None, None), ("s_DG10", "o_DG3", "o_DG4", "threshold", 0, 0, 0, None, None, None, None, None, None), ("s_DG11", "o_DG3", "o_DG5", "threshold", 1, 0, 1, None, None, None, None, None, None), ("s_DG12", "o_DG3", "o_DG6", "threshold", 1, 2, 2, None, None, None, None, None, None), ("s_DG13", "o_DG4", "o_DG9", "threshold", 10, 10, 9, None, None, None, None, None, None), ("s_DG14", "o_DG4", "o_DG6", "threshold", 0, 2, 3, None, None, None, None, None, None), ("s_DG15", "o_DG5", "o_DG7", "threshold", 1, 3, 2, None, None, None, None, None, None), ("s_DG16", "o_DG10", "o_DG21", "prediction", 10, 9, 9, "2", "4", "3", "4", "2", "1"), ("s_DG17", "o_DG15", "o_DG3", "prediction", 10, 10, 10, "3", "4", "3", "1", "3", "1"), ("s_DG18", "o_DG11", "o_DG14", "prediction", 9, 8, 6, "2", "4", "2", "4", "1|2", "4"), ("s_DG19", "o_DG13", "o_DG14", "prediction", 0, 2, 3, "3", "4", "3", "4", "3", "4"), ("s_DG20", "o_DG7", "o_DG5", "prediction", 9, 8, 7, "1|2", "4", "2", "4", "2", "2|4"), ("s_DG21", "o_DG15", "o_DG19", "prediction", 10, 8, 8, "3|4", "4", "3", "4", "3", "1"), ("s_DG22", "o_DG17", "o_DG5", "prediction", 1, 2, 3, "3", "3", "3", "3", "3", "1|4"), ("s_DG23", "o_DG18", "o_DG5", "prediction", 1, 2, 2, "3", "4", "3", "2|4","3", "1|2"), ("s_DG24", "o_DG3", "o_DG12", "prediction", 1, 1, 2, "3", "2", "1|4", "3", "1|2", "3"), ("s_DG25", "o_DG21", "o_DG16", "prediction", 1, 2, 2, "4", "3", "1", "2", "1", "2"), ("s_DG26", "o_DG16", "o_DG6", "prediction", 1, 3, 4, "4", "1", "3", "1", "3", "1"), ("s_DG27", "o_DG20", "o_DG6", "prediction", 0, 2, 3, "4", "1", "4", "1", "1", "1"), ] _LOTTERY_SITUATIONS = [ ("s_LT1", "o_LT1", "o_LT2", "threshold", 7, 8, 8, None, None, None, None, None, None), ("s_LT2", "o_LT1", "o_LT3", "threshold", 2, 3, 3, None, None, None, None, None, None), ("s_LT3", "o_LT1", "o_LT4", "threshold", 1, 2, 2, None, None, None, None, None, None), ("s_LT4", "o_LT1", "o_LT5", "threshold", 2, 2, 3, None, None, None, None, None, None), ("s_LT5", "o_LT1", "o_LT6", "threshold", 1, 1, 3, None, None, None, None, None, None), ("s_LT6", "o_LT2", "o_LT3", "threshold", 1, 1, 0, None, None, None, None, None, None), ("s_LT7", "o_LT2", "o_LT4", "threshold", 0, 1, 1, None, None, None, None, None, None), ("s_LT8", "o_LT2", "o_LT5", "threshold", 0, 2, 2, None, None, None, None, None, None), ("s_LT9", "o_LT2", "o_LT6", "threshold", 3, 4, 6, None, None, None, None, None, None), ("s_LT10", "o_LT3", "o_LT4", "threshold", 0, 2, 2, None, None, None, None, None, None), ("s_LT11", "o_LT3", "o_LT5", "threshold", 3, 1, 4, None, None, None, None, None, None), ("s_LT12", "o_LT3", "o_LT6", "threshold", 2, 4, 3, None, None, None, None, None, None), ("s_LT13", "o_LT4", "o_LT5", "threshold", 6, 4, 7, None, None, None, None, None, None), ("s_LT14", "o_LT4", "o_LT6", "threshold", 3, 3, 5, None, None, None, None, None, None), ("s_LT15", "o_LT5", "o_LT6", "threshold", 6, 7, 6, None, None, None, None, None, None), ("s_LT16", "o_LT8", "o_LT2", "prediction", 1, 2, 2, "4", "3", "4", "3", "3", "3"), ("s_LT17", "o_LT9", "o_LT2", "prediction", 9, 8, 6, "4", "3", "4", "3", "4", "3"), ("s_LT18", "o_LT7", "o_LT5", "prediction", 1, 1, 1, "1|4", "4", "1|4", "3", "1", "3"), ("s_LT19", "o_LT9", "o_LT16", "prediction", 0, 2, 4, "4", "2", "3|4", "3", "3", "3"), ("s_LT20", "o_LT7", "o_LT15", "prediction", 1, 3, 4, "4", "3", "4", "3", "1|4", "1|3"), ("s_LT21", "o_LT12", "o_LT6", "prediction", 1, 3, 4, "4", "2|4","4", "2", "3", "1|3"), ("s_LT22", "o_LT2", "o_LT17", "prediction", 0, 2, 2, "4", "2", "3", "2", "3", "3"), ("s_LT23", "o_LT2", "o_LT18", "prediction", 1, 2, 0, "3", "3", "3", "2|3","3", "2"), ("s_LT24", "o_LT11", "o_LT5", "prediction", 0, 2, 3, "3", "4", "3", "4", "3", "3"), ("s_LT25", "o_LT10", "o_LT16", "prediction", 0, 0, 0, "3", "4", "3", "4", "2|3", "2"), ("s_LT26", "o_LT14", "o_LT5", "prediction", 2, 2, 4, "2|3", "3|4","2", "3", "2", "3"), ("s_LT27", "o_LT13", "o_LT5", "prediction", 0, 2, 3, "2", "4", "3", "4", "2", "3"), ] # ── Auto-build SITUATIONS list ──────────────────────────────────────────────── SITUATIONS = [] for (sid, a, b, sit_set, norm_gr10, norm_gr8, norm_gr6, app_a_gr10, app_b_gr10, app_a_gr8, app_b_gr8, app_a_gr6, app_b_gr6) in _ALLOC_SITUATIONS + _LOTTERY_SITUATIONS: SITUATIONS.append({ "situation_id": sid, "option_A": a, "option_B": b, "set": sit_set, "norm_chosen_A_gr10": norm_gr10, "norm_chosen_A_gr8": norm_gr8, "norm_chosen_A_gr6": norm_gr6, "modal_app_a_gr10": app_a_gr10, "modal_app_b_gr10": app_b_gr10, "modal_app_a_gr8": app_a_gr8, "modal_app_b_gr8": app_b_gr8, "modal_app_a_gr6": app_a_gr6, "modal_app_b_gr6": app_b_gr6, }) SITUATION_NORMS = { s["situation_id"]: { "norm_chosen_A_gr10": s["norm_chosen_A_gr10"], "norm_chosen_A_gr8": s["norm_chosen_A_gr8"], "norm_chosen_A_gr6": s["norm_chosen_A_gr6"], } for s in SITUATIONS } SITUATION_APP_MODES = { s["situation_id"]: { "modal_app_a_gr10": s["modal_app_a_gr10"], "modal_app_b_gr10": s["modal_app_b_gr10"], "modal_app_a_gr8": s["modal_app_a_gr8"], "modal_app_b_gr8": s["modal_app_b_gr8"], "modal_app_a_gr6": s["modal_app_a_gr6"], "modal_app_b_gr6": s["modal_app_b_gr6"], } for s in SITUATIONS } # ============================================================================= # Helper: build the JSON-serialisable situation list for a participant # ============================================================================= def get_situations_for_participant(situation_ids=None, randomise_sides=True, randomise_order=True): """ Return a list of situation dicts ready to be JSON-serialised and passed to the frontend. Parameters ---------- situation_ids : list[str] | None Which situations to include (by situation_id string). None = all. randomise_sides : bool If True, randomly decide which option (A or B) appears on the left. randomise_order : bool If True, shuffle the presentation order of situations. Returns ------- list[dict] – each dict has keys: id, left, right, a_is_left """ base = SITUATIONS if situation_ids is None else [ s for s in SITUATIONS if s["situation_id"] in situation_ids ] result = [] for sit in base: opt_a = dict(OPTIONS[sit["option_A"]]) opt_b = dict(OPTIONS[sit["option_B"]]) a_is_left = True if randomise_sides and random.random() < 0.5: a_is_left = False result.append({ "id": sit["situation_id"], "left": opt_a if a_is_left else opt_b, "right": opt_b if a_is_left else opt_a, "a_is_left": a_is_left }) if randomise_order: random.shuffle(result) return result # ── Separate ID lists ───────────────────────────────────────────────────────── DG_SITUATION_IDS = [sid for (sid, _, _, _, *__) in _ALLOC_SITUATIONS] LT_SITUATION_IDS = [sid for (sid, _, _, _, *__) in _LOTTERY_SITUATIONS] DG_THRESHOLD_IDS = [sid for (sid, _, _, s, *__) in _ALLOC_SITUATIONS if s == "threshold"] DG_PREDICTION_IDS = [sid for (sid, _, _, s, *__) in _ALLOC_SITUATIONS if s == "prediction"] LT_THRESHOLD_IDS = [sid for (sid, _, _, s, *__) in _LOTTERY_SITUATIONS if s == "threshold"] LT_PREDICTION_IDS = [sid for (sid, _, _, s, *__) in _LOTTERY_SITUATIONS if s == "prediction"]