# Path: veidt/abstract.py
# class Describer(BaseEstimator, MSONable, TransformerMixin):
#     """
#     Base class for a Describer, i.e., something that converts an object to a
#     describer, typically a numerical representation useful for machine
#     learning.
#     """
# 
#     def fit(self, objs, targets=None):
#         """Fit the describer.
#         In the case that the describer relies on parameters calculated from training data,
#         this method should be rewritten to store the fitted parameters
#         """
#         return self
# 
#     def transform(self, objs):
#         """Transform the input objects"""
#         return self.describe_all(objs).values
# 
#     @abc.abstractmethod
#     def describe(self, obj):
#         """
#         Converts an obj to a descriptor vector.
# 
#         :param obj: Object
#         :return: Descriptor for a structure. Recommended format is a pandas
#             Dataframe object with the column names as intuitive names.
#             For example, a simple site describer of the fractional coordinates
#             (this is usually a bad describer, so it is just for illustration
#             purposes) can be generated as::
# 
#                 print(pd.DataFrame(s.frac_coords, columns=["a", "b", "c"]))
#                           a         b         c
#                 0  0.000000  0.000000  0.000000
#                 1  0.750178  0.750178  0.750178
#                 2  0.249822  0.249822  0.249822
# 
#             Pandas dataframes can be dumped to a variety of formats (json, csv,
#             etc.) easily. Note that a dataframe should be used even if you have
#             only one line, i.e., do not use Series objects unless you know
#             what you are doing.
#         """
#         pass
# 
#     def describe_all(self, objs):
#         """
#         Convenience method to convert a list of objects to a list of
#         descriptors. Default implementation simply loops a call to describe, but
#         in some instances, a batch implementation may be more efficient.
# 
#         :param objs: List of objects
# 
#         :return: Concatenated descriptors for all objects. Recommended format
#             is a pandas DataFrame. Default implement returns a list of
#             descriptors generated by a loop call to describe for each obj.
#         """
#         return pd.concat([self.describe(o) for o in objs])
# 
# class Model(BaseEstimator, MSONable):
#     """
#     Abstract Base class for a Model. Basically, it usually wraps around a deep
#     learning package, e.g., the Sequential Model in Keras, but provides for
#     transparent conversion of arbitrary input and outputs.
#     """
# 
#     @abc.abstractmethod
#     def fit(self, features, targets, **kwargs):
#         """
# 
#         :param features: Numerical input feature list or numpy array with dim (m, n)
#             where m is the number of data and n is the feature dimension
#         :param targets: Numerical output target list, or numpy array with dim (m, )
#         """
#         pass
# 
#     @abc.abstractmethod
#     def predict(self, features):
#         """
#         Predict the values given a set of inputs based on fitted model.
# 
#         :param features: List of input features
# 
#         :return: List of output objects
#         """
#         pass
# 
#     def evaluate(self, features, targets, metrics=['mae'], multi_targets=False):
#         """
#         evaluate the performance of model based on metric.
#         :return: dict of metric evaluations
#         """
#         pred_targets = self.predict(features)
#         evaluation = {}
#         if not multi_targets:
#             targets = [targets]
#             pred_targets = [pred_targets]
#         for metric in metrics:
#             veidt_metric = get(metric)
#             evaluation[metric] = [veidt_metric(np.array(target).ravel(), np.array(pred_target).ravel()) for
#                                   target, pred_target in zip(targets, pred_targets)]
#         return evaluation


import unittest
import numpy as np
import os
import pandas as pd
from veidt.abstract import Describer, Model
from sklearn.linear_model import LinearRegression

file_path = os.path.dirname(__file__)


class DummyDescriber(Describer):
    def describe(self, obj):
        return pd.Series(np.sum(obj))



# Path: veidt/abstract.py
# class Describer(BaseEstimator, MSONable, TransformerMixin):
#     """
#     Base class for a Describer, i.e., something that converts an object to a
#     describer, typically a numerical representation useful for machine
#     learning.
#     """
# 
#     def fit(self, objs, targets=None):
#         """Fit the describer.
#         In the case that the describer relies on parameters calculated from training data,
#         this method should be rewritten to store the fitted parameters
#         """
#         return self
# 
#     def transform(self, objs):
#         """Transform the input objects"""
#         return self.describe_all(objs).values
# 
#     @abc.abstractmethod
#     def describe(self, obj):
#         """
#         Converts an obj to a descriptor vector.
# 
#         :param obj: Object
#         :return: Descriptor for a structure. Recommended format is a pandas
#             Dataframe object with the column names as intuitive names.
#             For example, a simple site describer of the fractional coordinates
#             (this is usually a bad describer, so it is just for illustration
#             purposes) can be generated as::
# 
#                 print(pd.DataFrame(s.frac_coords, columns=["a", "b", "c"]))
#                           a         b         c
#                 0  0.000000  0.000000  0.000000
#                 1  0.750178  0.750178  0.750178
#                 2  0.249822  0.249822  0.249822
# 
#             Pandas dataframes can be dumped to a variety of formats (json, csv,
#             etc.) easily. Note that a dataframe should be used even if you have
#             only one line, i.e., do not use Series objects unless you know
#             what you are doing.
#         """
#         pass
# 
#     def describe_all(self, objs):
#         """
#         Convenience method to convert a list of objects to a list of
#         descriptors. Default implementation simply loops a call to describe, but
#         in some instances, a batch implementation may be more efficient.
# 
#         :param objs: List of objects
# 
#         :return: Concatenated descriptors for all objects. Recommended format
#             is a pandas DataFrame. Default implement returns a list of
#             descriptors generated by a loop call to describe for each obj.
#         """
#         return pd.concat([self.describe(o) for o in objs])
# 
# class Model(BaseEstimator, MSONable):
#     """
#     Abstract Base class for a Model. Basically, it usually wraps around a deep
#     learning package, e.g., the Sequential Model in Keras, but provides for
#     transparent conversion of arbitrary input and outputs.
#     """
# 
#     @abc.abstractmethod
#     def fit(self, features, targets, **kwargs):
#         """
# 
#         :param features: Numerical input feature list or numpy array with dim (m, n)
#             where m is the number of data and n is the feature dimension
#         :param targets: Numerical output target list, or numpy array with dim (m, )
#         """
#         pass
# 
#     @abc.abstractmethod
#     def predict(self, features):
#         """
#         Predict the values given a set of inputs based on fitted model.
# 
#         :param features: List of input features
# 
#         :return: List of output objects
#         """
#         pass
# 
#     def evaluate(self, features, targets, metrics=['mae'], multi_targets=False):
#         """
#         evaluate the performance of model based on metric.
#         :return: dict of metric evaluations
#         """
#         pred_targets = self.predict(features)
#         evaluation = {}
#         if not multi_targets:
#             targets = [targets]
#             pred_targets = [pred_targets]
#         for metric in metrics:
#             veidt_metric = get(metric)
#             evaluation[metric] = [veidt_metric(np.array(target).ravel(), np.array(pred_target).ravel()) for
#                                   target, pred_target in zip(targets, pred_targets)]
#         return evaluation


# Path: veidt/tests/test_abstract.py
import unittest
import numpy as np
import os
import pandas as pd
from veidt.abstract import Describer, Model
from sklearn.linear_model import LinearRegression


file_path = os.path.dirname(__file__)


class DummyDescriber(Describer):
    def describe(self, obj):
        return pd.Series(np.sum(obj))



class DummyModel(Model):