## Libraries
# General purpose libraries
import pandas as pd
import numpy as np
import pickle

## Files
#################################################################################
# The symbol "example_code.py ->" indicates that the file(s) is (are)           #
# generated from example_code.py.                                               #
# The symbol "-> example_code1.py,example_code2.py" indicates that the file(s)  #
# is (are) read and thus required by both example_code1.py and example_code2.py.#
# The symbol "example_code1.py -> example_code2.py" indicates that the file(s)  #
# is (are) generated by example_code1.py and read by example_code2.py.          #
#################################################################################
# Raw training data files (-> feature_extraction.py)
train_file = 'train_features.csv'
test_file = 'test_features.csv'
# Raw training labels file (-> feature_selection.py, train_classifier.py, train_regressor.py)
train_labels_file = 'train_labels.csv'
# Featured data (feature_extraction.py -> feature_selection.py)
test_features_files = ['test_features_clf.csv', 'test_features_rgr.csv']
train_features_files = ['train_features_clf.csv', 'train_features_rgr.csv']
# Selected features for label (feature_selection.py -> train_classifier.py, train_regressor.py, predict.py)
train_features_sel_file = 'train_features_sel.sav'
# Scaler of regression features (feature_selection.py -> train_classifier.py, train_regressor.py, predict.py)
rgr_scaler_ftr_file = 'rgr_scaler_ftr.sav'
# Scaler of regression labels (feature_selection.py -> predict.py)
rgr_scalers_lbl_file = 'rgr_scalers_lbl.sav'
# Models generated (train_classifier.py,train_regressor.py -> redict.py)
trained_models = ['classifiers_list.sav', 'regressors_list.sav']
# Prediction file (predict.py ->)
prediction_file = 'prediction.csv'
# Prediction archive (predict.py ->)
prediction_archive = 'prediction.zip'

## Random seed
# Initialize random seed
seed = 528

## Classes
# Classifier wrapper
class MedClassifierWrapper:
    def __init__(self, label, clf, cross_validation_score=-1, clf_params=None):
        self.label_ = label
        self.clf_ = clf
        self.cv_score_ = cross_validation_score
        self.clf_params_ = clf_params

# Regressor wrapper
class MedRegressorWrapper:
    def __init__(self, label, best_estimator, best_params, best_score):
        self.label_ = label
        self.best_estimator_ = best_estimator
        self.best_score_ = best_score
        self.best_params_ = best_params

## Functions
# Load trained model
def get_model(filename):
    model = pickle.load(open(filename, 'rb'))
    return model

# Compute nth moment from data
def nth_moment(n):
    # Unbiased 2nd order moment
    def nanstd(x):
        std = np.nanstd(x)
        if std == 0:
            return np.nan
        return std

    if n == 1:
        return np.nanmean
    elif n == 2:
        return nanstd

def last_first_diff(x):
    first = x.first_valid_index()
    last = x.last_valid_index()
    if first == None or first == last:
        return np.nan
    else:
        return x[last] - x[first]

def last_first_slope(x):
    first = x.first_valid_index()
    last = x.last_valid_index()
    if first == None or first == last:
        return np.nan
    else:
        return (x[last] - x[first]) / (last - first)
