# Path: mimicus/tools/featureedit.py
# class FeatureDescriptor(object):
#     '''
#     A class containing descriptions of PDFrate features. 
#     '''
#     
#     @staticmethod
#     def get_feature_count():
#         return 135
#     
#     @staticmethod
#     def get_feature_name(i):
#         '''
#         Returns the i-th feature name. 
#         '''
#         return copy.copy(_pdfrate_feature_names[i])
#     
#     @staticmethod
#     def get_feature_names():
#         '''
#         Returns a sorted list of feature names. 
#         '''
#         return copy.copy(_pdfrate_feature_names)
#     
#     @staticmethod
#     def get_feature_description(feat):
#         '''
#         Returns the description of the given feature as defined by the 
#         FeatureDescriptor.get_feature_descriptions() method. 
#         
#         feat - name or index of the feature
#         '''
#         feat_name = FeatureDescriptor.get_feature_names()[feat] if type(feat) == int else feat
#         return copy.copy(_pdfrate_feature_descriptions[feat_name])
#     
#     @staticmethod
#     def get_feature_descriptions():
#         '''
#         For every feature, a dictionary is returned describing that feature:
#         its type ('type'), whether it may be altered or not ('edit', with the 
#         values 'y' if altering is implemented, 'n' if it's impossible to 
#         alter and 'm' if altering is not directly implemented, but the 
#         feature value might change by modifying some other features) and 
#         the range ('range') within which it may be altered as a tuple of 
#         lower and upper bound (FileDefined means that this lower or upper 
#         bound cannot be modified further than what is currently in the file). 
#         The range represents actual minimum and maximum values seen in the 
#         Contagio dataset. 
#         '''
#         return copy.copy(_pdfrate_feature_descriptions)
# 
#     @staticmethod
#     def get_feature_mask_numpy():
#         '''
#         Returns a numpy array with 1 for every feature which is modifiable, 
#         otherwise 0. 
#         '''
#         return numpy.array([1 if _pdfrate_feature_descriptions[name]['edit'] == 'y' else 0 for name in _pdfrate_feature_names])
# 
# Path: mimicus/tools/datasets.py
# def csv2numpy(csv_in):
#     '''
#     Parses a CSV input file and returns a tuple (X, y) with 
#     training vectors (numpy.array) and labels (numpy.array), respectfully. 
#     
#     csv_in - name of a CSV file with training data points; 
#                 the first column in the file is supposed to be named 
#                 'class' and should contain the class label for the data 
#                 points; the second column of this file will be ignored 
#                 (put data point ID here). 
#     '''
#     # Parse CSV file
#     csv_rows = list(csv.reader(open(csv_in, 'rb')))
#     classes = {'FALSE':0, 'TRUE':1}
#     rownum = 0
#     # Count exact number of data points
#     TOTAL_ROWS = 0
#     for row in csv_rows:
#         if row[0] in classes:
#             # Count line if it begins with a class label (boolean)
#             TOTAL_ROWS += 1
#     # X = vector of data points, y = label vector
#     X = numpy.array(numpy.zeros((TOTAL_ROWS, FeatureDescriptor.get_feature_count())), dtype=numpy.float64, order='C')
#     y = numpy.array(numpy.zeros(TOTAL_ROWS), dtype=numpy.float64, order='C')
#     file_names = []
#     for row in csv_rows:
#         # Skip line if it doesn't begin with a class label (boolean)
#         if row[0] not in classes:
#             continue
#         # Read class label from first row
#         y[rownum] = classes[row[0]]
#         featnum = 0
#         file_names.append(row[1])
#         for featval in row[2:]:
#             if featval in classes:
#                 # Convert booleans to integers
#                 featval = classes[featval]
#             X[rownum, featnum] = float(featval)
#             featnum += 1
#         rownum += 1
#     return X, y, file_names


from argparse import ArgumentParser
from matplotlib import pyplot
from mimicus.tools.featureedit import FeatureDescriptor
from mimicus.tools.datasets import csv2numpy
from sklearn.cross_validation import KFold
import multiprocessing
import random
import sys
import numpy
import common
import config
    ben_means, ben_devs = common.get_benign_mean_stddev(data, labels)
    mim_data, mim_labels = common.get_FTC_mimicry()
    TRIALS = 5
    nCV = 10
    subsets = [0, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1]
    
    pool = multiprocessing.Pool(processes=None)
    pool_args = [(data, labels, mim_data, mim_labels, ben_means, ben_devs, 
                  subset, TRIALS, nCV) for subset in subsets]
    print '\n     % {:>15}{:>15}{:>15}'.format('ORIGINAL', 
                                              'MIMICRY', 
                                              'OUR MIMICRY'),
    norm = TRIALS * nCV
    res = []
    for accs, subset in pool.imap(perturbate_CV_parallel, pool_args):
        print '\n{:>6.2f}'.format(subset * 100),
        for acc in accs: sys.stdout.write('{:>15.3f}'.format(acc / norm))
        res.append(tuple([acc / norm for acc in accs]))
    return res

def main():
    random.seed(0)
    parser = ArgumentParser()
    parser.add_argument('--plot', help='Where to save plot (file name)',
                        default=False)
    parser.add_argument('--show', help='Show plot in a window', default=False, 
                        action='store_true')
    args = parser.parse_args()
    
    print 'Loading training data from CSV...'

