# Path: wallace/dataset.py
# class Dataset(object):
# class DatasetVariable(object):
#     def __init__(self, data_matrix, headers=None, data_types=None):
#     def get(self, row, col):
#     def get_with_header(self, row, header):
#     def get_independent_variables(self, dependent_variable):
#     def column_index(self, header):
#     def get_column(self, col):
#     def get_filtered_data_types(self, variables):
#     def get_filtered_matrix(self, variables):
#     def get_filtered_column(self, variable):
#     def get_column_with_header(self, header):
#     def get_row(self, row):
#     def crossfold_partitions(self, num_partitions=10):
#     def _initialize_data_types(self, data_types):
#     def _variable_indices(self, variables):
#     def _check_headers(self):
#     def __init__(self, variable):
#     def get_column_index(self, dataset):


from wallace import dataset
from datetime import datetime
import logging

class FitnessEvaluation(object):
    def __init__(self, settings, model, dataset):
        self.settings = settings
        self.model = model
        self.dataset = dataset

    def evaluate(self, evaluation_method):
        raise NotImplementedError()

class CrossValidationFitnessEvaluation(FitnessEvaluation):
    def __init__(self, settings, model, dataset):
        FitnessEvaluation.__init__(self, settings, model, dataset)
        self.logger = logging.getLogger(__name__)

    def evaluate(self, evaluation_method):
        num_partitions = self.settings.get("fitness_evaluation.crossfold_partitions")
        averaged_fitness = 0
        for training_dataset, test_dataset in self.dataset.crossfold_partitions(num_partitions):
            start_training = datetime.now()
            trained_model = self.model.train(training_dataset)
            finished_training = datetime.now()
            self.logger.debug("Training model time %s", (finished_training - start_training).total_seconds())

            fitness = trained_model.predict_and_evaluate_fitness(test_dataset, evaluation_method)
            finished_evaluating_fitness = datetime.now()
            self.logger.debug("Fitness evaluation time %s", (finished_evaluating_fitness - finished_training).total_seconds())

            self.logger.debug("Crossfold partition fitness for model %s: %s", self.model, fitness)
            averaged_fitness += (float(test_dataset.num_rows) / (test_dataset.num_rows + training_dataset.num_rows)) * fitness

# Path: wallace/dataset.py
# class Dataset(object):
# class DatasetVariable(object):
#     def __init__(self, data_matrix, headers=None, data_types=None):
#     def get(self, row, col):
#     def get_with_header(self, row, header):
#     def get_independent_variables(self, dependent_variable):
#     def column_index(self, header):
#     def get_column(self, col):
#     def get_filtered_data_types(self, variables):
#     def get_filtered_matrix(self, variables):
#     def get_filtered_column(self, variable):
#     def get_column_with_header(self, header):
#     def get_row(self, row):
#     def crossfold_partitions(self, num_partitions=10):
#     def _initialize_data_types(self, data_types):
#     def _variable_indices(self, variables):
#     def _check_headers(self):
#     def __init__(self, variable):
#     def get_column_index(self, dataset):


# Path: wallace/fitness_evaluation.py
from wallace import dataset
from datetime import datetime
import logging


class FitnessEvaluation(object):
    def __init__(self, settings, model, dataset):
        self.settings = settings
        self.model = model
        self.dataset = dataset

    def evaluate(self, evaluation_method):
        raise NotImplementedError()

class CrossValidationFitnessEvaluation(FitnessEvaluation):
    def __init__(self, settings, model, dataset):
        FitnessEvaluation.__init__(self, settings, model, dataset)
        self.logger = logging.getLogger(__name__)

    def evaluate(self, evaluation_method):
        num_partitions = self.settings.get("fitness_evaluation.crossfold_partitions")
        averaged_fitness = 0
        for training_dataset, test_dataset in self.dataset.crossfold_partitions(num_partitions):
            start_training = datetime.now()
            trained_model = self.model.train(training_dataset)
            finished_training = datetime.now()
            self.logger.debug("Training model time %s", (finished_training - start_training).total_seconds())

            fitness = trained_model.predict_and_evaluate_fitness(test_dataset, evaluation_method)
            finished_evaluating_fitness = datetime.now()
            self.logger.debug("Fitness evaluation time %s", (finished_evaluating_fitness - finished_training).total_seconds())

            self.logger.debug("Crossfold partition fitness for model %s: %s", self.model, fitness)
            averaged_fitness += (float(test_dataset.num_rows) / (test_dataset.num_rows + training_dataset.num_rows)) * fitness

        return averaged_fitness