Ordered and Unordered Sampling, with and without Replacement

# order does not matter, without replacement
# n >= k
# n choose k
def combinations(n,k):
    denom = 1
    numer = 1
    if n >= k and n >= 1 and k >= 1:
        for i in range(1,n+1):
            numer *= i 
        for j in range(1,k+1):
            denom *= j
        for h in range(1, n-k+1):
            denom *= h
    output = numer // denom 
    return output

# order matters, without replacement 
# n >= k
def permutations(n,k):
    denom = 1
    numer = 1
    if n >= k and n >= 1 and k >= 1:
        for i in range(1,n+1):
            numer *= i 
        for j in range(1, n-k+1):
            denom *= j
    output = numer // denom
    return output

# order matters , with replacement
def ord_w_rep(n, k):
    return n**k

# order does not matter, with replacement
def unord_w_rep(n,k):
    output = combinations(n+k-1, k)
    return output