def main(dic):
    values = sorted(dic.values())
    r, nr, prob = [], [], []
    for v in values:
        if not r or r[-1] != v:
            r.append(v)
            nr.append(1)
        else:
            nr[-1] += 1
    rr = dict(map(lambda x:list(reversed(x)), enumerate(r)))
    total = reduce(lambda x, y:(x[0]*x[1]+y[0]*y[1], 1), zip(nr, r))[0]
    z = getz(r, nr)
    a, b = least_square(map(lambda x:log(x), r), map(lambda x:log(x), z))
    use_good_turing = False
    nr.append(exp(a+b*log(r[-1]+1)))
    for i in xrange(len(r)):
        good_turing = (r[i]+1)*(exp(b*(log(r[i]+1)-log(r[i]))))
        turing = (r[i]+1)*nr[i+1]/nr[i] if i+1<len(r) else good_turing
        diff = ((((r[i]+1)**2)/nr[i]*nr[i+1]/nr[i]*(1+nr[i+1]/nr[i]))**0.5)*1.65
        if not use_good_turing and abs(good_turing-turing)>diff:
            prob.append(turing)
        else:
            use_good_turing = True
            prob.append(good_turing)
    sump = reduce(lambda x, y:(x[0]*x[1]+y[0]*y[1], 1), zip(nr, prob))[0]
    for cnt, i in enumerate(prob):
        prob[cnt] = (1-nr[0]/total)*i/sump
    return total/total/nr[0], dict(zip(dic.keys(), map(lambda x:prob[rr[x]], dic.values())))
dataset/ETHPy150Open isnowfy/snownlp/snownlp/utils/good_turing.py/main/swapped operands of `/`