2
votes

I tried to run the code below

import math
import random
from matplotlib import pyplot as plt
from collections import Counter

def bucketize(point,bucket_size):
    return bucket_size * math.floor(point/bucket_size)

def make_histogram(points, bucket_size):
    return Counter(bucketize(point,bucket_size) for point in points)

def plot_histogram(points,bucket_size,title=""):    
    histogram = make_histogram(points,bucket_size)
    plt.bar(histogram.keys(),histogram.values(),width=bucket_size)
    plt.title(title)
    plt.show()

def inverse_normalCDF(p,miu=0,sigma=1,tolerance=0.00001):
    if miu !=0 or sigma !=1:
        return miu + sigma * inverse_normalCDF(p,tolerance=tolerance)
    low_z,low_p = -10.0,0
    hi_z,hi_p = 10.0,1
    while hi_z - low_z > tolerance:
        mid_z = (low_z + hi_z)/2
        mid_p = normalCDF(mid_z)
        if mid_p > p:
            low_z,low_p = mid_z,mid_p
        elif mid_p > p:
            hi_z, hi_p = mid_z,mid_p
        else:
            break
    return mid_z

def normalCDF(x,miu=0,sigma=1):
    return (1+math.erf((x-miu)/math.sqrt(2)/sigma))/2


random.seed(0)
#uniform = [200*random.random()-100 for _ in range (10000)]
#plot_histogram(uniform,10,"uniform histogram")
normal = [57 * inverse_normalCDF(random.random() for _ in range(10000))]
plot_histogram(normal,10,"normal histogram")

but the program shows an error saying "RecursionError: maximum recursion depth exceeded in comparison", what should I do to fix the RecursionError, because it impacts the inverse_normalCDF function?

The error no longer shows maximum recursion depth exceeded in function, instead

Traceback (most recent call last):
  File "C:\Users\asus\Documents\Sublime\dataScience\normalHistogram.py", line 41, in <module>
    normal = [57 * inverse_normalCDF(random.random() for _ in range(10000))]
  File "C:\Users\asus\Documents\Sublime\dataScience\normalHistogram.py", line 26, in inverse_normalCDF
    if mid_p > p:
TypeError: '>' not supported between instances of 'float' and 'generator'
[Finished in 0.7s]

The version of pyhton I'm using is 3.7 and the matplotlib version I use is 3.0.3

*update, changed the

def inverse_normalCDF(p,miu=0,sigma=1,tolerance=0.00001): fix some typos in the code

1
Your recursive call to inverse_normalCDF will obviously recurse forever since the parameters you pass will always match the if statement. - Blorgbeard
I believe it's a typo and he meant to put sigma=1 on the inverse_normalCDF - Eduardo macedo
thanks, for pointing that out, I fixed some typos in the code but it still shows Traceback (most recent call last): File "C:\Users\asus\Documents\Sublime\dataScience\normalHistogram.py", line 41, in <module> normal = [57 * inverse_normalCDF(random.random() for _ in range(10000))] File "C:\Users\asus\Documents\Sublime\dataScience\normalHistogram.py", line 26, in inverse_normalCDF if mid_p > p: TypeError: '>' not supported between instances of 'float' and 'generator' [Finished in 0.7s] - Ariya Susanto
@AriyaSusanto: You are passing a generator to inverse_normalCDF—maybe your parentheses are misplaced? - Davis Herring
ah yeah, thanks, I misplaced the bracket in the random.random(). - Ariya Susanto

1 Answers

1
votes

You were almost there. That error can be resolved by rewriting your list comprehension:

normal = [57 * inverse_normalCDF(random.random()) for _ in range(10000)]

I merely moved a closing parenthesis so that the function inverse_normalCDF is passed a single value for each iteration, rather than the entire generator.