from otree.api import * class C(BaseConstants): NAME_IN_URL = 'post_questionaire' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 # HEXACO and TL Options LIKERT_5 = [ [1, 'Strongly Disagree'], [2, 'Disagree'], [3, 'Neutral'], [4, 'Agree'], [5, 'Strongly Agree'] ] LIKERT_6 = [ [1, 'Strongly Disagree'], [2, 'Disagree'], [3, 'Slightly Disagree'], [4, 'Slightly Agree'], [5, 'Agree'], [6, 'Strongly Agree'] ] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): demo_duration = models.FloatField() hexa_duration = models.FloatField() tightness_duration = models.FloatField() # Demographics age = models.IntegerField(label="How old are you?", min=18, max=100, error_messages={'required': 'Please state your age.'}) gender = models.StringField( label="What is your gender?", choices=['Male', 'Female', 'Non-binary', 'Other', 'Prefer not to say'], widget=widgets.RadioSelect ) residence = models.StringField(label="What is your country of residence?") # Racial/Ethnic Group (Boolean fields for multi-select) race_white = models.BooleanField( label="White", widget=widgets.CheckboxInput, initial=False, blank=True ) race_mena = models.BooleanField( label="Middle Eastern or North African", widget=widgets.CheckboxInput, initial=False, blank=True ) race_hispanic = models.BooleanField( label="Hispanic or Latino", widget=widgets.CheckboxInput, initial=False, blank=True ) race_black = models.BooleanField( label="Black", widget=widgets.CheckboxInput, initial=False, blank=True ) race_asian = models.BooleanField( label="Asian", widget=widgets.CheckboxInput, initial=False, blank=True ) race_indigenous_nordic = models.BooleanField( label="Indigenous – Nordic countries (e.g., Greenlandic, Sámi)", widget=widgets.CheckboxInput, initial=False, blank=True ) race_indigenous_other = models.BooleanField( label="Indigenous - other (e.g., American Indian, Alaska Native, Native Hawaiian, Pacific Islander)", widget=widgets.CheckboxInput, initial=False, blank=True ) income = models.StringField( label="Gross monthly income in USD:", choices=[ 'Less than $25,000', '$25,000-$35,000', '$35,001-$50,000', '$50,001-$75,000', '$75,001-$100,000', '$100,001-$150,000', '$150,001-$250,000', 'More than $250,000' ], widget=widgets.RadioSelect ) politics = models.IntegerField( label='Where would you place yourself on a "left" (0) to "right" (10) scale?', choices=list(range(11)), widget=widgets.RadioSelectHorizontal ) # HEXACO (24 items) hexaco_1 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I can look at a painting for a long time.") hexaco_2 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I make sure that things are in the right spot.") hexaco_3 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I remain unfriendly to someone who was mean to me.") hexaco_4 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="Nobody likes talking with me.") hexaco_5 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I am afraid of feeling pain.") hexaco_6 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I find it difficult to lie.") hexaco_7 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I think science is boring.") hexaco_8 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I postpone complicated tasks as long as possible.") hexaco_9 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I often express criticism.") hexaco_10 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I easily approach strangers.") hexaco_11 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I worry less than others.") hexaco_12 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I would like to know how to make lots of money in a dishonest manner.") hexaco_13 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I have a lot of imagination.") hexaco_14 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I work very precisely.") hexaco_15 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I tend to quickly agree with others.") hexaco_16 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I like to talk with others.") hexaco_17 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I can easily overcome difficulties on my own.") hexaco_18 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I want to be famous.") hexaco_19 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I like people with strange ideas.") hexaco_20 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I often do things without really thinking.") hexaco_21 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="Even when I'm treated badly, I remain calm.") hexaco_22 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I am seldom cheerful.") hexaco_23 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I have to cry during sad or romantic movies.") hexaco_24 = models.IntegerField(choices=C.LIKERT_5, widget=widgets.RadioSelect, label="I am entitled to special treatment.") # Tightness-Looseness (6 items) tl_1 = models.IntegerField(choices=C.LIKERT_6, widget=widgets.RadioSelect, label="There are many social norms that people are supposed to abide by in this country.") tl_2 = models.IntegerField(choices=C.LIKERT_6, widget=widgets.RadioSelect, label="In this country, there are very clear expectations for how people should act in most situations.") tl_3 = models.IntegerField(choices=C.LIKERT_6, widget=widgets.RadioSelect, label="People agree upon what behaviors are appropriate versus inappropriate in most situations this country.") tl_ac = models.IntegerField(choices=C.LIKERT_6, widget=widgets.RadioSelect, label="If you are reading this, select strongly Disagree.") tl_4 = models.IntegerField(choices=C.LIKERT_6, widget=widgets.RadioSelect, label="People in this country have a great deal of freedom in deciding how they want to behave in most situations.") tl_5 = models.IntegerField(choices=C.LIKERT_6, widget=widgets.RadioSelect, label="In this country, if someone acts in an inappropriate way, others will strongly disapprove.") tl_6 = models.IntegerField(choices=C.LIKERT_6, widget=widgets.RadioSelect, label="People in this country almost always comply with social norms.") # PAGES class Demographics(Page): form_model = 'player' form_fields = [ 'age', 'gender', 'residence', 'race_white', 'race_mena', 'race_hispanic', 'race_black', 'race_asian', 'race_indigenous_nordic', 'race_indigenous_other', 'income', 'politics' ] @staticmethod def error_message(player, values): # List all the race boolean fields race_fields = [ values['race_white'], values['race_mena'], values['race_hispanic'], values['race_black'], values['race_asian'], values['race_indigenous_nordic'], values['race_indigenous_other'] ] # If none of them are True (checked), return an error message if not any(race_fields): return "Please select at least one racial/ethnic group to continue." @staticmethod def before_next_page(player: Player, timeout_happened): import time # participant._last_page_timestamp ist ein interner oTree-Wert start_time = player.participant._last_page_timestamp if start_time: player.demo_duration = time.time() - start_time class Hexaco(Page): form_model = 'player' def get_form_fields(player): return [f'hexaco_{i}' for i in range(1, 25)] @staticmethod def before_next_page(player: Player, timeout_happened): import time # participant._last_page_timestamp ist ein interner oTree-Wert start_time = player.participant._last_page_timestamp if start_time: player.hexa_duration = time.time() - start_time class Tightness_loosness_scale(Page): form_model = 'player' def get_form_fields(player): return [f'tl_{i}' for i in range(1, 4)]+ ["tl_ac"] + [f'tl_{i}' for i in range(4, 7)] @staticmethod def before_next_page(player: Player, timeout_happened): import time # participant._last_page_timestamp ist ein interner oTree-Wert start_time = player.participant._last_page_timestamp if start_time: player.tightness_duration = time.time() - start_time page_sequence = [Demographics, Hexaco, Tightness_loosness_scale]