# Path: pydigree/common.py
# def product(iter):
#     """
#     Reduces an iterable by multiplication. Analogous to sum, but with
#     multiplication instead of addition.
# 
#     :returns: overall product
#     :rtype: numeric
#     """
#     # This should really be a python builtiin
#     if not iter:
#         # sum([]) returns 0, so this will return 1
#         return 1
#     return reduce(multiply, iter)
# 
# def cumsum(iter):
#     """
#     Cumulative sum:
#     >>> pydigree.cumsum([0,1,2,3,4])
#     [0, 1, 3, 6, 10]
#     
# 
#     :param iter: the iterable to be cumsum'ed
#     
#     Returns: cumulative sums
#     :rtype: integer
#     """
#     if not iter:
#         return []
#     value = 0
#     g = [None] * len(iter)
#     for idx, x in enumerate(iter):
#         value += x
#         g[idx] = value
#     return g
# 
# def flatten(x):
#     """
#     Recursively flattens lists.
#     """
#     try:
#         it = iter(x)
#     except TypeError:
#         yield x
#     else:
#         for i in it:
#             for j in flatten(i):
#                 yield j
# 
# def invert_dict(d):
#     """
#     Makes the keys the values and the values the keys
#     
#     .. warning:: 
#         No guarantee of dictionary structure if mappings are not unique
#     
#     :param d: dictionary to be inverted
# 
#     :rtype: dict
#     """
#     return dict((y, x) for x, y in d.items())
# 
# def merge_dicts(*args):
#     ''' Merges two dictionaries into one bigger one '''
#     odict = {}
#     for d in args:
#         odict.update(d)
#     return odict
# 
# Path: pydigree/common.py
# def count(val, iterable):
#     """ 
#     Counts how many times a value (val) occurs in an iterable, excluding `None`
# 
#     
#     :param val: The value to be counted
#     :param iterable: values to be counted over
#     :type iterable: iterable  
# 
#     :return: the count of values
#     :rtype: int
#     """
#     return sum(1 for x in (y for y in iterable if y is not None) if val == x)
# 
# def grouper(iterable, n, fillvalue=None):
#     """
#     Collect data into fixed-length chunks or blocks
#     :param iterable: values to evaluate
#     :param n: size of the groups
#     :param fillvalue: Value to pad the last group with if len(iterable) % n != 0
#     
#     :type n: integer
#     :rtype: a generator
#     """
#     
#     # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
#     args = [iter(iterable)] * n
#     return zip_longest(fillvalue=fillvalue, *args)
# 
# def log_base_change(value, old, new):
#     ''' 
#     Changes the base of the logarithm used on `value` from `old` to `new`
# 
#     Arguments: 
#     value: the value to be converted
#     old: old base (numeric)
#     new: new base (numeric)
# 
#     :returns: log of value in new base  
#     :rtype: float
#     '''
#     return value / log(old, new) 
# 
# def mode(seq):
#     """ 
#     Returns the most common value in a sequence 
# 
#     :param seq: sequence of values to evaluate
#     """
# 
#     if not len(seq):
#         raise IndexError('Sequence is empty')
#     tab = table(seq)
#     return sorted(tab.items(), key=lambda x: x[1], reverse=True)[0][0]
# 
# Path: pydigree/common.py
# def count(val, iterable):
# def table(seq):
# def mode(seq):
# def random_choice(iterable):
# def flatten(x):
# def grouper(iterable, n, fillvalue=None):
# def invert_dict(d):
# def merge_dicts(*args):
# def log_base_change(value, old, new):
# def product(iter):
# def cumsum(iter):


from nose.tools import assert_raises
from pydigree.common import product, cumsum, flatten, invert_dict, merge_dicts
from pydigree.common import count, grouper, log_base_change, mode
from pydigree.common import runs, runs_gte, interleave, is_sorted
from pydigree.cydigree.cyfuncs import runs_gte_uint8
from math import log, log10, e
import numpy as np

def float_equality(a,b):
    return abs(a-b) < 1e-15

def test_mode():
    a = [0,1,1,1,0,0,0,0]
    assert mode(a) == 0
    b = [1,2,3,1,2,1]
    assert mode(b) == 1

    assert_raises(IndexError, mode, []) 
def test_issorted():
    assert is_sorted([]) 
    assert is_sorted([1])

    assert is_sorted([1,2])
    assert not is_sorted([2,1])
    assert is_sorted([1,1,1,1])

def test_count():
    assert count(1, [0,0,0,1,1,1,0,0,0]) == 3
    assert count(1, [0]*10) == 0
    assert count('a', 'abba') == 2
    assert count(1, []) == 0
    
def test_product():
    assert product([1,2,3,4,5]) == 120
    assert product([0,1,2,3,4]) ==  0
    assert product([]) == 1


