from otree.api import * author = 'Thomas' class C(BaseConstants): NAME_IN_URL = 'Questionaire_Pre' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): session = subsession.session if 'quota_counts' not in session.vars: session.vars['quota_counts'] = { # Bundesland 'land_1': 0, # Baden-Württemberg 'land_2': 0, # Bayern 'land_3': 0, # Berlin 'land_4': 0, # Brandenburg 'land_5': 0, # Bremen 'land_6': 0, # Hamburg 'land_7': 0, # Hessen 'land_8': 0, # Mecklenburg-Vorpommern 'land_9': 0, # Niedersachsen 'land_10': 0, # Nordrhein-Westfalen 'land_11': 0, # Rheinland-Pfalz 'land_12': 0, # Saarland 'land_13': 0, # Sachsen 'land_14': 0, # Sachsen-Anhalt 'land_15': 0, # Schleswig-Holstein 'land_16': 0, # Thüringen # School 'school_0': 0, # No schooling 'school_1': 0, # Elementary school 'school_2': 0, # Secondary school 'school_3': 0, # Technical college entrance qualification 'school_4': 0, # High school diploma 'school_student': 0, # Student # Age 'age_18_29': 0, 'age_30_39': 0, 'age_40_49': 0, 'age_50_59': 0, 'age_60_69': 0, # Gender 'male': 0, 'female': 0, 'divers': 0, 'noanswer': 0, } if 'quota_limits' not in session.vars: session.vars['quota_limits'] = { # Bundesland 'land_1': 3, 'land_2': 3, 'land_3': 3, 'land_4': 3, 'land_5': 3, 'land_6': 3, 'land_7': 3, 'land_8': 3, 'land_9': 3, 'land_10': 3, 'land_11': 3, 'land_12': 3, 'land_13': 3, 'land_14': 3, 'land_15': 3, 'land_16': 3, # School 'school_0': 3, 'school_student': 3, 'school_1': 3, 'school_2': 3, 'school_3': 3, 'school_4': 3, # Age 'age_18_29': 3, 'age_30_39': 3, 'age_40_49': 3, 'age_50_59': 3, 'age_60_69': 3, # Gender 'male': 10, 'female': 10, # allow some - not in quota 'divers': 2, 'noanswer': 2, } class Group(BaseGroup): pass class Player(BasePlayer): dem_age = models.IntegerField(label="", blank=False, choices=[ (i, str(i)) for i in range(17, 72)]) dem_gender = models.IntegerField(label=" ", blank=False, choices=[ [1, 'männlich'], [2, 'weiblich'], [3, 'divers'], [99, 'Möchte ich nicht sagen'] ]) dem_school = models.IntegerField(label="Welchen höchsten allgemeinbildenden Schulabschluss haben Sie?", blank=False, choices=[ [0, 'Abschluss nach höchstens 7 Jahren Schulbesuch'], [1, 'Hauptschulabschluss / Volksschulabschluss'], [2, 'Realschulabschluss / Mittlere Reife / Polytechnische Oberschule'], [3, 'Fachhochschulreife'], [4, 'Abitur (allgemeine oder fachgebundene Hochschulreife)'], [5, 'Ich bin zur Zeit Schüler:in'] ]) dem_land = models.IntegerField(label="In welchem Bundesland leben Sie?", blank=False, choices=[ [1, 'Baden-Württemberg'], [2, 'Bayern'], [3, 'Berlin'], [4, 'Brandenburg'], [5, 'Bremen'], [6, 'Hamburg'], [7, 'Hessen'], [8, 'Mecklenburg-Vorpommern'], [9, 'Niedersachsen'], [10, 'Nordrhein-Westfalen'], [11, 'Rheinland-Pfalz'], [12, 'Saarland'], [13, 'Sachsen'], [14, 'Sachsen-Anhalt'], [15, 'Schleswig-Holstein'], [16, 'Thüringen'] ]) #FUNCTIONS def get_age_quota_key(age): if 18 <= age <= 29: return 'age_18_29' elif 30 <= age <= 39: return 'age_30_39' elif 40 <= age <= 49: return 'age_40_49' elif 50 <= age <= 59: return 'age_50_59' elif 60 <= age <= 69: return 'age_60_69' return None def get_gender_quota_key(gender): if gender == 1: return 'male' elif gender == 2: return 'female' elif gender == 3: return 'divers' elif gender == 99: return 'noanswer' return None def get_school_quota_key(school): if school == 0: return 'school_0' elif school == 1: return 'school_1' elif school == 2: return 'school_2' elif school == 3: return 'school_3' elif school == 4: return 'school_4' elif school == 5: return 'school_student' return None def get_land_quota_key(land): if land in range(1, 17): return f'land_{land}' return None def get_all_quota_keys(participant): """ Returns all quota buckets the participant belongs to. If one category is outside the quota frame, return None. """ age_key = get_age_quota_key(participant.dem_age) gender_key = get_gender_quota_key(participant.dem_gender) school_key = get_school_quota_key(participant.dem_school) land_key = get_land_quota_key(participant.dem_land) if None in [age_key, gender_key, school_key, land_key]: return None return [land_key, school_key, age_key, gender_key] def quota_is_full(player: Player): participant = player.participant keys = get_all_quota_keys(participant) # outside quota frame -> screen out if keys is None: return True counts = player.session.vars['quota_counts'] limits = player.session.vars['quota_limits'] for key in keys: if counts[key] >= limits[key]: return True return False #PAGES class Pre_Que1(Page): form_model = 'player' form_fields = ['dem_age', 'dem_gender', 'dem_school', 'dem_land'] def is_displayed(player): return player.participant.vars.get('survey_participate') == 1 @staticmethod def before_next_page(player, timeout_happened): # Save demographics at participant level so later apps can access them player.participant.dem_age = player.dem_age player.participant.dem_gender = player.dem_gender player.participant.dem_school = player.dem_school player.participant.dem_land = player.dem_land player.participant.quota_screened_out = quota_is_full(player) @staticmethod def app_after_this_page(player, upcoming_apps): if player.participant.quota_screened_out: return 'Screenout' page_sequence = [ Pre_Que1 ]