[Tutor] Graphing the random.gauss distribution
Dick Moores
rdm at rcblue.com
Tue Aug 14 18:29:48 CEST 2007
At 06:47 AM 8/14/2007, Kent Johnson wrote:
>Dick Moores wrote:
> > Kent Johnson posted this to Tutor list Aug 8, 2007
> > (<http://mail.python.org/pipermail/tutor/2007-August/056194.html>):
> >
> > ============================================
> > > Python provides you with a pseudo random number generator whose output
> > > values are uniformly distributed between the input parameters. What you
> > > are dealing with in fish weights or test scores or other natural
> > > phenomena is most likely a normal distribution. Check out Wikipedia's
> > > normal distribution entry. The math is really juicy. You may end up
> > > with a recipe for the Python Cookbook.
> >
> > No need for all that, use random.gauss()
> >
> > Kent
> > ============================================
> >
> > I hadn't noticed gauss was there in the Random module. I got to
> > wondering if I could graph the distribution. This code produces a
> > nice bell-curve-seeming curve (on its side). Takes about 80 secs to
> > run on my computer. To fit your situation, the length of the bars can
> > be shortened or lengthened by decreasing or increasing, respectively,
> > the divisor of gaussCalls in line 5, "barLengthAdjuster =
> gaussCalls//2600".
> >
> > Dick Moores
> >
> > ==============================
> > from random import gauss
> > mean = 100
> > std = 10
> > gaussCalls = 10000000
> > barLengthAdjuster = gaussCalls//2600
> >
> > d = []
> > for k in range(200):
> > d.append([k, 0])
>
>This could be a list comprehension:
>d = [ [k, 0] for k in range(200) ]
So you recommend using list comprehensions wherever possible? (I sure
wouldn't have thought of that one..)
>but there is no need to keep the array index in the array so this is
>simpler:
>
>d = [0] * 200
>
> > for k in xrange(gaussCalls):
> > n = int(gauss(mean, std))
> > d[n][1] += 1
>
>This becomes just
> d[n] += 1
>
> >
> > for c in d:
> > barLength = c[1]//barLengthAdjuster
> > print barLength, "=", c[0], c[1]
By the time my code got into my post, I had changed "print barLength
* "=", c[0], c[1]" to "print barLength, "=", c[0], c[1]", thinking
upon reading it over that the "*" was a mistake. :-( The code I
didn't send DID make bars out of "="s.
>Use enumerate() to get the indices as well as the list contents. This
>version prints an actual bar as well:
>for i, count in enumerate(d):
> barLength = count//barLengthAdjuster
> print i, '*' * barLength, count
Ah, enumerate() is nice! I'd forgotten about it. And "*" IS better
for bars than "=".
I prefer the index (or integer) to come after the bar ends, and
before the count. One reason is that if the index is at the base of
the bar, at 100 and above, the bars get pushed out one character
longer than they should be relative to the 99 or less bars. I suppose
there's a way to handle this, but I couldn't think of it then (but see below).
So this is my code now:
====================================
from random import gauss
mean = 100
std = 10
gaussCalls =1000000
barLengthAdjuster = gaussCalls//2600
d = [0] * 200
for k in xrange(gaussCalls):
n = int(gauss(mean, std))
d[n] += 1
for i, count in enumerate(d):
barLength = count//barLengthAdjuster
print '*' * barLength, i, count
=====================================
This would solve the problem I mentioned above caused by putting the
indices at the bases of the bars:
for i, count in enumerate(d):
barLength = count//barLengthAdjuster
if i < 100:
print "%d %s %d" % (i, '*' * barLength, count) # there are
2 spaces between %d and %s
else:
print "%d %s %d" % (i, '*' * barLength, count)
Thanks very much, Kent, for taking the time to advise me on my code.
Dick
More information about the Tutor
mailing list