from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) from otreeutils.surveys import create_player_model_for_survey, generate_likert_field, generate_likert_table author = 'Huanren Zhang' doc = """ Survey questions """ class Constants(BaseConstants): name_in_url = 'survey_questions' players_per_group = None num_rounds = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass # some pre-defined choices GENDER_CHOICES = ( ('female', 'Female'), ('male', 'Male'), ('no_answer', 'Prefer not to answer'), ) YESNO_CHOICES = ( ('yes', 'Yes'), ('no', 'No'), ) likert_7_labels = ( 'Strongly Disagree', 'Moderately Disagree', 'Slightly Disagree', 'Neutral', 'Slightly Agree', 'Moderately Agree', 'Strongly Agree' ) likert_7point_field = generate_likert_field(likert_7_labels) # define survey questions per page # for each page define a page title and a list of questions # the questions have a field name, a question text (input label), and a field type (model field class) SURVEY_DEFINITIONS = ( { 'page_title': 'Survey Questions', 'survey_fields': [ ('age', { # field name (which will also end up in your "Player" class and hence in your output data) 'text': 'What is your age?', # survey question 'field': models.PositiveIntegerField(min=15, max=100), # the same as in normal oTree model field definitions }), ('gender', { 'text': 'What is your gender?', 'field': models.CharField(widget=widgets.RadioSelect, choices=GENDER_CHOICES), }), ] }, { 'page_title': 'Survey Questions', 'survey_fields': [ generate_likert_table(('1', '2', '3', '4', '5', '6', '7', '8', '9', '10'), [('happiness', '')], form_help_initial='

On a scale of 1 to 10, how happy are you with your life?

', # HTML to be placed on top of form form_help_final='

', # HTML to be placed below form table_row_header_width_pct=0, ), ] }, { # 'page_title': 'Please finish the following questions.', 'page_title': '', 'survey_fields': [ # create a table of Likert scale choices # we use the same 5-point scale a before and specify four rows for the table, # each with a tuple (field name, label) generate_likert_table(likert_7_labels, [ ('cfc1', 'When I make a decision, I think about how it might affect me in the future.'), ('cfc2', 'I am willing to give up something that is beneficial today in order to benefit more from that in the future.'), ('ambiguity1', 'There is a right way and a wrong way to do almost everything.'), ('ambiguity2', 'Practically every problem has a solution.'), ('trust', 'I assume that people have only the best intentions.'), ('nr2', 'I am willing to punish someone who treats others unfairly, even if there may be costs.'), ('risk', ' I am willing to take risks.'), ('competition', 'I like to compete with others.'), ('math', ' I am good at math.'), ], form_help_initial='

Below are a number of descriptions that may or may not apply to you. ' + 'Please indicate the extent to which you agree or disagree with that statement ' + 'on a scale of 1 (strongly disagree) to 7 (strongly agree).

', # HTML to be placed on top of form form_help_final='

', # HTML to be placed below form table_row_header_width_pct=50, # width of row header (first column) in percent. default: 25 table_rows_randomize=True, # randomize order of displayed rows ), ] }, { 'page_title': '', 'survey_fields': [ # create a table of Likert scale choices # we use the same 5-point scale a before and specify four rows for the table, # each with a tuple (field name, label) generate_likert_table(likert_7_labels, [ ('pr', 'When someone does me a favor I am willing to return it.'), ('nr1', ' If I am treated very unjustly, I will take revenge at the first occasion, even if there is a cost to do so.'), ('ambiguity4', 'I find it hard to make a choice when the outcome is uncertain.'), ('ambiguity3', 'I feel relieved when an ambiguous situation suddenly becomes clear.'), ('altruism', 'I am willing to give to good causes without expecting anything in return.'), ('fne', 'I am concerned with what other people think of me.'), ('friend', 'I have relatives or friends that I can count on to help whenver needed.'), ('smarter', 'Generally speaking, I am smarter than an average person.'), ('cfc3', 'I only act to satisfy immediate concerns, figuring that I will take care of future problems that may occur at a later date.'), ], form_help_initial='

Below are a number of descriptions that may or may not apply to you. ' + 'Please indicate the extent to which you agree or disagree with that statement ' + 'on a scale of 1 (strongly disagree) to 7 (strongly agree).

', # HTML to be placed on top of form form_help_final='

', # HTML to be placed below form table_row_header_width_pct=50, # width of row header (first column) in percent. default: 25 table_rows_randomize=True, # randomize order of displayed rows ), ] }, ) # now dynamically create the Player class from the survey definitions # we can also pass additional (non-survey) fields via `other_fields` Player = create_player_model_for_survey('survey_questions.models', SURVEY_DEFINITIONS, other_fields={ })