# Path: mimicus/tools/featureedit.py
# class FeatureDescriptor(object):
#     '''
#     A class containing descriptions of PDFrate features. 
#     '''
#     
#     @staticmethod
#     def get_feature_count():
#         return 135
#     
#     @staticmethod
#     def get_feature_name(i):
#         '''
#         Returns the i-th feature name. 
#         '''
#         return copy.copy(_pdfrate_feature_names[i])
#     
#     @staticmethod
#     def get_feature_names():
#         '''
#         Returns a sorted list of feature names. 
#         '''
#         return copy.copy(_pdfrate_feature_names)
#     
#     @staticmethod
#     def get_feature_description(feat):
#         '''
#         Returns the description of the given feature as defined by the 
#         FeatureDescriptor.get_feature_descriptions() method. 
#         
#         feat - name or index of the feature
#         '''
#         feat_name = FeatureDescriptor.get_feature_names()[feat] if type(feat) == int else feat
#         return copy.copy(_pdfrate_feature_descriptions[feat_name])
#     
#     @staticmethod
#     def get_feature_descriptions():
#         '''
#         For every feature, a dictionary is returned describing that feature:
#         its type ('type'), whether it may be altered or not ('edit', with the 
#         values 'y' if altering is implemented, 'n' if it's impossible to 
#         alter and 'm' if altering is not directly implemented, but the 
#         feature value might change by modifying some other features) and 
#         the range ('range') within which it may be altered as a tuple of 
#         lower and upper bound (FileDefined means that this lower or upper 
#         bound cannot be modified further than what is currently in the file). 
#         The range represents actual minimum and maximum values seen in the 
#         Contagio dataset. 
#         '''
#         return copy.copy(_pdfrate_feature_descriptions)
# 
#     @staticmethod
#     def get_feature_mask_numpy():
#         '''
#         Returns a numpy array with 1 for every feature which is modifiable, 
#         otherwise 0. 
#         '''
#         return numpy.array([1 if _pdfrate_feature_descriptions[name]['edit'] == 'y' else 0 for name in _pdfrate_feature_names])
# 
# Path: mimicus/tools/datasets.py
# def csv2numpy(csv_in):
#     '''
#     Parses a CSV input file and returns a tuple (X, y) with 
#     training vectors (numpy.array) and labels (numpy.array), respectfully. 
#     
#     csv_in - name of a CSV file with training data points; 
#                 the first column in the file is supposed to be named 
#                 'class' and should contain the class label for the data 
#                 points; the second column of this file will be ignored 
#                 (put data point ID here). 
#     '''
#     # Parse CSV file
#     csv_rows = list(csv.reader(open(csv_in, 'rb')))
#     classes = {'FALSE':0, 'TRUE':1}
#     rownum = 0
#     # Count exact number of data points
#     TOTAL_ROWS = 0
#     for row in csv_rows:
#         if row[0] in classes:
#             # Count line if it begins with a class label (boolean)
#             TOTAL_ROWS += 1
#     # X = vector of data points, y = label vector
#     X = numpy.array(numpy.zeros((TOTAL_ROWS, FeatureDescriptor.get_feature_count())), dtype=numpy.float64, order='C')
#     y = numpy.array(numpy.zeros(TOTAL_ROWS), dtype=numpy.float64, order='C')
#     file_names = []
#     for row in csv_rows:
#         # Skip line if it doesn't begin with a class label (boolean)
#         if row[0] not in classes:
#             continue
#         # Read class label from first row
#         y[rownum] = classes[row[0]]
#         featnum = 0
#         file_names.append(row[1])
#         for featval in row[2:]:
#             if featval in classes:
#                 # Convert booleans to integers
#                 featval = classes[featval]
#             X[rownum, featnum] = float(featval)
#             featnum += 1
#         rownum += 1
#     return X, y, file_names


# Path: reproduction/fig10.py
from argparse import ArgumentParser
from matplotlib import pyplot
from mimicus.tools.featureedit import FeatureDescriptor
from mimicus.tools.datasets import csv2numpy
from sklearn.cross_validation import KFold
import multiprocessing
import random
import sys
import numpy
import common
import config

    ben_means, ben_devs = common.get_benign_mean_stddev(data, labels)
    mim_data, mim_labels = common.get_FTC_mimicry()
    TRIALS = 5
    nCV = 10
    subsets = [0, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1]
    
    pool = multiprocessing.Pool(processes=None)
    pool_args = [(data, labels, mim_data, mim_labels, ben_means, ben_devs, 
                  subset, TRIALS, nCV) for subset in subsets]
    print '\n     % {:>15}{:>15}{:>15}'.format('ORIGINAL', 
                                              'MIMICRY', 
                                              'OUR MIMICRY'),
    norm = TRIALS * nCV
    res = []
    for accs, subset in pool.imap(perturbate_CV_parallel, pool_args):
        print '\n{:>6.2f}'.format(subset * 100),
        for acc in accs: sys.stdout.write('{:>15.3f}'.format(acc / norm))
        res.append(tuple([acc / norm for acc in accs]))
    return res

def main():
    random.seed(0)
    parser = ArgumentParser()
    parser.add_argument('--plot', help='Where to save plot (file name)',
                        default=False)
    parser.add_argument('--show', help='Show plot in a window', default=False, 
                        action='store_true')
    args = parser.parse_args()
    
    print 'Loading training data from CSV...'

    tr_data, tr_labels, _ = csv2numpy(config.get('datasets', 'contagio'))