# Path: concept_formation/utils.py
# def mean(values):
#     """
#     Computes the mean of a list of values.
# 
#     This is primarily included to reduce dependency on external math libraries
#     like numpy in the core algorithm.
# 
#     :param values: a list of numbers
#     :type values: list
#     :return: the mean of the list of values
#     :rtype: float
# 
#     >>> mean([600, 470, 170, 430, 300])
#     394.0
#     """
#     if len(values) <= 0:
#         raise ValueError("Length of list must be greater than 0.")
# 
#     return float(sum(values))/len(values)
# 
# Path: concept_formation/utils.py
# def isNumber(n):
#     """
#     Check if a value is a number that should be handled differently than
#     nominals.
#     """
#     return (not isinstance(n, bool) and isinstance(n, Number)) and not isnan(n)
# 
# Path: concept_formation/structure_mapper.py
# class StructureMapper(Preprocessor):
#     """
#     Structure maps an instance that has been appropriately preprocessed (i.e.,
#     standardized apart, flattened, subcomponent processed, and lists processed
#     out). Transform renames the instance based on this structure mapping, and
#     return the renamed instance.
# 
#     :param base: A concept to structure map the instance to
#     :type base: TrestleNode
#     :param gensym: a function that returns unique object names (str) on each
#         call
#     :type gensym: function
#     :return: A flattened and mapped copy of the instance
#     :rtype: instance
#     """
#     def __init__(self, base):
#         self.base = base
#         self.mapping = None
#         self.reverse_mapping = None
# 
#     def get_mapping(self):
#         """
#         Returns the currently established mapping.
# 
#         :return: The current mapping.
#         :rtype: dict
#         """
#         return {self.reverse_mapping[o]: o for o in self.reverse_mapping}
# 
#     def transform(self, target, initial_mapping=None):
#         """
#         Transforms a provided target (either an instance or an av_counts table
#         from a CobwebNode or Cobweb3Node).
# 
#         :param target: An instance or av_counts table to rename to bring into
#             alignment with the provided base.
#         :type target: instance or av_counts table (from CobwebNode or
#             Cobweb3Node).
#         :return: The renamed instance or av_counts table
#         :rtype: instance or av_counts table
#         """
#         self.mapping = flat_match(target, self.base, initial_mapping)
#         self.reverse_mapping = {self.mapping[o]: o for o in self.mapping}
#         return rename_flat(target, self.mapping)
# 
#     def undo_transform(self, target):
#         """
#         Takes a transformed target and reverses the structure mapping using the
#         mapping discovered by transform.
# 
#         :param target: A previously renamed instance or av_counts table to
#             reverse the structure mapping on.
#         :type target: previously structure mapped instance or av_counts table
#             (from CobwebNode or Cobweb3Node).
#         :return: An instance or concept av_counts table with original object
#             names
#         :rtype: dict
#         """
#         if self.reverse_mapping is None:
#             raise Exception("Must transform before undoing transform")
#         return rename_flat(target, self.reverse_mapping)


