<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Option 2
Step1:  Notice that as we decreased the standard deviation (from half of the mean to a tenth of the mean) our spread of probabilities got a lot smaller.  Also notice that this method doesn't require any scaling of the probabilities to get them to sum to 1.  This gives me a warm and fuzzy feeling that this is a good way to generate coupon probabilities.
Additional thought
<ASSISTANT_TASK:>
Python Code:
n = 20 #number of coupons
mu = 1/n #this is the mean coupon probability
sigma = mu/2 #this is the std dev parameter we will play around with - it seems to make sense to express it in terms of the mean
x = np.arange(n)+0.5 #arange goes from 0 to n-1, and I want it to go from 1 to n
p_x = stat.norm.ppf(x/(n), mu, sigma)
print('mean prob = %1.16f' % np.mean(p_x), ', sum of all probs = %1.16f' % np.sum(p_x) )
plt.bar(x, p_x, align='center')
plt.axis([0,n,0,2/n])
n = 20 #number of coupons
mu = 1/n #this is the mean coupon probability
sigma = mu/10 #this is the std dev parameter we will play around with - it seems to make sense to express it in terms of the mean
x = np.arange(n)+0.5 #arange goes from 0 to n-1, and I want it to go from 1 to n
p_x = stat.norm.ppf(x/n, mu, sigma)
print('mean prob = %1.16f' % np.mean(p_x), ', sum of all probs = %1.16f' % np.sum(p_x) )
plt.bar(x, p_x, align='center')
plt.axis([0,n,0,2/n])
Explanation: Option 2: Normal Distribution
After playing around with the previous option (in the notebook GenerateProbs) and thinking a little more about what makes a distribution "normal," I've come up with the following method that I think will work nicely for generating probabilities for a general coupon collector simulation.  
My idea starts with the idea of a quantile function (called a percent point function (ppf) in SciPy's stats library).  This is because the ppf is a way to get the probability of most of the coupons centered around some number with a few coupons having lower probabilities and a few coupons having higher probabilities; a ppf is the inverse of a pdf which would give the number of coupons having that probability.  
My idea continues by knowing that normal distributions are symmetrical around some number (the mean) and that the mean of the coupons' probabilities must be $\frac{1}{n}$.  This is because there are $n$ coupons and the sum of their probabilities must be 1, so the mean must be $\frac{1}{n}$.  
The only parameter that defines a normal distribution other than the mean is the standard deviation (or alternately the variance), and this can change to give us a different "spread" of probabilities around the mean of $\frac{1}{n}$.  The higher the standard deviation, the greater the spread, just like we expect.  
While this may not be the absolute best way to generate coupon probabilities, it seems like this results in a set of probabilities that meets criteria that most people would call "normal."  Let's look at an example and see how changing the standard deviation around affects the shape of the probabilities.
End of explanation
n = 20 #number of coupons
mu = 1/n #this is the mean coupon probability
sigma = mu #this is the std dev parameter we will play around with - it seems to make sense to express it in terms of the mean
x = np.arange(n)+0.5 #arange goes from 0 to n-1, and I want it to go from 1 to n
p_x = stat.norm.ppf(x/n, mu, sigma)
print('mean prob = %1.16f' % np.mean(p_x), ', sum of all probs = %1.16f' % np.sum(p_x) )
plt.bar(x, p_x, align='center')
plt.axis([0,n,-0.1,3/n])
Explanation: Notice that as we decreased the standard deviation (from half of the mean to a tenth of the mean) our spread of probabilities got a lot smaller.  Also notice that this method doesn't require any scaling of the probabilities to get them to sum to 1.  This gives me a warm and fuzzy feeling that this is a good way to generate coupon probabilities.
Additional thought:  What are the allowable values for the standard deviation?
Obviously the minimum value would be 0.  This would give us the coupon collector's problem with a uniform distribution, so it is a good way to check our work.  But what is the max value?  From the example below, we see that there is clearly a point where the first few coupons have negative probabilities.  This should be avoided:
End of explanation
<END_TASK>