from otree.api import * #( # models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, # Currency as c, currency_range #) import random doc = """ hybrid_auctions """ author = 'Song, Jian' class Constants(BaseConstants): name_in_url = 'hybrid_auctions' players_per_group = 2 num_rounds = 3 #in real experiment, this should be changed. v = cu(1000) instructions_template = 'hybrid_auctions/instructions.html' table_template = __name__ + '/table.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): winner_pay_choice = models.IntegerField( min=0, max=1000, label="How much discount you would like to provide?" ) #w all_pay_choice = models.IntegerField( min=0, max=1000, label="How much quality you would like to provide?" ) #a win = models.BooleanField() round_earning = models.CurrencyField() part1_payoff=models.CurrencyField() score = models.FloatField() temp_score = models.FloatField(initial= 0.0, blank=True) raw_responses = models.LongStringField() chose_lottery = models.BooleanField() won_lottery = models.BooleanField(initial=False) age = models.IntegerField( label='What is your age?', min=18, max=125) gender = models.StringField( choices=['Male', 'Female', 'Other'], label='What is your gender?', widget=widgets.RadioSelect) citizenship = models.StringField( label='Your country of citizenship') major = models.StringField( label='What is your major?') year = models.StringField( choices=['Freshman', 'Sophomore', 'Junior', 'Senior', 'Graduate', 'Other'], label='Which year are you in?', widget=widgets.RadioSelect) risk = models.StringField( choices=['Strongly Disagree', 'Disagree', 'Slightly Disagree', 'Slightly Agree', 'Agree', 'Strongly Agree'], label='You are the person who is fully prepared to take risks.', widget=widgets.RadioSelect) decision = models.TextField(initial=None, verbose_name="How you made your decisions in Part 1?") comments = models.TextField(blank=True, initial=None, verbose_name="Do you have any comment, questions, or complains about today's experiment?") name = models.TextField(initial=None, verbose_name="To link your identity with your name, please type your name below. Note that your identity will be confidencial. " ) class Trial(ExtraModel): player = models.Link(Player) sure_payoff = models.CurrencyField() lottery_high = models.CurrencyField() lottery_low = models.CurrencyField() probability = models.FloatField() chose_lottery = models.BooleanField() randomly_chosen = models.BooleanField(initial=False) #Functions def read_csv(): import csv f = open(__name__ + '/stimuli.csv', encoding='utf-8-sig') rows = list(csv.DictReader(f)) return rows def other_player(player: Player): return player.get_others_in_group()[0] def set_payoffs(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) for player in [p1,p2]: player.score = round((player.winner_pay_choice)**(1/3) * (player.all_pay_choice)**(2/3), 2) if p1.score == p2.score: #tie occurs p = random.random() if (p<0.5): p1.win = True p2.win = False else: p1.win = False p2.win = True elif p1.score > p2.score: #p1 score is greater p1.win = True p2.win = False elif p1.score < p2.score: #p2 score is greater p1.win = False p2.win = True for player in [p1, p2]: if player.win: player.round_earning = Constants.v - player.winner_pay_choice - player.all_pay_choice else: player.round_earning = -player.all_pay_choice def creating_session(subsession:Subsession): #print('in creating_session') session = subsession.session subsession.group_randomly() if subsession.round_number == 1: paying_round = random.randint(2, Constants.num_rounds) session.vars['paying_round'] = paying_round for p in subsession.get_players(): p.round_chosen = session.vars['paying_round'] stimuli = read_csv() for stim in stimuli: Trial.create(player=p, **stim) # PAGES class Welcome(Page): def is_displayed(self): return self.round_number == 1 after_all_players_arrive = creating_session class Practiceround_instruction(Page): def is_displayed(self): return self.round_number == 1 class Practiceround_summary (Page): def is_displayed(self): return self.round_number == 1 class Contribution(Page): form_model = 'player' form_fields = ['winner_pay_choice', 'all_pay_choice'] @staticmethod def vars_for_template(player: Player): return dict( round_shown=player.round_number-1, total_shown=Constants.num_rounds - 1 ) class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs class Part1_end(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def vars_for_template(player: Player): session = player.session player_in_round = player.in_round(session.vars['paying_round']) return dict( part1_payoff=player_in_round.round_earning, paying_round=session.vars['paying_round'] - 1 ) class Stimuli(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds form_model = 'player' form_fields = ['raw_responses'] @staticmethod def vars_for_template(player: Player): return dict(trials=Trial.filter(player=player)) @staticmethod def before_next_page(player: Player, timeout_happened): import json import random trials = Trial.filter(player=player) # you could adjust this code to handle timeout_happened. responses = json.loads(player.raw_responses) for trial in trials: trial.chose_lottery = responses[str(trial.id)] trial = random.choice(trials) trial.randomly_chosen = True player.chose_lottery = trial.chose_lottery if player.chose_lottery: #player.won_lottery = trial.probability > random.random() if trial.probability > 100*(random.random()): player.won_lottery = True else: player.won_lottery = False if player.won_lottery: risk_payoff = trial.lottery_high else: risk_payoff = trial.lottery_low else: risk_payoff = trial.sure_payoff player.payoff = risk_payoff class Stimuli_Results(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def vars_for_template(player: Player): trials = Trial.filter(player=player, randomly_chosen=True) return dict(trials=trials) class Results(Page): @staticmethod def vars_for_template(player: Player): return dict(other_player_all_pay_choice=other_player(player).all_pay_choice, other_player_winner_pay_choice=other_player(player).winner_pay_choice, other_player_score = other_player(player).score) class End_game(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def vars_for_template(player: Player): session = player.session player_in_round = player.in_round(session.vars['paying_round']) return dict(part1_payoff= player_in_round.round_earning, part2_payoff= player.payoff, total_payoff = player_in_round.round_earning + player.payoff, paying_round = session.vars['paying_round'] - 1, player_chose_lottery = player.chose_lottery, player_won_lottery = player.won_lottery ) class Demographic(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds form_model = 'player' form_fields = ['name', 'age', 'gender', 'citizenship', 'major', 'year', 'risk'] class Comment(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds form_model = 'player' form_fields = ['decision', 'comments'] page_sequence = [ Welcome, Practiceround_instruction, Contribution, ResultsWaitPage, Results, Practiceround_summary, Part1_end, Stimuli, Stimuli_Results, Demographic, Comment, End_game ]