Welcome, guest | Sign In | My Account | Store | Cart
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
from __future__ import division
import random, bisect
 
class ItemGenerator(object):
    '''Choices randomly an element from a list.

    It does it not uniformly, but using a given weight for
    each element.

    Just instantiate this class passing a list of pairs 
    (item, weight), and then call it to get the items.
    '''
    def __init__(self, items):
        self.puntos = []
        self.ponderado = []
        total = sum(x[1] for x in items)
        acum = 0
        for it,peso in items:
            acum += peso
            self.puntos.append(it)
            self.ponderado.append(acum/total)
        self.total = acum - 1

    def __call__(self):
        ind = random.random()
        cual = bisect.bisect(self.ponderado, ind)
        return self.puntos[cual]
 
if __name__ == "__main__":
    # This shows the usage, and also test the recipe, as calling that
    # a lot of times, it should return the elements in the same 
    # given proportion

    items = (
        ("A", 10),
        ("B", 100),
        ("C", 5)
    )

    itgen = ItemGenerator(items)
    cuenta = {}
    for i in range(1000000):
        item = itgen()
        cuenta[item] = cuenta.get(item, 0) + 1
    print cuenta

History