import csv import math from otree.api import * doc = """ Social Value Orientation (Murphy et al) """ def read_csv(): with open('svo/SVO.csv', encoding='utf-8-sig') as f: return [ dict( round_number=int(row['round_number']), to_self=int(row['to_self']), to_other=int(row['to_other']), ) for row in csv.DictReader(f) ] def group_rows(): from collections import defaultdict d = defaultdict(list) for row in read_csv(): round_number = row['round_number'] d[round_number].append(row) return d class Constants(BaseConstants): name_in_url = 'svo' players_per_group = None num_rounds = 15 # change to 15 for the full task chart_template = 'svo/chart.html' instructions_template = 'svo/instructions.html' rows = group_rows() class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): choice = models.IntegerField(choices=list(range(9))) angle = models.FloatField() category = models.StringField() def assign_category(angle): if angle > 57.15: return 'Altruistic' if angle > 22.45: return 'Prosocial' if angle > -12.04: return 'Individualistic' return 'Competitive' class Decide(Page): form_model = 'player' form_fields = ['choice'] @staticmethod def js_vars(player: Player): return dict(rows=Constants.rows[player.round_number]) class Results(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def vars_for_template(player: Player): participant = player.participant to_self_total = 0 to_other_total = 0 for p in player.in_all_rounds(): row = Constants.rows[p.round_number][p.choice] to_self_total += row['to_self'] to_other_total += row['to_other'] avg_self = to_self_total / Constants.num_rounds avg_other = to_other_total / Constants.num_rounds radians = math.atan((avg_other - 50) / (avg_self - 50)) participant.svo_angle = round(math.degrees(radians), 2) participant.svo_category = assign_category(participant.svo_angle) page_sequence = [Decide, Results]