## L219: Solution

'''
Let X stand for a set/list/tuple/range with n = len(X) > 1. 
Let W be a list of n positive numbers [weights]. 
Define a function select(X,W) that returns an element of X 
with probability proportional to the corresponding weight.
'''
import sys
sys.path.append("D:/Docencia/2015/py/")
from cdi import rd_float

def select(X,W):
    if not is_list_positive_numbers(W):
        return 'L219/select: second parameter is not a list of positive numbers'
    if len(W)<2:
        return 'L219/select: second parameter is not a weight list'
    W = accumulate(W)
    n = len(W)
    if len(X) != n:
        return 'L219/select: lengths of parameters do not match'
    S = W[n-1]
    r = rd_float(0,S)
    #print('r =',r)
    j = 0
    while r >= W[j]:
        j +=1
    #print('j =',j)
    return X[j]

def is_list_positive_numbers(W):
    return isinstance(W,list) and all(w>0 for w in W)
def accumulate(W):
    A = []
    a = 0
    for w in W:
        a += w
        A += [a]
    return A

## Tests

X = "aeiou"
W = [22,30,15,20,13]
N = 10000
# x = select(X,W)
# print('x =', x)
S=[select(X,W) for _ in range(N)]
H = [S.count(x) for x in X]
print('Frequences:', H)