# Path: tde/util/functions.py
# def iterator_length(iterable):
# def unique(iterable):
# def unique_by(iterable, key):
# def intersection(iterable1, iterable2):
# def intersection_by(iterable1, iterable2, key):
# def grouper(n, iterable, padvalue=None):
# def fname2speaker(corpus_type):
# def fscore(p, r):
# 
# Path: tde/substrings/acss.py
# def pairwise_substring_completion(fragment1, fragment2, corpus,
#                                   minlength, maxlength):
#     name1, name2 = fragment1.name, fragment2.name
#     tokenseq1 = [(f.mark, f.interval)
#                  for f in corpus.tokens(name1, fragment1.interval)]
#     tokenseq2 = [(f.mark, f.interval)
#                  for f in corpus.tokens(name2, fragment2.interval)]
# 
#     for seq1, seq2 in psubstrings(tokenseq1, tokenseq2, minlength, maxlength):
#         submark1, intervalseq1 = zip(*seq1)
#         submark2, intervalseq2 = zip(*seq2)
#         interval1 = Interval(intervalseq1[0].start, intervalseq1[-1].end)
#         interval2 = Interval(intervalseq2[0].start, intervalseq2[-1].end)
#         yield (FragmentToken(name1, interval1, submark1),
#                FragmentToken(name2, interval2, submark2))
# 
# Path: tde/data/classes.py
# class ClassDict(collections.Mapping):
#     """
#     Mapping representing the partitioning of a collection of FragmentTokens
#     into classes
# 
#     Parameters
#     ----------
#     clsdict : dict from ClassID to tuple of FragmentToken
# 
#     Methods
#     -------
#     iter_fragments(with_class=False)
#         Iterate over single FragmentTokens.
#     iter_pairs()
#         Iterate over pairs of FragmentTokens.
#     restrict()
#         Restrict to a collection of Intervals
# 
#     """
#     def __init__(self, clsdict):
#         self.clsdict = clsdict
# 
#     def __contains__(self, key):
#         return key in self.clsdict
# 
#     def __getitem__(self, key):
#         return self.clsdict[key]
# 
#     def __iter__(self):
#         return iter(self.clsdict)
# 
#     def __len__(self):
#         return len(self.clsdict)
# 
#     def __str__(self):
#         return str(self.clsdict)
# 
#     def __eq__(self, other):
#         return self.clsdict == other.clsdict
# 
#     def __ne__(self, other):
#         return not self.__eq__(other)
# 
#     def pretty(self):
#         return pformat(self.clsdict)
# 
#     def iter_fragments(self, with_class=False):
#         """
#         Iterate over FragmentTokens.
# 
#         Parameters
#         ----------
#         with_class : bool, optional
#             Iterate over (ClassID, FragmentToken) pairs instead
# 
#         Returns
#         -------
#         Iterator over FragmentToken or (ClassID, FragmentToken) pairs
# 
#         """
#         if with_class:
#             return unique(flatten(izip(repeat(c), v)
#                                   for c, v in self.clsdict.iteritems()))
#         else:
#             return unique(flatten(self.clsdict.itervalues()))
# 
#     def iter_pairs(self, within, order):
#         """
#         Iterate over FragmentToken pairs.
# 
#         Parameters
#         ----------
#         within : bool
#             Only select pairs from the same class.
#         order : bool
#             Also include reverse of a pair.
# 
#         Returns
#         -------
#         Iterator over (FragmentToken, FragmentToken) pairs.
# 
#         """
#         vals = self.clsdict.itervalues()
#         if within:
#             if order:
#                 pairs = flatten(((f1, f2), (f2, f1))
#                                 for fragments in vals
#                                 for f1, f2 in combinations(fragments, 2))
#             else:
#                 pairs = (tuple(sorted((f1, f2),
#                                       key=lambda f: (f.name, f.interval.start)))
#                          for fragments in vals
#                          for f1, f2 in combinations(fragments, 2))
#         else: # across classes
#             if order:
#                 pairs = (((f1, f2), (f2, f1))
#                          for f1, f2 in combinations(flatten(vals), 2))
#                 pairs = flatten(pairs)
#             else:
#                 pairs = (tuple(sorted((f1, f2),
#                                       key=lambda f: (f.name, f.interval.start)))
#                          for f1, f2 in combinations(flatten(vals), 2))
#         return unique(ifilterfalse(lambda f: f[0].interval.overlaps_with(f[1].interval),
#                                    pairs))
# 
#     def restrict(self, interval_db, remove_singletons=False):
#         """
#         Restrict the ClassDict to a set of Intervals.
# 
#         Returns a new ClassDict object with only the FragmentTokens
#         that are fully covered in `interval_db`.
# 
#         Parameters
#         ----------
#         interval_db : IntervalDB
#             Collection of Intervals
#         remove_singletons : bool
#             Remove classes with a single element
# 
#         Returns
#         -------
#         ClassDict
#             New ClassDict object restricted to the fragments in `interval_db`
# 
#         """
#         r = {}
#         for classID, fragments in self.clsdict.iteritems():
#             fs = [f for f in fragments
#                   if interval_db.is_covered(f.name, f.interval)]
#             if len(fs) == 0:
#                 pass
#             elif len(fs) == 1:
#                 if remove_singletons:
#                     pass
#                 else:
#                     r[classID] = tuple(fs)
#             else:
#                 r[classID] = tuple(fs)
#         return ClassDict(r)


