oTree Forum >

Ranking participant given their score to a survey

#1 by Ben (edited )

Hi, 

I would like to rank my participant given their score to a "pre-experiment survey", and then use this ranking to create groups for the task

Here is my code for one question as an example (it is located in the class Player(BasePlayer):)
    q1 = models.IntegerField(choices=[(1, "Never"), (2, "Sometimes"), (3, "Often"), (4, "Always")],
                             label="    xxx ?    ",
                             widget=widgets.RadioSelect)
    q2 = ...
    
    rank = models.IntegerField()

Then, in a class Survey(Page): I have the following code :
 
class Survey(Page):
    form_model = 'player'
    form_fields = ["q1","q2","q3","q4" ]
    
    @staticmethod
    def before_next_page(player: Player, timeout_happened):
        score = sum([player.q1,    player.q2,    player.q3,    player.q4 ])
        Player.rank = score
        
Then I don't really know what to do. I guess I should create a list with all of the score and sort them but I am not sure how to do that.

Thank you in advance for your answer !

Best,

Benjamin

#2 by Ben (edited )

Hi,

With some improvement, I manage to do it. Here is the code:

class Group(BaseGroup):
    total_rank = models.IntegerField()
    med = models.FloatField()

class Player(BasePlayer):
    q1 = ....
    
    rank = models.FloatField()
    roole = models.IntegerField()

# FUNCTIONS
def sum_score(group: Group):
    players = group.get_players()
    ranks = [p.rank for p in players]
    group.total_rank = sum(ranks)
    # to get the median
    group.med = statistics.median(ranks)

    # check for tie
    if len(set(ranks)) != len(ranks):
        tied_players = [p for p in players if p.rank == group.med]
        for p in tied_players:
            p.rank = round(p.rank + random.uniform(-0.5, 0.5), 1)

# PAGES
class Survey(Page):
    form_model = 'player'
    form_fields = ["q1","q2","q3","q4"]

    @staticmethod
    def before_next_page(player: Player, timeout_happened):
        player.rank = sum([player.q1 + player.q2 + player.q3 + player.q4])


class ResultsWaitPage(WaitPage):
    after_all_players_arrive = sum_score

class Results(Page):
    @staticmethod
    def vars_for_template(player):
        if player.rank >= player.group.med:
            player.roole = "A"
        else:
            player.roole = "B"
            
            
        # set the value of player.roole in session.vars
        player.participant.vars['roole'] = player.roole

        return {
            'roole': player.roole,
        }

Write a reply

Set forum username