from otree.api import * c = cu doc = '\nThis is a standard 2-player trust game where the amount sent by player 1 gets\ntripled. The trust game was first proposed by\n\n Berg, Dickhaut, and McCabe (1995)\n.\n' class C(BaseConstants): NAME_IN_URL = 'trust' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 4 ENDOWMENT = cu(200) MULTIPLIER = 3 MY_CONSTANT = 0 ROLES = "'Sender', 'Receiver'" INSTRUCTIONS_TEMPLATE = 'trust/instructions.html' class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): session = subsession.session if subsession.round_number == 1 or subsession.round_number == 2: subsession.group_randomly(fixed_id_in_group=True) elif subsession.round_number == 3 or subsession.round_number == 4: for group in subsession.get_groups(): players = group.get_players() for player in players: if player.id_in_group == 1: player.id_in_group = 2 else: player.id_in_group = 1 subsession.group_randomly(fixed_id_in_group=True) class Group(BaseGroup): sent_amount = models.CurrencyField(doc='Amount sent by P1', label='Пожалуйста, укажите сумму от 0 до 200', max=C.ENDOWMENT, min=0) sent_back_amount = models.CurrencyField(doc='Amount sent back by P2', label='Сумма отправленная обратно', min=0) def sent_back_amount_max(group: Group): return group.sent_amount * C.MULTIPLIER def set_payoffs(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) p1.payoff = C.ENDOWMENT - group.sent_amount + group.sent_back_amount p2.payoff = group.sent_amount * C.MULTIPLIER - group.sent_back_amount class Player(BasePlayer): Name = models.StringField(label='Как вас зовут?') Age = models.IntegerField(label='Укажите ваш год рождения:') Gender = models.StringField(choices=[['Ж', 'Ж'], ['М', 'М']], label='Пол', widget=widgets.RadioSelectHorizontal) Region = models.StringField(label='В каком регионе вы родились? Если вы родились не в России, укажите страну') SpendRegion = models.StringField(label='В каком регионе вы провели большую часть детства? Если вы провели большую часть детства за пределами России, пожалуйста, укажите страну.') Specialization = models.StringField(choices=[['Специалист с высшим образованием, например, врач, учитель, инженер, художник, юрист.', 'Специалист с высшим образованием, например, врач, учитель, инженер, художник, юрист.'], ['Высокий менеджер, например, финансовый директор, исполнительный директор крупного предприятия, высокопоставленный менеджер в государственных органах и управлениях, местных органах власти или профсоюзах.', 'Старший менеджер, например, финансовый директор, исполнительный директор крупного предприятия, высокопоставленный'], ['Офисный работник, например, секретарь, офисный сотрудник, офис-менеджер, бухгалтер.', 'Офисный работник, например, секретарь, офисный сотрудник, офис-менеджер, бухгалтер.'], ['Работник в области торговли или продаж, например, менеджер по продажам, владелец магазина, продавец, агент по страхованию.', 'Работник в области торговли или продаж, например, менеджер по продажам, владелец магазина, продавец, агент по страхованию.'], ['Квалифицированный сотрудник в сфере обслуживания, например, полицейский, официант/бармен, парикмахер, военнослужащий без офицерского звания, медсестра.', 'Квалифицированный сотрудник в сфере обслуживания, например, полицейский, официант/бармен, парикмахер, военнослужащий без офицерского звания, медсестра.'], ['Высококвалифицированный работник или руководитель рабочей группы, например, мастер, старший мастер, автомеханик, сборщик, наборщик/печатник, слесарь-инструментальщик, электрик.', 'Высококвалифицированный работник или руководитель рабочей группы, например, мастер, старший мастер, автомеханик, сборщик, наборщик/печатник, слесарь-инструментальщик, электрик.'], ['• Рабочие средней квалификации, например, каменщик, водитель, плотник, кузнец, пекарь.', 'Рабочие средней квалификации, например, каменщик, водитель, плотник, кузнец, пекарь'], ['Неквалифицированные рабочие, например, грузчик, охранник.', 'Неквалифицированные рабочие, например, грузчик, охранник.'], ['Сельскохозяйственный работник, например, тракторист/комбайнер, рыбак, доярка.', 'Сельскохозяйственный работник, например, тракторист/комбайнер, рыбак, доярка.'], ['Фермер, управляющий фермой.', 'Фермер, управляющий фермой.'], ['-', '-']], label='В какой области вы специализируетесь? Если вы студент, укажите "-".') Major = models.StringField(choices=[['Экономика и управление', 'Экономика и управление'], ['Математические и естественные науки', 'Математические и естественные науки'], ['Инженерия, технологии и технические науки', 'Инженерия, технологии и технические науки'], ['Здравоохранение и медицинские науки', 'Здравоохранение и медицинские науки'], ['Образование и педагогические науки', 'Образование и педагогические науки'], ['Искусство и культура', 'Искусство и культура'], ['Социология, психология и философия', 'Социология, психология и философия'], ['Юриспруденция', 'Юриспруденция'], ['Политология и регионоведение', 'Политология и регионоведение'], ['Лингвистика и литературоведение', 'Лингвистика и литературоведение'], ['История и археология', 'История и археология'], ['Другие области', 'Другие области'], ['-', '-']], label='В какой области вы специализируетесь? Если вы работаете, укажите "-".') LevelofEducation = models.StringField(choices=[['Базовое общее образование (9 классов)', 'Базовое общее образование (9 классов)'], ['Среднее общее образование (11 классов)', 'Среднее общее образование (11 классов)'], ['Среднее профессиональное образование (техникум, колледж)', 'Среднее профессиональное образование (техникум, колледж)'], ['Высшее образование - бакалаврский диплом', 'Высшее образование - бакалаврский диплом'], ['Высшее образование - специалист, магистрский диплом', 'Высшее образование - специалист, магистрский диплом'], ['Высшее образование - кандидат наук, доктор наук', 'Высшее образование - кандидат наук, доктор наук']], label='Ваш самый высокий уровень образования (отметьте одну галочку):', widget=widgets.RadioSelect) Risk = models.StringField(choices=[['Мне нравится идти на риск.', 'Мне нравится идти на риск.'], ['Обычно я люблю идти на риск.', 'Обычно я люблю идти на риск.'], ['Нейтрально.', 'Нейтрально.'], ['Обычно я избегаю риска.', 'Обычно я избегаю риска.'], ['Я избегаю риска.', 'Я избегаю риска.']], label='Как вы относитесь к риску? (пожалуйста, выберите один вариант)', widget=widgets.RadioSelect) FinancialSituation = models.StringField(choices=[['1', '1'], ['2', '2'], ['3', '3'], ['4', '4'], ['5', '5'], ['6', '6'], ['7', '7'], ['8', '8'], ['9', '9'], ['10', '10']], label='Оцените ваше финансовое положение по шкале от 1 до 10, где 1 означает "У меня недостаточно денег для выживания", а 10 означает "Я могу позволить себе все свои расходы в любое время".', widget=widgets.RadioSelectHorizontal) SatisfiedLife = models.StringField(choices=[['1', '1'], ['2', '2'], ['3', '3'], ['4', '4'], ['5', '5'], ['6', '6'], ['7', '7'], ['8', '8'], ['9', '9'], ['10', '10']], label='В целом, насколько вы удовлетворены своей жизнью? Оцените по шкале от 1 до 10, где 1 – "совершенно недовольны", а 10 – "полностью удовлетворены".', widget=widgets.RadioSelectHorizontal) Trust = models.StringField(choices=[['1', '1'], ['2', '2'], ['3', '3'], ['4', '4'], ['5', '5'], ['6', '6'], ['7', '7'], ['8', '8'], ['9', '9'], ['10', '10']], label='В общем, вы считаете, что большинству людей можно доверять, или при общении с другими людьми всегда стоит проявлять осторожность? Оцените по шкале, где 1 означает "Нужно быть максимально осторожным в доверии другим людям", а 10 означает "Большинству людей можно полностью доверять".', widget=widgets.RadioSelectHorizontal) FreedomofChoice = models.StringField(choices=[['1', '1'], ['2', '2'], ['3', '3'], ['4', '4'], ['5', '5'], ['6', '6'], ['7', '7'], ['8', '8'], ['9', '9'], ['10', '10']], label='Некоторые люди верят, что они имеют полную свободу выбора и полный контроль над своей жизнью, в то время как другие люди верят, что их действия не имеют реального влияния на то, что происходит с ними. Оцените ваше мнение по шкале от 1 до 10, где 1 означает "У меня нет свободы выбора", а 10 означает "У меня полная свобода выбора".', widget=widgets.RadioSelectHorizontal) Feedback = models.LongStringField(label='Здесь вы можете оставить свои комментарии и поделиться впечатлениями о участии в эксперименте (если вы не хотите ничего писать, просто поставьте прочерк):') OtherName = models.StringField(label='Если вы родитель, укажите имя вашего ребенка. Если вы ребенок, укажите имя вашего родителя.') BankCard = models.StringField(label='Пожалуйста, укажите ваш банк и номер телефона (или номер карты), чтобы мы могли отправить сумму, которую вы заработали') def set_initial_role(player: Player): import random if player.round_number == 1: player.role = random.choice(['sender', 'receiver']) def before_next_round(player: Player): session = player.session subsession = player.subsession if subsession.round_number == 1: subsession.set_initial_role() elif subsession.round_number > 1: prev_role = subsession.in_round(subsession.round_number - 1).role if subsession.round_number == 2 or subsession.round_number == 4: subsession.role = prev_role elif subsession.round_number == 3: subsession.role = 'receiver' if prev_role == 'sender' else 'sender' def custom_export(players): yield ['participant_code', 'id_in_group'] for p in players: pp = p.participant yield [pp.code, p.id_in_group] class Introduction(Page): form_model = 'player' class MyWaitPage(WaitPage): wait_for_all_groups = True class Send(Page): form_model = 'group' form_fields = ['sent_amount'] @staticmethod def is_displayed(player: Player): group = player.group return player.id_in_group == 1 class WaitForP1(WaitPage): pass class SendBack(Page): form_model = 'group' form_fields = ['sent_back_amount'] @staticmethod def is_displayed(player: Player): group = player.group return player.id_in_group == 2 @staticmethod def vars_for_template(player: Player): group = player.group tripled_amount = group.sent_amount * C.MULTIPLIER return dict(tripled_amount=tripled_amount) class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs class Results(Page): form_model = 'player' @staticmethod def vars_for_template(player: Player): group = player.group return dict(tripled_amount=group.sent_amount * C.MULTIPLIER) class Survey(Page): form_model = 'player' form_fields = ['Name', 'OtherName', 'Age', 'Gender', 'Region', 'SpendRegion', 'Specialization', 'Major', 'LevelofEducation', 'Risk', 'FinancialSituation', 'SatisfiedLife', 'Trust', 'FreedomofChoice', 'Feedback', 'BankCard'] @staticmethod def is_displayed(player: Player): return player.round_number == 4 page_sequence = [Introduction, MyWaitPage, Send, WaitForP1, SendBack, ResultsWaitPage, Results, Survey]