from collections import Counter, defaultdict
from tde.util.functions import unique, iterator_length, flatten
from tde.substrings.acss import pairwise_substring_completion
from tde.data.classes import ClassDict
"""Set primitives.

"""
from __future__ import division



def typeset(pairs):
    """
    Yield the unique marks in a pair iterator.

    Parameters
    ----------
    pairs : Iterator over (FragmentToken, FragmentToken) pairs

    Returns
    -------
    Iterator over strings
        Unique marks.

    """

# Path: tde/util/functions.py
# def iterator_length(iterable):
# def unique(iterable):
# def unique_by(iterable, key):
# def intersection(iterable1, iterable2):
# def intersection_by(iterable1, iterable2, key):
# def grouper(n, iterable, padvalue=None):
# def fname2speaker(corpus_type):
# def fscore(p, r):
# 
# Path: tde/substrings/acss.py
# def pairwise_substring_completion(fragment1, fragment2, corpus,
#                                   minlength, maxlength):
#     name1, name2 = fragment1.name, fragment2.name
#     tokenseq1 = [(f.mark, f.interval)
#                  for f in corpus.tokens(name1, fragment1.interval)]
#     tokenseq2 = [(f.mark, f.interval)
#                  for f in corpus.tokens(name2, fragment2.interval)]
# 
#     for seq1, seq2 in psubstrings(tokenseq1, tokenseq2, minlength, maxlength):
#         submark1, intervalseq1 = zip(*seq1)
#         submark2, intervalseq2 = zip(*seq2)
#         interval1 = Interval(intervalseq1[0].start, intervalseq1[-1].end)
#         interval2 = Interval(intervalseq2[0].start, intervalseq2[-1].end)
#         yield (FragmentToken(name1, interval1, submark1),
#                FragmentToken(name2, interval2, submark2))
# 
# Path: tde/data/classes.py
# class ClassDict(collections.Mapping):
#     """
#     Mapping representing the partitioning of a collection of FragmentTokens
#     into classes
# 
#     Parameters
#     ----------
#     clsdict : dict from ClassID to tuple of FragmentToken
# 
#     Methods
#     -------
#     iter_fragments(with_class=False)
#         Iterate over single FragmentTokens.
#     iter_pairs()
#         Iterate over pairs of FragmentTokens.
#     restrict()
#         Restrict to a collection of Intervals
# 
#     """
#     def __init__(self, clsdict):
#         self.clsdict = clsdict
# 
#     def __contains__(self, key):
#         return key in self.clsdict
# 
#     def __getitem__(self, key):
#         return self.clsdict[key]
# 
#     def __iter__(self):
#         return iter(self.clsdict)
# 
#     def __len__(self):
#         return len(self.clsdict)
# 
#     def __str__(self):
#         return str(self.clsdict)
# 
#     def __eq__(self, other):
#         return self.clsdict == other.clsdict
# 
#     def __ne__(self, other):
#         return not self.__eq__(other)
# 
#     def pretty(self):
#         return pformat(self.clsdict)
# 
#     def iter_fragments(self, with_class=False):
#         """
#         Iterate over FragmentTokens.
# 
#         Parameters
#         ----------
#         with_class : bool, optional
#             Iterate over (ClassID, FragmentToken) pairs instead
# 
#         Returns
#         -------
#         Iterator over FragmentToken or (ClassID, FragmentToken) pairs
# 
#         """
#         if with_class:
#             return unique(flatten(izip(repeat(c), v)
#                                   for c, v in self.clsdict.iteritems()))
#         else:
#             return unique(flatten(self.clsdict.itervalues()))
# 
#     def iter_pairs(self, within, order):
#         """
#         Iterate over FragmentToken pairs.
# 
#         Parameters
#         ----------
#         within : bool
#             Only select pairs from the same class.
#         order : bool
#             Also include reverse of a pair.
# 
#         Returns
#         -------
#         Iterator over (FragmentToken, FragmentToken) pairs.
# 
#         """
#         vals = self.clsdict.itervalues()
#         if within:
#             if order:
#                 pairs = flatten(((f1, f2), (f2, f1))
#                                 for fragments in vals
#                                 for f1, f2 in combinations(fragments, 2))
#             else:
#                 pairs = (tuple(sorted((f1, f2),
#                                       key=lambda f: (f.name, f.interval.start)))
#                          for fragments in vals
#                          for f1, f2 in combinations(fragments, 2))
#         else: # across classes
#             if order:
#                 pairs = (((f1, f2), (f2, f1))
#                          for f1, f2 in combinations(flatten(vals), 2))
#                 pairs = flatten(pairs)
#             else:
#                 pairs = (tuple(sorted((f1, f2),
#                                       key=lambda f: (f.name, f.interval.start)))
#                          for f1, f2 in combinations(flatten(vals), 2))
#         return unique(ifilterfalse(lambda f: f[0].interval.overlaps_with(f[1].interval),
#                                    pairs))
# 
#     def restrict(self, interval_db, remove_singletons=False):
#         """
#         Restrict the ClassDict to a set of Intervals.
# 
#         Returns a new ClassDict object with only the FragmentTokens
#         that are fully covered in `interval_db`.
# 
#         Parameters
#         ----------
#         interval_db : IntervalDB
#             Collection of Intervals
#         remove_singletons : bool
#             Remove classes with a single element
# 
#         Returns
#         -------
#         ClassDict
#             New ClassDict object restricted to the fragments in `interval_db`
# 
#         """
#         r = {}
#         for classID, fragments in self.clsdict.iteritems():
#             fs = [f for f in fragments
#                   if interval_db.is_covered(f.name, f.interval)]
#             if len(fs) == 0:
#                 pass
#             elif len(fs) == 1:
#                 if remove_singletons:
#                     pass
#                 else:
#                     r[classID] = tuple(fs)
#             else:
#                 r[classID] = tuple(fs)
#         return ClassDict(r)


# Path: tde/data/sets.py
from collections import Counter, defaultdict
from tde.util.functions import unique, iterator_length, flatten
from tde.substrings.acss import pairwise_substring_completion
from tde.data.classes import ClassDict

"""Set primitives.

"""
from __future__ import division



def typeset(pairs):
    """
    Yield the unique marks in a pair iterator.

    Parameters
    ----------
    pairs : Iterator over (FragmentToken, FragmentToken) pairs

    Returns
    -------
    Iterator over strings
        Unique marks.

    """

    return unique(f.mark for f in flatten(pairs))