from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'TheGameOfCovids' PLAYERS_PER_GROUP = None NUM_ROUNDS = 10 COLLECTIVE_IMMUNITY_THRESHOLD = 80 INITIAL_DEPOSIT = 500 VACC_COST = 125 LIGHT_FORM_CHARGE = 250 class Subsession(BaseSubsession): pass class Group(BaseGroup): total_active_players = models.IntegerField(min=0, max = 1000) total_vaccinated = models.IntegerField(min=0, max = 1000) alpha_vaccinated = models.FloatField(initial=0) beta_disease_probability = models.FloatField(initial=0) class Player(BasePlayer): name = models.StringField(label='Укажите Ваше имя и фамилию: ') sex = models.IntegerField( choices=[ [1, 'Мужской'], [2, 'Женский'], ], widget=widgets.RadioSelect, label="Укажите Ваш пол:" ) age = models.IntegerField(min=0, label='Введите Ваш возраст (полных лет):') marital_status = models.IntegerField( choices=[ [1, 'Женат/замужем'], [2, 'Не женат/не замужем'], ], widget=widgets.RadioSelect, label="Укажите Ваше семейное положение:" ) my_kids = models.IntegerField( choices=[ [0, 'Ни одного'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7'], [8, '8'], [9, '9'], [10, '10 и более'] ], widget=widgets.RadioSelectHorizontal, label="Сколько у Вас детей?" ) my_education = models.IntegerField( choices=[ [1, 'Неполное среднее'], [2, 'Среднее или среднее специальное'], [3, 'Студент бакалавриата или специалитета'], [4, 'Диплом бакалавра или специалиста'], [5, 'Студент магистратуры'], [6, 'Диплом магистра'], [7, 'Высшее со степенью кандидата или доктора наук'] ], widget=widgets.RadioSelectHorizontal, label="Ваше образование: " ) hum_or_tech = models.IntegerField( choices=[ [1, 'Ярко выраженный гуманитарий'], [2, 'Гуманитарий'], [3, 'Скорее гуманитарный склад ума'], [4, 'Нейтральное положение'], [5, 'Скорее технический склад ума'], [6, 'Технарь'], [7, 'Ярко выраженный технарь'] ], widget=widgets.RadioSelectHorizontal, label="Укажите Ваше представление о себе: " ) WF = models.IntegerField( choices=[ [1, 'Очень низкий'], [2, 'Низкий'], [3, 'Ниже среднего'], [4, 'Средний'], [5, 'Выше среднего'], [6, 'Высокий'], [7, 'Очень высокий'] ], widget=widgets.RadioSelectHorizontal, label="Укажите Ваше самоощущение от уровня доходов:" ) risk = models.IntegerField( choices=[ [1, 'Абсолютно не склонен к риску'], [2, 'Не склонен к риску'], [3, 'Скорее не склонен к риску'], [4, 'Нейтрален к риску'], [5, 'Скорее склонен к риску'], [6, 'Склонен к риску'], [7, 'Максимально склонен к риску'], ], widget = widgets.RadioSelectHorizontal, label="Оцените Ваше отношение к риску:" ) covid_before = models.IntegerField( choices=[ [1, 'Совсем отсутствовал'], [2, 'Ниже среднего'], [3, 'Средний'], [4, 'Выше среднего'], [5, 'Очень высокий'] ], widget=widgets.RadioSelectHorizontal, label="Оцените Ваш интерес к коронавирусу на момент начала пандемии: " ) covid_now = models.IntegerField( choices=[ [1, 'Совсем отсутствовал'], [2, 'Ниже среднего'], [3, 'Средний'], [4, 'Выше среднего'], [5, 'Очень высокий'] ], widget=widgets.RadioSelectHorizontal, label="Оцените Ваш интерес к коронавирусу в настоящее время: " ) wants_to_vaccinate = models.IntegerField( choices=[ [1, 'Я буду вакцинироваться'], [0, 'Я не буду вакцинироваться'], ], widget=widgets.RadioSelect, label="Готовы ли Вы сделать прививку?", initial=-1 ) covid_status = models.IntegerField( choices=[ [0, 'Здоров'], [1, 'Бессимптомно'], [2, 'Легкая форма'], [4, 'Тяжелая форма'] ], widget=widgets.RadioSelectHorizontal, label="Ваш ковид-статус:" ) vacc_danger = models.IntegerField( choices=[ [1, 'Нет, вообще никакого вреда'], [2, 'Серьезного вреда не нанесет'], [3, 'Может нанести средний урон'], [4, 'Возможный вред достаточно серьезен'], [5, 'Вакцина наносит тяжелый урон'], ], widget = widgets.RadioSelectHorizontal, label="По Вашему мнению вакцина может повредить вашему здоровью?" ) vax_lowers = models.IntegerField( choices=[ [1, 'Совсем не уменьшит'], [2, 'Уменьшит незначительно'], [3, 'В какой-то степени уменьшит'], [4, 'Ощутимо уменьшит'], [5, 'Вообще сведет к минимуму'], ], widget=widgets.RadioSelectHorizontal, label="Как Вы думаете, насколько вакцина уменьшит Вашу вероятность заболеть коронавирусом?" ) vax_eases = models.IntegerField( choices=[ [1, 'Совсем не облегчит'], [2, 'Облегчит незначительно'], [3, 'В какой-то степени облегчит'], [4, 'Ощутимо облегчит'], [5, 'Сделает течение болезни бессимптомным'], ], widget=widgets.RadioSelectHorizontal, label="Как Вы думаете, насколько вакцина облегчит Ваше состояние в случае заболевания?" ) my_immunity = models.IntegerField( choices=[ [1, 'плохой'], [2, 'ниже среднего'], [3, 'средний'], [4, 'выше среднего'], [5, 'высокий'], ], widget=widgets.RadioSelectHorizontal, label="Как Вы думаете, какой у Вас иммунитет?" ) my_real_vax = models.IntegerField( choices=[ [1, 'Нет и не собираюсь'], [2, 'Нет, но планирую когда-нибудь'], [3, 'Нет, но планирую в ближайшее время'], [4, 'Да'], [5, 'Да, и даже ревакцинацию'], ], widget=widgets.RadioSelectHorizontal, label="Сделали ли Вы прививку от коронавируса?" ) russian_vacc = models.IntegerField( choices=[ [1, 'Российские вакцины значительно хуже'], [2, 'Нет, но планирую когда-нибудь'], [3, 'Вакцины сопоставимы'], [4, 'Российские вакцины немного лучше'], [5, 'Российские вакцины значительно лучше'], ], widget=widgets.RadioSelectHorizontal, label="Как Вы оцениваете качество российских вакцин в сравнении с зарубежными аналогами?" ) your_environment = models.IntegerField( choices=[ [1, 'Совершенно неважный'], [2, 'Не очень важный'], [3, 'Относительно важный'], [4, 'Важный'], [5, 'Важнейший довод из всех'], ], widget=widgets.RadioSelectHorizontal, label="Считаете ли Вы важным доводом то, что Ваша вакцинация позволит избежать заболевания не только Вам, но и кому–то из вашего окружения?" ) your_disease = models.IntegerField( choices=[ [1, 'Точно нет'], [2, 'Скорее нет'], [3, 'Не знаю'], [4, 'Скорее да'], [5, 'Точно да'], ], widget=widgets.RadioSelectHorizontal, label="Болели ли Вы лично коронавирусом?" ) my_anticovid_attitude = models.IntegerField( choices=[ [1, 'категорически против'], [2, 'против'], [3, 'скорее против'], [4, 'нейтральное отношение'], [5, 'скорее за'], [6, 'за'], [7, 'категорически за'] ], widget=widgets.RadioSelectHorizontal, label="Как Вы относитесь к мерам, принуждающим к вакцинации – введению QR-кодов, ограничениям в работе или учебе и т.д?" ) my_thought_about_env = models.IntegerField( label="Оцените процент Ваших знакомых, которые переболели коронавирусом:" ) control_1 = models.IntegerField( label="Какова Ваша вероятность заболеть (в процентах), если из 10 участников эксперимента вакцинируются 6? " "Если возникают вопросы, обратитесь к организатору эксперимента." ) control_2 = models.IntegerField( label="Какова Ваша вероятность остаться здоровым (в процентах), если из 15 участников эксперимента вакцинируются" " 13? Если возникают вопросы, обратитесь к организатору эксперимента." ) control_3 = models.IntegerField( label="Каков Ваш выигрыш, если Вы вакцинировались и заболели в бессимптомной форме? Если возникают вопросы," "обратитесь к организатору эксперимента" ) control_4 = models.IntegerField( label="Если болеет 30% населения, а Вы не вакцинированы, то какова вероятность (в процентах), что болезнь будет " "протекать в тяжелой форме? Если возникают вопросы, обратитесь к организатору эксперимента" ) my_approx_percent = models.IntegerField( label="Какой процент участников данного эксперимента, на Ваш взгляд примет положительное решение о вакцинации? " ) def disease(self): import random my_group = self.group beta = my_group.beta_disease_probability my_random = random.randint(1, 100) self.payoff = C.INITIAL_DEPOSIT prev_self = self.in_round(1) self.vacc_danger = prev_self.vacc_danger self.vax_lowers = prev_self.vax_lowers self.vax_eases = prev_self.vax_eases self.my_immunity = prev_self.my_immunity if self.round_number < 6: if self.wants_to_vaccinate==1: #вакцинирован self.payoff = self.payoff - C.VACC_COST if my_random < 2*beta/3: self.covid_status = 1 elif (my_random>=2*beta/3) and (my_random=2*beta/3) and (my_random=beta*possibility(self.vax_lowers)) and (my_random=2*beta/3) and (my_random= C.COLLECTIVE_IMMUNITY_THRESHOLD, 'beta_probability': max(self.group.beta_disease_probability, 0), 'my_vax': my_vaxx_text, 'my_status': my_status_text, 'my_payoff': self.payoff } class JustWaitPage(WaitPage): pass class ResultsWaitPage(WaitPage): def after_all_players_arrive(group: Group): print('Все тут') group.total_active_players = 0 group.total_vaccinated = 0 for player in group.get_players(): if player.wants_to_vaccinate > -1: group.total_active_players = group.total_active_players + 1 if player.wants_to_vaccinate == 1: group.total_vaccinated = group.total_vaccinated + 1 print('Активных игроков:') print(group.total_active_players) print('Из них привились:') print(group.total_vaccinated) group.alpha_vaccinated = group.total_vaccinated/group.total_active_players if group.alpha_vaccinated >= C.COLLECTIVE_IMMUNITY_THRESHOLD: group.beta_disease_probability=0 else: group.beta_disease_probability=100*(1-100*group.alpha_vaccinated/C.COLLECTIVE_IMMUNITY_THRESHOLD) #А вот сейчас начнем симулировать, заболел ли каждый конкретный человек for player in group.get_players(): player.disease() def vars_for_template(self): return { 'subsession': self.subsession, 'group': self.group } class Introduction(Page): form_model = 'player' form_fields = ['name', 'age', 'sex', 'WF', 'my_kids', 'my_education', 'hum_or_tech', 'risk', 'covid_before', 'covid_now', 'vacc_danger', 'vax_lowers', 'vax_eases', 'my_immunity', 'my_real_vax', 'russian_vacc', 'your_environment', 'your_disease', 'my_anticovid_attitude', 'my_thought_about_env'] def is_displayed(player): return player.round_number == 1 def error_message(self, values): if (values['my_thought_about_env'] > 100) or (values['my_thought_about_env'] < 0): return 'Проценты измеряются от 0 до 100' def vars_for_template(self): return { 'subsession': self.subsession, 'group': self.group } class Selfreporting(Page): pass class Control1(Page): form_model = 'player' form_fields = ['control_1', 'control_2'] def error_message(self, values): if (values['control_1'] != 25): return 'Неверный ответ в вопросе 1' if (values['control_2'] != 100): return 'Неверный ответ в вопросе 2' def is_displayed(player): return player.round_number == 1 def vars_for_template(self): return { 'subsession': self.subsession, 'group': self.group, 'round_number': self.round_number, 'alpha_hat': C.COLLECTIVE_IMMUNITY_THRESHOLD } class Control2(Page): form_model = 'player' form_fields = ['control_3', 'control_4'] def error_message(self, values): if (values['control_3'] != 375): return 'Неверный ответ в вопросе 1' if (values['control_4'] != 10): return 'Неверный ответ в вопросе 2' def is_displayed(player): return player.round_number == 1 def vars_for_template(self): return { 'subsession': self.subsession, 'group': self.group, 'round_number': self.round_number, 'alpha_hat': C.COLLECTIVE_IMMUNITY_THRESHOLD } class Test(Page): form_model = 'player' form_fields = ['wants_to_vaccinate', 'my_approx_percent'] def vars_for_template(self): prev_self = self.in_round(1) self.vacc_danger = prev_self.vacc_danger self.vax_lowers = prev_self.vax_lowers self.vax_eases = prev_self.vax_eases self.my_immunity = prev_self.my_immunity if self.round_number < 6: deposit = 500 vacc_cost = 125 healthy_vacc_cost = 375 prob_modifier = 2/3 vac_light = 125 novac_medium = 250 novac_severe = 0 else: deposit = 500 vacc_cost = harm(self.vacc_danger) healthy_vacc_cost = 500 - harm(self.vacc_danger) prob_modifier = possibility(self.vax_lowers) vac_light = 500 - severeness(self.vax_eases) novac_medium = 150 + immunity(self.my_immunity) novac_severe = immunity(self.my_immunity) return { 'subsession': self.subsession, 'group': self.group, 'round_number': self.round_number, 'alpha_hat': C.COLLECTIVE_IMMUNITY_THRESHOLD, 'deposit': deposit, 'vacc_cost': vacc_cost, 'healthy_vacc_cost': healthy_vacc_cost, 'prob_modifier': prob_modifier, 'vac_light': vac_light, 'novac_medium': novac_medium, 'novac_severe': novac_severe, '1_prob_modifier': 1.0 - prob_modifier } @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.wants_to_vaccinate = -1 # FUNCTIONS def harm(belief): if belief == 1: return 50 elif belief == 2: return 100 elif belief == 3: return 125 elif belief == 4: return 150 elif belief == 5: return 200 def possibility(belief): if belief == 1: return 0 elif belief == 2: return 1.0/6 elif belief == 3: return 1.0/3 elif belief == 4: return 1.0/2 elif belief == 5: return 2.0/3 def severeness(belief): if belief == 1: return 300 elif belief == 2: return 275 elif belief == 3: return 250 elif belief == 4: return 225 elif belief == 5: return 200 def immunity(belief): if belief == 1: return 0 elif belief == 2: return 50 elif belief == 3: return 75 elif belief == 4: return 100 elif belief == 5: return 125 elif belief == 6: return 150 elif belief == 7: return 200 #def creating_session(subsession: Subsession): #import random #print('in creating_session', subsession.round_number) #for curr_group in subsession.get_groups(): # curr_group.real_endowment = random.randint(C.MIN_ENDOWMENT, C.MAX_ENDOWMENT) # print('real_endowment', curr_group.real_endowment) page_sequence = [Introduction, Control1, Control2, Test, ResultsWaitPage, Results] #