#!/usr/bin/python

import sys
import time
import math

############### Utils functions #####################################################

def print_usage():
    print 'USAGE\n\t   ./203hotline [n k | d]\n\n',
    print 'DESCRIPTION\n\t   n\tn value for the computation of (n k)\n',
    print '\t   k\tk value for the computation of (n k)\n',
    print '\t   d\taverage duration of calls (in seconds)\n',
    
def minimum(a, b):
    if (a < b):
        return (a)
    return(b)

def binomial_coeff(n, k):
    res = 1
    i = 0
    lim = minimum(k, (n - k))
    if (k < 0 or k > n):
        print("Error, k must be integer greater than 0 and not greater than n")
        exit(84)
    if (n == 0 or k == 0):
        return (1)
    while (i < lim):
        tmp1 = n - i
        tmp2 = i + 1
        res = res * tmp1 / tmp2
        i = i + 1
    return (res)

def print_combination(k, n):
    res = binomial_coeff(k, n)
    print '%i-combination of a' % (n),k,'set:\n',res
    
#############################################################################


############### Distribution functions ######################################

def poisson(k, m):
    res = (math.exp(-m)*m**k)/math.factorial(k)
    return (res)

def poisson_distribution(n):
    var = n / 3600.0
    overload = 0.0
    k = 0
    j = 1
    m = (var * 3500) / 8
    start = time.time()
    print("Poisson distribution:")
    while (k <= 50):
        res = poisson(k, m)
        print "%i -> " % (k) + "%.3f" % (res),
        if (k == 50):
            sys.stdout.write('\n')
        elif (j == 6):
            sys.stdout.write('\n')
            j = 0
        else:
            sys.stdout.write('\t')
        if (k > 25):
            overload = overload + res
        k = k + 1
        j = j + 1
    end = time.time()
    print 'overload: %.1f' % (overload * 100) + '%\n',
    print 'computation time: %.2f ms\n' % ((end - start) * 1000),


def binomial_distribution(n):
    var = n / 28800.0
    overload = 0.0
    k = 0
    j = 1
    start = time.time()
    print("Binomial distribution:")
    while (k <= 50):
        tmp1 = binomial_coeff(3500, k) * var**k
        tmp2 = (1 - var)**(3500 - k)
        res = tmp1 * tmp2
        print '%i ->' % (k), '%.3f' % (res),
        if (k == 50):
            sys.stdout.write('\n')
        elif (j == 6):
            sys.stdout.write('\n')
            j = 0
        else:
            sys.stdout.write('\t')
        if (k > 25):
            overload = overload + res
        k = k + 1
        j = j + 1
    end = time.time()
    print 'overload: %.1f' % (overload * 100) + '%\n',
    print 'computation time: %.2f ms\n\n' % ((end - start) * 1000),
    
##############################################################################


############## Main instructions #############################################

if (len(sys.argv) > 3):
    sys.stderr.write('Error, too many arguments\n')
    exit(84)

if (len(sys.argv) == 1):
    sys.stderr.write('Error, too few arguments. Try [./203hotline -h]\n')
    exit(84)

if (len(sys.argv) == 2 and sys.argv[1] == '-h'):
    print_usage()
    exit(0)
 
if (len(sys.argv) == 2):
    if (sys.argv[1].isdigit() == 0):
        sys.stderr.write('Error, argument in position one must be an integer\n')
        exit(84)
    binomial_distribution(int(sys.argv[1]))
    poisson_distribution(int(sys.argv[1]))
    exit(0)

if (len(sys.argv) == 3):
    if (sys.argv[1].isdigit() == 0):
        sys.stderr.write('Error, argument in position one must be an integer\n')
        exit(84)
    if (sys.argv[2].isdigit() == 0):
        sys.stderr.write('Error, argument in second position must be an integer\n')
        exit(84)
        
    n = int(sys.argv[2])
    k = int(sys.argv[1])
    print_combination(k, n)
    exit(0)

    ###########################################################################
