Random Distribution to fit an Average Python This is from my own question on Stack Overflow. 

I want to get average numbers from a range such that they fit an intended average.  I expect something bell-curve-like, but asymmetrical unless the average is the mean of the range.  The function should allow for any degree of deviation.  In my Overflow question, I wanted it to pick from a list, but that's an easy modification if my idea works.

This is what I've come up with: (imports: numpy and random)

def randlist(minn, maxn, goaln, countn):
    nlist = []
    for i in range(0, countn):
        if len(nlist) &gt; 10:
            ave = numpy.mean(nlist)
            if ave &gt; goaln:
                a = random.uniform(minn, goaln)
            else:
                a = random.uniform(goaln, maxn)
        else:
            a = random.uniform(minn, maxn)
        nlist.append(a)
    return nlist


Trying it out:

b = randlist(1, 10, 7, 1000)
print len(b)
&gt;&gt; 1000
print numpy.mean(b)
&gt;&gt; 6.99951157861


I'm no mathematician; is this as functional as it appears to me to be?
If you want to express the field or distribution in a wave form, you should consider doing a Fourier Transformation on the function. Now, I must admit that I haven't understood exactly the sort of distribution function you are looking for. Numpy already has implementations for Gaussian distribution and such in the random module.

You can easily do so by:

numpy.random.normal(loc=7, scale=1.0, size=None)


This will produce a normal distribution with μ=7 and σ2=1.0



Now, about your code



def randlist(minn, maxn, goaln, countn):
    nlist = []


Consider renaming this function to the distribution's name that you are looking for. Such as normal for a normal distribution. Rename minn and maxn to min_ or max_. Since you are trying to avoid clashes with the keywords, you could also try using synonyms such as low and high.

for i in range(0, countn):


range(countn) is enough to start the list from 0.

if len(nlist) &gt; 10:
    ave = numpy.mean(nlist)
    if ave &gt; goaln:
        a = random.uniform(minn, goaln)
    else:
        a = random.uniform(goaln, maxn)
else:
    a = random.uniform(minn, maxn)


Since you are adding the first 10 numbers randomly to the list, you can do so inside the nlist itself in the form of a list comprehension (see sample code below).

def weighted_distribution(low, high, ev, count, start=10):
    result = [random.uniform(low, high) for i in range(start)]
    for i in range(count-start):
        if numpy.mean(result)&gt; ev:
            result.append(random.uniform(low, ev))
        else:
            result.append(random.uniform(ev, high))
    return result


ev is the expected value for this distribution (mean).