# Path: pydigree/common.py
# def product(iter):
#     """
#     Reduces an iterable by multiplication. Analogous to sum, but with
#     multiplication instead of addition.
# 
#     :returns: overall product
#     :rtype: numeric
#     """
#     # This should really be a python builtiin
#     if not iter:
#         # sum([]) returns 0, so this will return 1
#         return 1
#     return reduce(multiply, iter)
# 
# def cumsum(iter):
#     """
#     Cumulative sum:
#     >>> pydigree.cumsum([0,1,2,3,4])
#     [0, 1, 3, 6, 10]
#     
# 
#     :param iter: the iterable to be cumsum'ed
#     
#     Returns: cumulative sums
#     :rtype: integer
#     """
#     if not iter:
#         return []
#     value = 0
#     g = [None] * len(iter)
#     for idx, x in enumerate(iter):
#         value += x
#         g[idx] = value
#     return g
# 
# def flatten(x):
#     """
#     Recursively flattens lists.
#     """
#     try:
#         it = iter(x)
#     except TypeError:
#         yield x
#     else:
#         for i in it:
#             for j in flatten(i):
#                 yield j
# 
# def invert_dict(d):
#     """
#     Makes the keys the values and the values the keys
#     
#     .. warning:: 
#         No guarantee of dictionary structure if mappings are not unique
#     
#     :param d: dictionary to be inverted
# 
#     :rtype: dict
#     """
#     return dict((y, x) for x, y in d.items())
# 
# def merge_dicts(*args):
#     ''' Merges two dictionaries into one bigger one '''
#     odict = {}
#     for d in args:
#         odict.update(d)
#     return odict
# 
# Path: pydigree/common.py
# def count(val, iterable):
#     """ 
#     Counts how many times a value (val) occurs in an iterable, excluding `None`
# 
#     
#     :param val: The value to be counted
#     :param iterable: values to be counted over
#     :type iterable: iterable  
# 
#     :return: the count of values
#     :rtype: int
#     """
#     return sum(1 for x in (y for y in iterable if y is not None) if val == x)
# 
# def grouper(iterable, n, fillvalue=None):
#     """
#     Collect data into fixed-length chunks or blocks
#     :param iterable: values to evaluate
#     :param n: size of the groups
#     :param fillvalue: Value to pad the last group with if len(iterable) % n != 0
#     
#     :type n: integer
#     :rtype: a generator
#     """
#     
#     # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
#     args = [iter(iterable)] * n
#     return zip_longest(fillvalue=fillvalue, *args)
# 
# def log_base_change(value, old, new):
#     ''' 
#     Changes the base of the logarithm used on `value` from `old` to `new`
# 
#     Arguments: 
#     value: the value to be converted
#     old: old base (numeric)
#     new: new base (numeric)
# 
#     :returns: log of value in new base  
#     :rtype: float
#     '''
#     return value / log(old, new) 
# 
# def mode(seq):
#     """ 
#     Returns the most common value in a sequence 
# 
#     :param seq: sequence of values to evaluate
#     """
# 
#     if not len(seq):
#         raise IndexError('Sequence is empty')
#     tab = table(seq)
#     return sorted(tab.items(), key=lambda x: x[1], reverse=True)[0][0]
# 
# Path: pydigree/common.py
# def count(val, iterable):
# def table(seq):
# def mode(seq):
# def random_choice(iterable):
# def flatten(x):
# def grouper(iterable, n, fillvalue=None):
# def invert_dict(d):
# def merge_dicts(*args):
# def log_base_change(value, old, new):
# def product(iter):
# def cumsum(iter):


# Path: tests/test_common.py
from nose.tools import assert_raises
from pydigree.common import product, cumsum, flatten, invert_dict, merge_dicts
from pydigree.common import count, grouper, log_base_change, mode
from pydigree.common import runs, runs_gte, interleave, is_sorted
from pydigree.cydigree.cyfuncs import runs_gte_uint8
from math import log, log10, e
import numpy as np


def float_equality(a,b):
    return abs(a-b) < 1e-15

def test_mode():
    a = [0,1,1,1,0,0,0,0]
    assert mode(a) == 0
    b = [1,2,3,1,2,1]
    assert mode(b) == 1

    assert_raises(IndexError, mode, []) 
def test_issorted():
    assert is_sorted([]) 
    assert is_sorted([1])

    assert is_sorted([1,2])
    assert not is_sorted([2,1])
    assert is_sorted([1,1,1,1])

def test_count():
    assert count(1, [0,0,0,1,1,1,0,0,0]) == 3
    assert count(1, [0]*10) == 0
    assert count('a', 'abba') == 2
    assert count(1, []) == 0
    
def test_product():
    assert product([1,2,3,4,5]) == 120
    assert product([0,1,2,3,4]) ==  0
    assert product([]) == 1


def test_cumsums():