An easier method for randomly selecting from an element from a list based on the corresponding probability

The task I wanted to implement is straightforward. I have a list [player1, player2, player3] and the probability of each player being selected [prob1, prob2, prob3]. I wanted to select 1 player based on the corresponding probability. The experiment is going to be in PsychoPy and PsychJS, so I implemented a solution for both. The way I did it was super tedious, I wanted to know if there was a cleaner way of doing it.

The way I implemented it in Python is

import random

selected_player = random.choices([player1, player2, player3],  weights=(prob1,prob2,prob3), k=1)

and in PsychJS, I don’t know if there is an existing library that I can use, so I implemented the probabilistic selection function from scratch. If you know of any simpler method, please let me know.

// Before Experiment
//create distribution
const createDistribution = (weights, size) => {
    const distribution = [];
    const sum = weights.reduce((a, b) => a + b);
    const quant = size / sum;
    for (let i = 0; i < weights.length; ++i) {
        const limit = quant * weights[i];
        for (let j = 0; j < limit; ++j) {
            distribution.push(i);
        }
    }
    return distribution;
};

const randomIndex = (distribution) => {
    const index = Math.floor(distribution.length * Math.random());  // random index
    return distribution[index];  
};

const randomItem = (array, distribution) => {
    const index = randomIndex(distribution);
    return array[index];
};
// selection

distribution = createDistribution([prob1,prob2,prob3,prob4], 1000);
selected_player = randomItem([player1, player2, player3, player4], distribution);

How about the following:

playerList = [player1, player2, player3]
playerProb = [x, y, z] # Must add up to 100

selected_player = playerList[-1]
percentage = randint(100)
percentCount = 0

for Idx in range(len(playerList)):
     if percentage < percentCount + playerProb[Idx]:
          selected_player = playerList[Idx]
     percentCount += playerProb[Idx]

That’s GENIUS! Thank you! :star_struck:

A follow-up question: In PsychJS, can I import an existing library? There was one time I wanted to use the Permutation function, which could be solved by importing a library, but somehow it didn’t work. What I did was implement the Permutation function and put it in the BEFORE Experiment Module.

@wakecarter

You can’t import a Python function for online use. You can write a function in Before Experiment or Begin Experiment. Have a look in my crib sheet or code snippets for how to do this.