from random import shuffle
from re import search
from concept_formation.utils import mean
from concept_formation.utils import isNumber
from concept_formation.structure_mapper import StructureMapper

    If the instance currently contains the target attribute a shallow copy is
    created to allow the attribute to be predicted.

    .. warning:: This is an older function in the library and we are not quite
        sure how to set it up for component values under the new
        representation and so for the time being it will raise an Exception if
        it encounts a component.

    :param tree: A category tree to evaluate.
    :type tree: :class:`CobwebTree <concept_formation.cobweb.CobwebTree>`,
        :class:`Cobweb3Tree <concept_formation.cobweb3.Cobweb3Tree>`, or
        :class:`TrestleTree <concept_formation.trestle.TrestleTree>`
    :param instance: An instance to use query the tree with
    :type instance: {a1:v1, a2:v2, ...}
    :param attr: A target instance attribute to evaluate probability on
    :type attr: :ref:`Attribute<attributes>`
    :param val: The target value of the given attr
    :type val: A :ref:`Nominal<val-nom>` or :ref:`Numeric<val-num>` value.
    :returns: The probabily of the given instance attribute value in the given
        tree
    :rtype: float
    """
    if attr in instance:
        instance = {a: instance[a] for a in instance if not a == attr}
    concept = tree.categorize(instance)

    if isinstance(val, dict):
        raise Exception(
            "Probability cannot be estimated on component attributes!")

# Path: concept_formation/utils.py
# def mean(values):
#     """
#     Computes the mean of a list of values.
# 
#     This is primarily included to reduce dependency on external math libraries
#     like numpy in the core algorithm.
# 
#     :param values: a list of numbers
#     :type values: list
#     :return: the mean of the list of values
#     :rtype: float
# 
#     >>> mean([600, 470, 170, 430, 300])
#     394.0
#     """
#     if len(values) <= 0:
#         raise ValueError("Length of list must be greater than 0.")
# 
#     return float(sum(values))/len(values)
# 
# Path: concept_formation/utils.py
# def isNumber(n):
#     """
#     Check if a value is a number that should be handled differently than
#     nominals.
#     """
#     return (not isinstance(n, bool) and isinstance(n, Number)) and not isnan(n)
# 
# Path: concept_formation/structure_mapper.py
# class StructureMapper(Preprocessor):
#     """
#     Structure maps an instance that has been appropriately preprocessed (i.e.,
#     standardized apart, flattened, subcomponent processed, and lists processed
#     out). Transform renames the instance based on this structure mapping, and
#     return the renamed instance.
# 
#     :param base: A concept to structure map the instance to
#     :type base: TrestleNode
#     :param gensym: a function that returns unique object names (str) on each
#         call
#     :type gensym: function
#     :return: A flattened and mapped copy of the instance
#     :rtype: instance
#     """
#     def __init__(self, base):
#         self.base = base
#         self.mapping = None
#         self.reverse_mapping = None
# 
#     def get_mapping(self):
#         """
#         Returns the currently established mapping.
# 
#         :return: The current mapping.
#         :rtype: dict
#         """
#         return {self.reverse_mapping[o]: o for o in self.reverse_mapping}
# 
#     def transform(self, target, initial_mapping=None):
#         """
#         Transforms a provided target (either an instance or an av_counts table
#         from a CobwebNode or Cobweb3Node).
# 
#         :param target: An instance or av_counts table to rename to bring into
#             alignment with the provided base.
#         :type target: instance or av_counts table (from CobwebNode or
#             Cobweb3Node).
#         :return: The renamed instance or av_counts table
#         :rtype: instance or av_counts table
#         """
#         self.mapping = flat_match(target, self.base, initial_mapping)
#         self.reverse_mapping = {self.mapping[o]: o for o in self.mapping}
#         return rename_flat(target, self.mapping)
# 
#     def undo_transform(self, target):
#         """
#         Takes a transformed target and reverses the structure mapping using the
#         mapping discovered by transform.
# 
#         :param target: A previously renamed instance or av_counts table to
#             reverse the structure mapping on.
#         :type target: previously structure mapped instance or av_counts table
#             (from CobwebNode or Cobweb3Node).
#         :return: An instance or concept av_counts table with original object
#             names
#         :rtype: dict
#         """
#         if self.reverse_mapping is None:
#             raise Exception("Must transform before undoing transform")
#         return rename_flat(target, self.reverse_mapping)


# Path: concept_formation/evaluation.py
from random import shuffle
from re import search
from concept_formation.utils import mean
from concept_formation.utils import isNumber
from concept_formation.structure_mapper import StructureMapper


    If the instance currently contains the target attribute a shallow copy is
    created to allow the attribute to be predicted.

    .. warning:: This is an older function in the library and we are not quite
        sure how to set it up for component values under the new
        representation and so for the time being it will raise an Exception if
        it encounts a component.

    :param tree: A category tree to evaluate.
    :type tree: :class:`CobwebTree <concept_formation.cobweb.CobwebTree>`,
        :class:`Cobweb3Tree <concept_formation.cobweb3.Cobweb3Tree>`, or
        :class:`TrestleTree <concept_formation.trestle.TrestleTree>`
    :param instance: An instance to use query the tree with
    :type instance: {a1:v1, a2:v2, ...}
    :param attr: A target instance attribute to evaluate probability on
    :type attr: :ref:`Attribute<attributes>`
    :param val: The target value of the given attr
    :type val: A :ref:`Nominal<val-nom>` or :ref:`Numeric<val-num>` value.
    :returns: The probabily of the given instance attribute value in the given
        tree
    :rtype: float
    """
    if attr in instance:
        instance = {a: instance[a] for a in instance if not a == attr}
    concept = tree.categorize(instance)

    if isinstance(val, dict):
        raise Exception(
            "Probability cannot be estimated on component attributes!")

        structure_mapper = StructureMapper(concept)