Source code for psynet.demography.general

from psynet.modular_page import (
    DropdownControl,
    ModularPage,
    NumberControl,
    PushButtonControl,
    RadioButtonControl,
    TextControl,
)
from psynet.timeline import FailedValidation, Module, conditional, join
from psynet.utils import (
    get_country_dict,
    get_language_dict,
    get_locale,
    get_logger,
    get_translator,
)

logger = get_logger()


[docs] class BasicDemography(Module): def __init__( self, label="basic_demography", ): self.label = label self.elts = join( Gender(), Age(), CountryOfBirth(), CountryOfResidence(), FormalEducation(), ) super().__init__(self.label, self.elts)
[docs] class Language(Module): def __init__( self, label="language", ): self.label = label self.elts = join( MotherTongue(), MoreThanOneLanguage(), conditional( "more_than_one_language", lambda experiment, participant: participant.answer == "yes", LanguagesInOrderOfProficiency(), ), ) super().__init__(self.label, self.elts)
[docs] class BasicMusic(Module): def __init__( self, label="basic_music", ): self.label = label self.elts = join( YearsOfFormalTraining(), HoursOfDailyMusicListening(), MoneyFromPlayingMusic(), ) super().__init__(self.label, self.elts)
[docs] class Dance(Module): def __init__( self, label="dance", ): self.label = label self.elts = join( DanceSociallyOrProfessionally(), conditional( "dance_socially_or_professionally", lambda experiment, participant: ( participant.answer in ["socially", "professionally"] ), LastTimeDanced(), ), ) super().__init__(self.label, self.elts)
[docs] class SpeechDisorders(Module): def __init__( self, label="speech_disorders", ): self.label = label self.elts = join( SpeechLanguageTherapy(), DiagnosedWithDyslexia(), ) super().__init__(self.label, self.elts)
[docs] class Income(Module): def __init__( self, label="income", ): self.label = label self.elts = join( HouseholdIncomePerYear(), ) super().__init__(self.label, self.elts)
[docs] class ExperimentFeedback(Module): def __init__( self, label="feedback", ): self.label = label self.elts = join( LikedExperiment(), FoundExperimentDifficult(), EncounteredTechnicalProblems(), ) super().__init__(self.label, self.elts)
# Basic demography # class Gender(ModularPage): def __init__( self, label="gender", ): _p = get_translator(context=True) prompt = _p("gender", "How do you identify yourself?") self.label = label self.prompt = prompt self.time_estimate = 5 control = RadioButtonControl( ["female", "male", "non_binary", "not_specified", "prefer_not_to_say"], [ _p("gender", "Female"), _p("gender", "Male"), _p("gender", "Non-binary"), _p("gender", "Not specified"), _p("gender", "I prefer not to answer"), ], name="gender", show_free_text_option=True, placeholder_text_free_text=_p("gender", "Specify yourself"), ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) class Age(ModularPage): def __init__( self, label="age", ): _p = get_translator(context=True) self.label = label self.prompt = _p("age", "What is your age?") self.time_estimate = 5 super().__init__( self.label, self.prompt, control=NumberControl(), time_estimate=self.time_estimate, save_answer=label, ) def validate(self, response, **kwargs): _p = get_translator(context=True) answer = response.answer error_msg = ( _p("age", "You need to provide your age as an integer between 0 and 120!") + " " + _p("age", "Your answer was: '{AGE}'").format(AGE=answer) ) try: age = int(answer) if not (0 < age < 120): return FailedValidation(error_msg) else: return None except ValueError: return FailedValidation(error_msg) class CountryDropdown(ModularPage): def __init__(self, label): self.label = label _p = get_translator(context=True) self.time_estimate = 5 locale = get_locale() country_dict = get_country_dict(locale) control = DropdownControl( choices=list(country_dict.keys()) + ["OTHER"], labels=list(country_dict.values()) + [_p("country-select", "Other country")], default_text=_p("country-select", "Select a country"), name=self.label, ) super().__init__( self.label, self.get_prompt(), control=control, time_estimate=self.time_estimate, save_answer="country", ) def get_prompt(self): raise NotImplementedError() def validate(self, response, **kwargs): _p = get_translator(context=True) if self.control.force_selection and response.answer == "": return FailedValidation( _p("country-select", "You need to select a country!") ) return None class CountryOfBirth(CountryDropdown): def __init__( self, label="country_of_birth", ): super().__init__(label) def get_prompt(self): _p = get_translator(context=True) return _p("country-select", "What country are you from?") class CountryOfResidence(CountryDropdown): def __init__( self, label="country_of_residence", ): super().__init__(label) def get_prompt(self): _p = get_translator(context=True) return _p("country-select", "What is your current country of residence?") class FormalEducation(ModularPage): def __init__( self, label="formal_education", ): _p = get_translator(context=True) self.label = label self.prompt = _p( "formal-education", "What is your highest level of formal education?" ) self.time_estimate = 5 control = RadioButtonControl( [ "none", "high_school", "college", "graduate_school", "postgraduate_degree_or_higher", ], [ _p("formal-education", "None"), _p("formal-education", "High school"), _p("formal-education", "College"), _p("formal-education", "Graduate School"), _p("formal-education", "Postgraduate degree or higher"), ], name="formal_education", ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) # Language # class MotherTongue(ModularPage): def __init__( self, label="mother_tongue", # TODO Change back to plural (add "(s)") once multi-select is implemented. ): _p = get_translator(context=True) self.label = label self.prompt = _p( "language-select", "What is your mother tongue - i.e., the language which you have grown up speaking from early childhood?", ) self.time_estimate = 5 locale = get_locale() language_dict = get_language_dict(locale) control = DropdownControl( choices=list(language_dict.keys()) + ["other"], labels=list(language_dict.values()) + ["Other language"], default_text=_p("language-select", "Select a language"), name=self.label, ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) def validate(self, response, **kwargs): _p = get_translator(context=True) if self.control.force_selection and response.answer == "": return FailedValidation( _p("language-select", "You need to select a language!") ) return None class MoreThanOneLanguage(ModularPage): def __init__( self, label="more_than_one_language", ): _ = get_translator() _p = get_translator(context=True) self.label = label self.prompt = _p("language-select", "Do you speak more than one language?") self.time_estimate = 5 control = PushButtonControl( choices=["yes", "no"], labels=[_("Yes"), _("No")], arrange_vertically=False, ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) class LanguagesInOrderOfProficiency(ModularPage): def __init__( self, label="languages_in_order_of_proficiency", ): _p = get_translator(context=True) self.label = label self.prompt = _p( "language-select", "Please list the languages you speak in order of proficiency (first language first, second language second, ...)", ) self.time_estimate = 5 super().__init__( self.label, self.prompt, control=TextControl(), time_estimate=self.time_estimate, save_answer=label, ) def validate(self, response, **kwargs): _p = get_translator(context=True) if not response.answer != "": return FailedValidation( _p("language-select", "Please list at least one language!") ) return None # Basic music # class YearsOfFormalTraining(ModularPage): def __init__( self, label="years_of_formal_training", ): _p = get_translator(context=True) self.label = label self.prompt = _p( "music", "How many years of formal training on a musical instrument (including voice) have you had during your lifetime?", ) self.time_estimate = 5 super().__init__( self.label, self.prompt, control=NumberControl(), time_estimate=self.time_estimate, save_answer=label, ) class HoursOfDailyMusicListening(ModularPage): def __init__( self, label="hours_of_daily_music_listening", ): _p = get_translator(context=True) self.label = label self.prompt = _p( "music", "On average, how many hours do you listen to music daily?" ) self.time_estimate = 5 super().__init__( self.label, self.prompt, control=NumberControl(), time_estimate=self.time_estimate, save_answer=label, ) class MoneyFromPlayingMusic(ModularPage): def __init__( self, label="money_from_playing_music", ): _p = get_translator(context=True) self.label = label self.prompt = _p("music", "Do you make money from playing music?") self.time_estimate = 5 control = RadioButtonControl( ["frequently", "sometimes", "never"], [_p("music", "Frequently"), _p("music", "Sometimes"), _p("music", "Never")], name="money_from_playing_music", ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) # Hearing loss #
[docs] class HearingLoss(ModularPage): def __init__( self, label="hearing_loss", ): _ = get_translator() _p = get_translator(context=True) self.label = label self.prompt = _p( "music", "Do you have hearing loss or any other hearing issues?" ) self.time_estimate = 5 control = PushButtonControl( choices=["yes", "no"], labels=[_("Yes"), _("No")], arrange_vertically=False, ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, )
# Dance # class DanceSociallyOrProfessionally(ModularPage): def __init__( self, label="dance_socially_or_professionally", ): _p = get_translator(context=True) self.label = label self.prompt = _p("dance", "Do you dance socially or professionally?") self.time_estimate = 5 control = RadioButtonControl( ["socially", "professionally", "never_dance"], [ _p("dance", "Socially"), _p("dance", "Professionally"), _p("dance", "I never dance"), ], name="dance_socially_or_professionally", ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) class LastTimeDanced(ModularPage): def __init__( self, label="last_time_danced", ): _p = get_translator(context=True) self.label = label self.prompt = _p( "dance", "When was the last time you danced? (choose the most accurate answer):", ) self.time_estimate = 5 control = RadioButtonControl( [ "this_week", "this_month", "this_year", "some_years_ago", "many_years_ago", "never_danced", ], [ _p("dance", "This week"), _p("dance", "This month"), _p("dance", "This year"), _p("dance", "Some years ago"), _p("dance", "Many years ago"), _p("dance", "I never danced"), ], name="last_time_danced", ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) # Speech disorders # class SpeechLanguageTherapy(ModularPage): def __init__( self, label="speech_language_therapy", ): _ = get_translator() _p = get_translator(context=True) self.label = label self.prompt = _p( "speech-disorder", "Did you get speech-language therapy as a child?" ) self.time_estimate = 5 control = PushButtonControl( choices=["yes", "no", "dont_know"], labels=[_("Yes"), _("No"), _("I don’t know")], arrange_vertically=False, ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) class DiagnosedWithDyslexia(ModularPage): def __init__( self, label="diagnosed_with_dyslexia", ): _ = get_translator() _p = get_translator(context=True) self.label = label self.prompt = _p( "speech-disorder", "Have you ever been diagnosed with dyslexia?" ) self.time_estimate = 5 control = PushButtonControl( choices=["yes", "no", "dont_know"], labels=[_("Yes"), _("No"), _("I don’t know")], arrange_vertically=False, ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) # Income # class HouseholdIncomePerYear(ModularPage): def __init__( self, label="household_income_per_year", currency="USD", ): _p = get_translator(context=True) self.label = label self.prompt = _p("income", "What is your total household income per year?") self.time_estimate = 5 control = RadioButtonControl( [ "ĺess_than_10000", "10000_to_19999", "20000_to_29999", "30000_to_39999", "40000_to_49999", "50000_to_59999", "60000_to_69999", "70000_to_79999", "80000_to_89999", "90000_to_99999", "100000_to_149999", "150000_or_more", ], [ _p("income", "Less than 10,000 {CURRENCY}").format(CURRENCY=currency), _p("income", "10,000 to 19,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "20,000 to 29,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "30,000 to 39,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "40,000 to 49,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "50,000 to 59,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "60,000 to 69,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "70,000 to 79,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "80,000 to 89,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "90,000 to 99,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "100,000 to 149,999 {CURRENCY}").format(CURRENCY=currency), _p("income", "150,000 {CURRENCY} or more").format(CURRENCY=currency), ], name="household_income_per_year", ) super().__init__( self.label, self.prompt, control=control, time_estimate=self.time_estimate, save_answer=label, ) # ExperimentFeedback # class LikedExperiment(ModularPage): def __init__( self, label="liked_experiment", ): _p = get_translator(context=True) self.label = label self.prompt = _p("experiment-feedback", "Did you like the experiment?") self.time_estimate = 5 super().__init__( self.label, self.prompt, control=TextControl( bot_response=lambda: "I'm a bot so I don't really have feelings..." ), time_estimate=self.time_estimate, save_answer=label, ) class FoundExperimentDifficult(ModularPage): def __init__( self, label="find_experiment_difficult", ): _p = get_translator(context=True) self.label = label self.prompt = _p( "experiment-feedback", "Did you find the experiment difficult?" ) self.time_estimate = 5 super().__init__( self.label, self.prompt, control=TextControl(), time_estimate=self.time_estimate, bot_response=lambda: "I'm a bot so I found it pretty easy...", save_answer=label, ) class EncounteredTechnicalProblems(ModularPage): def __init__( self, label="encountered_technical_problems", ): _p = get_translator(context=True) self.label = label self.prompt = ( _p( "experiment-feedback", "Did you encounter any technical problems during the experiment?", ) + " " + _p( "experiment-feedback", "If so, please provide a few words describing the problem.", ) ) self.time_estimate = 5 super().__init__( self.label, self.prompt, control=TextControl(), time_estimate=self.time_estimate, bot_response=lambda: "No technical problems.", save_answer=label, )