""" spncci.py

    Result storage and access for spncci runs.

    Language: Python 3

    Mark A. Caprio
    University of Notre Dame

    7/9/17 (mac): Extract SpNCCIMeshPointData from res.py.
    7/15/17 (mac): Implement approximate shape invariants.
    7/22/17 (mac): Move out approximate shape invariants.
    10/10/17 (mac): Rename SpNCCIMeshPointData to SpNCCIResultsData.

"""

import math

import numpy as np

from . import (
    am,
    results_data,
    tools,
    )

#################################################
# SpNCCIResultsData
#################################################

class SpNCCIResultsData(results_data.ResultsData):
    """ Container for results data for spncci mesh point.

    TODO: rewrite docstring

    Inherited attributes:
        params (dict)
        energies (dict)
        num_eigenvalues (dict)
        filename (str)

    Attributes:
        spj_listing (list of tuple):
        baby_spncci_listing (list of list):
        decompositions (dictionary):
        observables (dictionary):
          (observable,(Jg_bra,Jg_ket)) -> matrix
          observable (str): observable identifier

    Accessors:

    """

    ########################################
    # Initializer
    ########################################
    def __init__ (self):
        """Initialize attributes as empty containers or None.

        Note: Attributes from parent type (params, energies) are implicitly
        initialized by calling the parent class's __init__.
        """
        super().__init__()
        self.Jgex_values = []
        self.spj_listing = None
        self.baby_spncci_listing = None
        self.decompositions = {}
        self.observables = {}

    ########################################
    # Accessors
    ########################################

    def get_baby_spncci_subspace_label(self,baby_spncci_subspace_index,label):
        """
        Arguments:
            subspace_index (int): subspace index
            label (str): one of the dtype labels for the basis listing
                structured array (e.g., "Nex", "omega.mu", ...)
        """
        return self.baby_spncci_listing[baby_spncci_subspace_index][label]

    def get_rme_matrix(self,observable,Jg_pair,verbose=False):
        """Retrieve RME matrix for observable.

        Assumes stored matrices are between (J,g) subspaces in
        canonical order.  Takes care of canonicalization on retrieval.

        Assumes matrix elements are in group-theory (Rose) convention.

        Assumes matrices on diagonal sector are completely filled in,
        rather than stored just as upper triangles.

        ...

        """

        # determine canonicalization
        (Jg_pair_canonical,flipped,canonicalization_factor) = tools.canonicalize_Jg_pair(
            Jg_pair,tools.RMEConvention.kRose
        )
        if (verbose):
            print("Jg_pair_canonical {} flipped {} canonicalization_factor {}".format(Jg_pair_canonical,flipped,canonicalization_factor))

        # retrieve underlying matrix
        key = (observable,Jg_pair_canonical)
        try:
            matrix = self.observables[observable][Jg_pair_canonical]
        except:
            return None

        # derive canonicalized matrix
        if (flipped):
            matrix = canonicalization_factor*matrix.transpose()

        return matrix

    def get_radius(self,radius_type,qn,default=np.nan):
        """Retrieve rms radius value.

        Note: Raw group-theory convention RME from spncci is intrinsic
        squared radius, i.e., summed over particles.

        Arguments:
           radius_type (str): radius type rp/rn/r
           qn (tuple): quantum numbers for state
           default (float,optional): default value to return for missing radius

        Returns:
           (float): rms radius

        """

        # extract labels
        (J,gex,n) = qn
        n0 = n-1

        # retrieve underlying rme
        if (radius_type=="r"):
            key = ("r2intr",(J,gex),(J,gex))
            ## if (key not in self.observables):
            ##     return np.nan
            try:
                Jg_pair = ((J,gex),(J,gex))
                sum_sqr_radius = self.get_rme_matrix("r2intr",Jg_pair)[n0,n0]
            except:
                return default
        elif (radius_type in {"rp","rn"}):
            sum_sqr_radius = default
        else:
            raise ValueError("radius type code")

        # derive final value from rme
        A = self.params["A"]
        rms_radius = math.sqrt(sum_sqr_radius)

        return rms_radius

    def get_rme(self,observable,qn_pair,default=np.nan,verbose=False):
        """Retrieve reduced matrix element (RME).

        Returns RME in Edmonds convention, as common for spectroscopic data
        analysis in the shell model community.

        <Jf||op||Ji>_Racah = sqrt(2*Jf+1) * <Jf||op||Ji>_gt

        Relies on get_rme_matrix for canonicalization of bra-ket order.

        """

        # extract labels
        (qn_bra,qn_ket) = qn_pair
        (J_bra,gex_bra,n_bra) = qn_bra
        (J_ket,gex_ket,n_ket) = qn_ket
        n0_bra = n_bra-1
        n0_ket = n_ket-1

        # retrieve underlying rme
        try:
            Jg_pair = ((J_bra,gex_bra),(J_ket,gex_ket))
            if (verbose):
                print("  Looking up rme matrix {} {} ->  {}[{}]".format(observable,qn_pair,Jg_pair,(n0_bra,n0_ket)))
            matrix = self.get_rme_matrix(observable,Jg_pair,verbose=verbose)
            rme_gt = matrix[n0_bra,n0_ket]
        except:
            return default

        # derive final value from rme
        rme_racah = math.sqrt(2*J_bra+1)*rme_gt

        return rme_racah

    def get_rtp(self,observable,qn_pair,default=np.nan):
        """ Retrieve reduced transition probability (RTP).
        """

        # extract labels
        (qn_bra,qn_ket) = qn_pair
        (J_bra,gex_bra,n_bra) = qn_bra
        (J_ket,gex_ket,n_ket) = qn_ket

        # retrieve underlying rme
        try:
            rme = self.get_rme(observable,qn_pair)
        except:
            return default

        # derive final value from rme
        rtp = 1/(2*J_ket+1)*rme**2

        return rtp

    def get_decomposition(self,decomposition_type,qn):
        """ Retrieve decomposition ("Nex", "BabySpNCCI", ...) as np.array.
        """

        # extract labels
        (J,gex,n) = qn
        n0 = n-1

        # retrieve decomposition
        try:
            decomposition = self.decompositions[decomposition_type][(J,gex)][:,n0]
        except:
            return None

        return decomposition

#################################################
# test code
#################################################

if (__name__ == "__main__"):
    pass


import numpy as np
from torch.utils.data import Dataset
import matplotlib.pyplot as plt
from PIL import Image
from dataset import OxfordPetDataset
from transforms import train_transform

def visualize_dataset(dataset : Dataset):

    fig, ax = plt.subplots(2, 6, figsize=(15,10), layout='tight')

    sample_idxs = np.random.randint(len(dataset), size=6)

    for i, idx in enumerate(sample_idxs):
        img, msk = dataset[idx]

        img = Image.fromarray(img.numpy().transpose((1,2,0)).astype('uint8'))
        ax[0,i].imshow(img)
        ax[0,i].axis('off')

        msk = Image.fromarray(msk.numpy().astype('uint8'))
        ax[1,i].imshow(msk)
        ax[1,i].axis('off')

    plt.show()

if __name__ == '__main__':
    img_dir = '/Users/stefanswandel/PythonProjects/oxford-iiit-pet/images'
    msk_dir = '/Users/stefanswandel/PythonProjects/oxford-iiit-pet/annotations/trimaps'
    ds = OxfordPetDataset(img_dir, msk_dir, transform=train_transform, set_type='val')
    visualize_dataset(ds)


# 🚨 Don't change the code below 👇
row1 = ["⬜","⬜","⬜"]
row2 = ["⬜","⬜","⬜"]
row3 = ["⬜","⬜","⬜"]

map = [row1, row2, row3]

print(f"{row1}\n{row2}\n{row3}")

position = input("Where do you want to put the treasure? ")

position_row = position[1]
position_column = int(position[0])

if position_row == "1":
    row1[position_column-1] = "X"
elif position_row == "2":
    row2[position_column-1] = "X"
elif position_row == "3":
    row3[position_column-1] = "X"

print(f"{row1}\n{row2}\n{row3}")


import numpy as np

import pylab as pl
from uxdconverter.raw.converter import MeasurementsConverter
from uxdconverter.raw.parser import RawParser

from symm.symmetry import Symmetry, unzip

class Plot(object):
    def plot(self, data_xy, color='b'):
        symm = Symmetry(data_xy)

        peaks = symm.find_peaks()
        symm_axis = symm.optimize_symmetry()

        func = symm.get_symmetry_function()

        x, y = unzip(data_xy)
        func = symm.get_function()

        print("Peaks at (x,y):")
        print(peaks)

        for peak in peaks:
            pl.axvline(peak[0], linestyle='--', color=color)

        pl.plot(x, y)

        x_space = np.linspace(x[0], x[-1], num=200)
        pl.plot(x_space, func(x_space))

        print("Found axis at %s with symmetry %s" % (symm_axis.x, symm_axis.fun))

        pl.axvline(symm_axis.x, color=color)

        symm_opt = symm.make_symmetric(symm_axis.x)
        symm_axis = symm_opt.optimize_symmetry()

        print("Found new axis at %s with symmetry %s" % (symm_axis.x, symm_axis.fun))
        pl.axvline(symm_axis.x, linestyle='--', color=color)
        print()
        print()

        # pl.show()
        # mirror to the right
        # right_space = np.linspace(0, x[-1] - symm_axis.x, num=100)
        # pl.plot(right_space + symm_axis.x, func(-right_space+symm_axis.x))
        # mirror to the left
        # left_space = np.linspace(x[0] - symm_axis.x, 0, num=100)
        # pl.plot(left_space +symm_axis.x, func(-left_space+symm_axis.x))

class Loader(object):
    def __init__(self):
        self._plotter = Plot()
        self._parser = MeasurementsConverter()

    def load(self, file, color):

        try:
            rawms = RawParser().parse_from_file(file)
            print("Loaded file %s" % file)
        except BaseException as e:
            print("Cannot parse file %s" % file)

            print(e)
            return

        measurement = rawms.get_measurements()[0]
        stepsize = measurement.get_header().get_step_size()
        steptime = measurement.get_header().get_step_time()
        start = measurement.get_header().get_start_two_theta()

        # Convert to counts per second
        data_y = np.array(measurement.get_data().get_data_points()) / steptime
        data_x = np.array(range(0, measurement.get_data().get_number_of_data_points())) * stepsize + start
        data_xy = list(zip(data_x, data_y))

        self._plotter.plot(data_xy, color=color)

loader = Loader()

# file = '/mnt/hektor/measure/Dünnschicht/XRD/Alex/Alignment_2018_March/12_alignment_source_slit_0d2/262_SS0d2_'
# rawms = RawParser().parse_from_file(file)
# loader.load(file + 'DS.raw', 'b')
# loader.load(file + 'BS.raw', 'r')

def load(number, slit='0d1'):
    pl.cla()

    print(len(slit))
    if not slit  == '':
        file = '/mnt/hektor/measure/Dünnschicht/XRD/Alex/03_Alignment/Alignment_2018_June/09_ReAlign_Exit_Slit/' + str(number) + '_' + slit + '_'
    else:
        file = '/mnt/hektor/measure/Dünnschicht/XRD/Alex/03_Alignment/Alignment_2018_June/09_ReAlign_Exit_Slit/' + str(number) + '_'

    loader.load(file + 'DS.raw', 'b')
    loader.load(file + 'BS.raw', 'r')

load('23', '')


"""game time ps state

Revision ID: 603e4def37ae
Revises: be58e854b159
Create Date: 2019-10-26 11:45:00.046144

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '603e4def37ae'
down_revision = 'be58e854b159'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('game', schema=None) as batch_op:
        batch_op.add_column(sa.Column('last_time', sa.DateTime(), nullable=True))
        batch_op.add_column(sa.Column('ps', sa.String(length=140), nullable=True))
        batch_op.add_column(sa.Column('start_time', sa.DateTime(), nullable=True))
        batch_op.add_column(sa.Column('state', sa.Integer(), nullable=True))

    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('game', schema=None) as batch_op:
        batch_op.drop_column('state')
        batch_op.drop_column('start_time')
        batch_op.drop_column('ps')
        batch_op.drop_column('last_time')

    # ### end Alembic commands ###


import sys

def f_gold ( n , k ) :
    dp = np.zeros ( ( n + 1 , k + 1 ) )
    dp [ 1 ] [ 0 ] = 1
    dp [ 1 ] [ 0 ] = 1
    for i in range ( 2 , n + 1 ) :
        for j in range ( i , k + 1 ) :
            dp [ i ] [ j ] [ 0 ] = dp [ i - 1 ] [ j ] [ 0 ] + dp [ i - 1 ] [ j ] [ 1 ]
            dp [ i ] [ j ] [ 1 ] = dp [ i - 1 ] [ j ] [ 0 ]
            if j - 1 >= 0 :
                dp [ i ] [ j ] [ 1 ] += dp [ i - 1 ] [ j - 1 ] [ 1 ]
    return dp [ n ] [ k ] [ 0 ] + dp [ n ] [ k ] [ 1 ]

if __name__ == '__main__':
    param = [
    (29,85,),
    (47,29,),
    (77,96,),
    (9,91,),
    (29,80,),
    (94,85,),
    (51,87,),
    (46,62,),
    (18,96,),
    (86,86,)
        ]
    n_success = 0
    print("class,mutant,test_index,result")
    for i, parameters_set in enumerate(param):
        try:
            print("COUNT_BINARY_STRINGS_K_TIMES_APPEARING_ADJACENT_TWO_SET_BITS," + sys.argv[1] + "," + str(i) + "," + str(f_gold(*parameters_set)))
        except:
            print("COUNT_BINARY_STRINGS_K_TIMES_APPEARING_ADJACENT_TWO_SET_BITS," + sys.argv[1] + "," + str(i) + ",EXCEPTION")


import time
import numpy as np
import pandas as pd
from itertools import combinations, product
from sklearn.metrics import accuracy_score
from collections import defaultdict

class RULES:
    def __init__(self, contains_header=True, discretize_mode='equal', number_bins=7, discretize_ints=False):
        self.contains_header = contains_header
        self.discretize_mode = discretize_mode
        self.number_bins = number_bins
        self.discretize_ints = discretize_ints
        self.bins = []

        self.attribute_names = None
        self.preproc_dict = None
        self.labels_dict = None

        self.rules = []
        self.most_probable_class = None
        self.n_attributes = 0

    # ######################### F I T #########################
    def fit(self, x, y, method='RRULES', show_rules=True, show_metrics=True, show_time=True):
        since = time.time()
        x, y = self.__preproc_train_data(x, y)
        preproc_time = time.time() - since

        since = time.time()
        if method == 'RRULES':
            print('Training with RRULES...')
            self.__fit_RRULES(x, y)
        elif method == 'Original':
            print('Training with Original RULES...')
            self.__fit_original_RULES(x, y)
        fit_time = time.time() - since

        since = time.time()
        if show_rules:
            metrics = None
            if show_metrics:
                metrics = self.__compute_metrics(x, y)
                metrics_time = time.time() - since
                since = time.time()
            print('\nInduced rules:')
            print(self.__print_rules(metrics))
            print()
        print_time = time.time() - since

        if show_time:
            print(f"Time to preprocess data = {preproc_time:.2f}s")
            print(f"Time to fit data = {fit_time:.2f}s")
            if show_rules:
                if show_metrics:
                    print(f"Time to comput metrics = {metrics_time:.2f}s")
                print(f"Time to print rules = {print_time:.2f}s")
            print()

    def __fit_RRULES(self, x, y):
        # We calculate the most probable class to create a default rule for unseen combinations of attributes
        classes, counts = np.unique(y, return_counts=True)
        self.most_probable_class = classes[np.argmax(counts)]

        # ##### RRULES #####
        n_examples, n_attributes = x.shape
        self.n_attributes = n_attributes
        # Track non-classified by index
        indices_not_classified = np.arange(n_examples)

        # For each n_conditions = 1, ..., n_attributes
        for n_conditions in range(1, n_attributes + 1):
            # Generate all possible combinations of attributes (without repetition and without order)
            # of length n_conditions
            attribute_combinations_n = combinations(range(n_attributes), n_conditions)
            # For each combination of attributes (columns)
            for attribute_group in attribute_combinations_n:
                lists_of_values = []
                # Calculate the unique values of the chosen attributes from the non-classified instances,
                # and generate all combinations of selectors <attribute, value> given the chosen attributes
                # These combination of selectors form conditions
                for attribute in attribute_group:
                    lists_of_values.append(np.unique(x[indices_not_classified, attribute]))
                value_combinations = product(*lists_of_values)
                # For each condition <att1, val1>, <att2, val2>, ...
                for value_group in value_combinations:
                    # Find indices of ALL INSTANCES that match the condition
                    indices_match = np.where((x[:, list(attribute_group)] == value_group).all(axis=1))[0]
                    # Find indices of NON-CLASSIFIED INSTANCES that match the condition
                    indices_match_not_classified = \
                        np.where((x[np.ix_(indices_not_classified, attribute_group)] == value_group).all(axis=1))[0]
                    if len(indices_match) == 0:
                        # This condition is not present in the training set of examples
                        continue
                    if len(indices_match_not_classified) == 0:
                        # Although this condition is present in the set of examples,
                        # it does not match any non-classified instance
                        # It is the case of a condition that could end generating an IRRELEVANT RULE
                        continue
                    # Take the ground truth of the matched instances and look if they belong to a single class
                    classes = y[indices_match]
                    unique_classes = np.unique(classes)
                    if len(unique_classes) == 1:
                        # Generate the rule and add it to the set of rules
                        # The rule is encoded as the set of attributes to match, their values and the class
                        self.rules.append((attribute_group, value_group, unique_classes[0]))
                        # Remove the classified instances from the set of non-classified ones
                        indices_not_classified = np.setdiff1d(indices_not_classified, indices_match, assume_unique=True)
                        # If there aren't any more instances to classify, return
                        if len(indices_not_classified) == 0:
                            return
                    # If we are in the last iteration, we are checking for the full antecedent
                    # If there is more than a single class, we have a contradiction in the data
                    # Let's choose the most probable class (or random if tie)
                    elif n_conditions == n_attributes:
                        print("WARNING: There are contradictions in the training set")
                        unique_classes, counts = np.unique(classes, return_counts=True)
                        self.rules.append((attribute_group, value_group, unique_classes[np.argmax(counts)]))
                        # Remove the classified instances from the set of non-classified ones
                        indices_not_classified = np.setdiff1d(indices_not_classified, indices_match, assume_unique=True)
                        # If there aren't any more instances to classify, return
                        if len(indices_not_classified) == 0:
                            return

    def __fit_original_RULES(self, x, y):
        # We calculate the most probable class to create a default rule for unseen combinations of attributes
        classes, counts = np.unique(y, return_counts=True)
        self.most_probable_class = classes[np.argmax(counts)]

        # ##### RULES #####
        n_examples, n_attributes = x.shape
        self.n_attributes = n_attributes
        # Track non-classified by index
        indices_not_classified = np.arange(n_examples)

        # For each n_conditions = 1, ..., n_attributes
        for n_conditions in range(1, n_attributes + 1):
            # Check stopping condition only at the beginning of every outer iteration
            if len(indices_not_classified) == 0:
                return
            # Generate all combinations of selectors of length n_conditions
            conditions = []
            # Generate all possible combinations of attributes (without repetition and without order)
            # of length n_conditions
            attribute_combinations_n = combinations(range(n_attributes), n_conditions)
            # For each combination of attributes (columns)
            for attribute_group in attribute_combinations_n:
                lists_of_values = []
                # Calculate the unique values of the chosen attributes, and generate
                # all combinations of selectors <attribute, value> given the chosen attributes
                # These combination of selectors form conditions
                for attribute in attribute_group:
                    lists_of_values.append(np.unique(x[indices_not_classified, attribute]))
                value_combinations = product(*lists_of_values)
                for value_group in value_combinations:
                    conditions.append((attribute_group, value_group))

            # For each condition <att1, val1>, <att2, val2>, ...
            for attribute_group, value_group in conditions:
                # Find indices of ALL INSTANCES that match the condition
                indices_match = np.where((x[:, list(attribute_group)] == value_group).all(axis=1))[0]
                if len(indices_match) == 0:
                    # This condition is not present in the training set of examples
                    continue
                # Take the ground truth of the matched instances and look if they belong to a single class
                classes = y[indices_match]
                unique_classes = np.unique(classes)
                if len(unique_classes) == 1:
                    # Check for irrelevant conditions
                    is_irrelevant = False
                    if n_conditions > 1:
                        for rule in self.rules:
                            # If there is a previous rule (with less conditions) that includes all the selectors for
                            # the new rule, this becomes irrelevant as it does not classify any new instance
                            if all(selector in zip(attribute_group, value_group) for selector in zip(rule[0], rule[1])):
                                is_irrelevant = True
                                break
                    if not is_irrelevant:
                        # Generate the rule and add it to the set of rules
                        # The rule is encoded as the set of attributes to match, their values and the class
                        self.rules.append((attribute_group, value_group, unique_classes[0]))
                        # Remove the classified instances from the set of non-classified ones
                        indices_not_classified = np.setdiff1d(indices_not_classified, indices_match, assume_unique=True)

                # If we are in the last iteration, we are checking for the full antecedent
                # If there is more than a single class, we have a contradiction in the data
                # Let's choose the most probable class (or random if tie)
                # There won't be irrelevant conditions here because it is the last iteration and we have
                # non-classified instances!
                elif n_conditions == n_attributes:
                    print("WARNING: There are contradictions in the training set")
                    unique_classes, counts = np.unique(classes, return_counts=True)
                    self.rules.append((attribute_group, value_group, unique_classes[np.argmax(counts)]))
                    # Remove the classified instances from the set of non-classified ones
                    indices_not_classified = np.setdiff1d(indices_not_classified, indices_match, assume_unique=True)

    # ######################### P R E D I C T #########################
    def predict(self, x):
        # Predict
        y_pred = self.__predict(x)
        # Predictions are integers, convert back to original values
        y_pred = np.vectorize(self.labels_dict[-1].get)(y_pred)
        return y_pred

    def score(self, x, y):
        y_pred = self.__predict(x)
        # Convert true class to integers (predictions already are)
        y = np.vectorize(self.preproc_dict[-1].get)(y)
        return accuracy_score(y, y_pred)

    def __predict(self, x):
        print('Predicting...')
        x = self.__preproc_test_data(x)
        y_pred = []
        # For each instance
        for instance in x:
            classified = False
            # For each rule
            for attributes, values, tag in self.rules:
                # Check if antecedent matches
                if np.array_equal(instance[list(attributes)], values):
                    y_pred.append(tag)
                    classified = True
                    break
            # No rule matched, we apply the default rule --> Most probable class
            if not classified:
                print("WARNING: There are unseen combinations")
                y_pred.append(self.most_probable_class)
        return np.array(y_pred)

    # ################ M E T R I C S   A N D   R U L E S ################
    def compute_metrics(self, x, y):
        # Use the already computed (training) bins and integer conversions
        x = self.__preproc_test_data(x)
        y = np.vectorize(self.preproc_dict[-1].get)(y)
        return self.__compute_metrics(x, y)

    def __compute_metrics(self, x, y):
        n_examples = x.shape[0]

        # Store (Coverage, Precision) for each rule
        metrics = []
        overall_coverage = []
        overall_precision = []
        for attributes, values, tag in self.rules:
            indices_match_condition = np.where((x[:, list(attributes)] == values).all(axis=1))[0]
            coverage = len(indices_match_condition) / n_examples
            indices_match_rule = np.where(y[indices_match_condition] == tag)[0]
            precision = len(indices_match_rule) / len(indices_match_condition)
            overall_precision.append(precision)
            overall_coverage.append(coverage)
            metrics.append((coverage, precision))
        # Add overall metrics
        metrics.append((sum(overall_coverage), sum(overall_precision) / len(overall_precision)))

        return metrics

    def __print_rules(self, metrics=None):
        # Set default attribute names if not present in dataset
        if self.attribute_names is None:
            attribute_names = [f"Attribute_{i + 1}" for i in range(self.n_attributes)]
            attribute_names.append("Class")
            self.attribute_names = attribute_names

        rule_strings = []
        for i in range(len(self.rules)):
            attributes, values, tag = self.rules[i]
            rule = f"Rule {i + 1:3}.  IF " \
                   f"{' AND '.join([f'{self.attribute_names[attributes[j]]} IS {self.labels_dict[attributes[j]][values[j]]}' for j in range(len(attributes))])}" \
                   f" THEN {self.attribute_names[-1]} IS {self.labels_dict[-1][tag]}"

            if metrics:
                rule = f"{rule:100}    Coverage = {100 * metrics[i][0]:5.2f}%    Precision = " \
                       f"{100 * metrics[i][1]:5.2f}%"
            rule_strings.append(rule)
        if metrics:
            overall = f"Overall Coverage = {100 * metrics[-1][0]:5.2f}%     Overall Precision = {100 * metrics[-1][1]:5.2f}%"
            rule_strings.append(overall)
        return '\n'.join(rule_strings)

    # ############### P R E P R O C E S S I N G ###############
    def __preproc_train_data(self, x, y):
        # Set attribute names for pretty printing
        if self.contains_header:
            names_x = x.columns.values.tolist()
            name_y = y.columns.values.tolist()
            self.attribute_names = names_x + name_y

        column_types = x.dtypes
        # Missing Values
        for attribute, dtype in zip(x, column_types):
            # We take the mean for floats
            if np.issubdtype(dtype, np.floating):
                x.loc[:, attribute].fillna(x[attribute].mean(), inplace=True)
            # We take the mode for categoricals (including integers)
            else:
                # Intermediate conversion into '?' (to join different representations for mv)
                x.loc[:, attribute].fillna('?', inplace=True)
                uniques, counts = np.unique(x[attribute], return_counts=True)
                mode = uniques[np.argmax(counts)]
                if mode == '?':
                    mode = uniques[np.argsort(counts)[-2]]
                x.loc[x[attribute] == '?', attribute] = mode

        # Discretize Numeric attributes
        # Store exact discretization bins for test data
        if self.number_bins != 0:
            to_discretize = np.number if self.discretize_ints else np.floating
            for attribute, dtype in zip(x, column_types):
                if np.issubdtype(dtype, to_discretize):
                    if self.discretize_mode == 'equal':
                        x[attribute], bins = pd.cut(x[attribute], bins=self.number_bins, retbins=True)
                        self.bins.append((attribute, bins, np.unique(x[attribute])))
                    elif self.discretize_mode == 'freq':
                        x[attribute], bins = pd.qcut(x[attribute], q=self.number_bins, retbins=True)
                        self.bins.append((attribute, bins, np.unique(x[attribute])))
                    else:
                        raise ValueError("Wrong discretize_mode")

        # Move everything to integer, so numpy works faster
        x = x.to_numpy()
        y = y.to_numpy()
        data = np.concatenate((x, y), axis=1)
        _, n_cols = data.shape

        # Store conversion from original values to integers for pretty printing
        inv_conversions = []
        conversions = []
        for i in range(n_cols):
            col = data[:, i]
            uniques = np.unique(col).tolist()
            d = defaultdict(lambda: -1, zip(uniques, range(len(uniques))))
            d_inv = dict(zip(range(len(uniques)), uniques))
            data[:, i] = np.vectorize(d.get)(col)
            conversions.append(d)
            inv_conversions.append(d_inv)

        # Preprocessing Dictionary
        # Contains all the conversions from original values to integers --> To be used when preprocessing test data
        self.preproc_dict = conversions
        # Labels Dictionary
        # Contains all the conversions from integers to original values --> To be used when pretty printing
        self.labels_dict = inv_conversions

        return data[:, :-1].astype(np.uint8), data[:, -1].astype(np.uint8)

    def __preproc_test_data(self, x):
        # Preprocess only attributes (not class)
        # Use the same exact steps than in training
        #   MV
        #   Discretization using same bins
        #   Conversion to integers using same mapping

        column_types = x.dtypes
        # Missing Values
        for attribute, dtype in zip(x, column_types):
            # We take the mean for floats
            if np.issubdtype(dtype, np.floating):
                x.loc[:, attribute].fillna(x[attribute].mean(), inplace=True)
            # We take the mode for categoricals (including integers)
            else:
                # Intermediate conversion into '?' (to join different representations for mv)
                x.loc[:, attribute].fillna('?', inplace=True)
                uniques, counts = np.unique(x[attribute], return_counts=True)
                mode = uniques[np.argmax(counts)]
                if mode == '?':
                    mode = uniques[np.argsort(counts)[-2]]
                x.loc[x[attribute] == '?', attribute] = mode

        # Discretize Numeric attributes using training bins
        for attribute, bins, labels in self.bins:
            if len(labels) + 1 == len(bins):
                x[attribute] = pd.cut(x[attribute], bins=bins, labels=labels)
            else:
                x[attribute] = pd.cut(x[attribute], bins=bins)

        # Move everything to integer, so numpy works faster
        data = x.to_numpy()
        _, n_cols = data.shape

        # Use original-integer training mapping
        for i in range(n_cols):
            col = data[:, i]
            data[:, i] = np.vectorize(self.__my_vectorized_mapping)(i, col)

        return data.astype(np.uint8)

    def __my_vectorized_mapping(self, i, x):
        return self.preproc_dict[i][x]


from tensorflow import keras
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import *
from sklearn.preprocessing import LabelEncoder, StandardScaler
from collections import Counter, namedtuple
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from sklearn.model_selection import StratifiedShuffleSplit, ShuffleSplit
from utils import *
from nets import *

path_stub="/data/data_corpora/SIGIR2019_gsdata"
data2017 = TrialInputData(path_stub,"2017ct", "20180712processedGoldStandardCT2017.tsv.gz")
data2018 = TrialInputData(path_stub,"2018ct","20190111processedGoldStandardCT2018.tsv.gz")

def prepare_tensorflow():
    ## extra imports to set GPU options
    import tensorflow as tf

    # TensorFlow wizardry
    config = tf.ConfigProto()

    # Don't pre-allocate memory; allocate as-needed
    config.gpu_options.allow_growth = True

    # Only allow a total of half the GPU memory to be allocated
    config.gpu_options.per_process_gpu_memory_fraction = 0.4

    # Create a session with the above options specified.
    session = tf.Session(config=config)
    tf.keras.backend.set_session(session)

bonus_info_max=10000
max_sentences = 30
max_sentence_length = 30
vocab_size=40000
nfold=10
max_epochs=8

def run_and_report(tuners, model_provider, data, labels):
    for tuner in tuners:
        acc, accs = experiment(model_provider, data, labels,
                   fine_tuner=tuner, max_epochs=max_epochs, nfold=nfold, verbose=0)
    print("Accuracy for", nfold, "crossvalidation:", "{:.3f}".format(acc))
    print("Raw values:",["{:.3f}".format(a) for a in accs])

def perform_cross_experiment(data1, data2):
    prepare_tensorflow()
    all_sentences, all_mesh, all_genes, all_organisms, all_keywords, all_id, labels, word_index, tokenizers = read_trial_data(data1, vocab_size, max_sentences, max_sentence_length, bonus_info_max)
    embedding_weights = get_embedding_weights(path="/home/hellrich/keras-test/embeddings/bio_nlp_win30_", input_dim=vocab_size, word_index=word_index)
    all_sentences2, all_mesh2, all_genes2, all_organisms2, all_keywords2, all_id2, labels2, word_index2 = read_trial_data(data2, vocab_size, max_sentences, max_sentence_length, bonus_info_max, tokenizers)

    tuners =[SmartTuner(4, {4: 0.5, 5: 4, 6: .7, 7: .7, 8: .7, 9: .7, 10: .7})]
    model_provider = two_level_gru(embedding_weights, vocab_size, max_sentences, max_sentence_length, bonus_info_shapes=(all_mesh.shape[1], all_genes.shape[1], all_organisms.shape[1], all_keywords.shape[1]), bi=True)
    for tuner in tuners:
        acc = cross_experiment(model_provider, [all_sentences, all_mesh, all_genes, all_organisms, all_keywords], labels,
        [all_sentences2, all_mesh2, all_genes2, all_organisms2, all_keywords2], labels2, fine_tuner=tuner, max_epochs=max_epochs)
        print("Accuracy for cross-comparison:", "{:.3f}".format(acc))

def crossvalidation(input_data):
    prepare_tensorflow()
    #loading stuff
    all_sentences, all_mesh, all_genes, all_organisms, all_keywords, all_id, labels, word_index, tokenizers = read_trial_data(input_data, vocab_size, max_sentences, max_sentence_length, bonus_info_max)
    embedding_weights = get_embedding_weights(path="/home/hellrich/keras-test/embeddings/bio_nlp_win30_", input_dim=vocab_size, word_index=word_index)

    tuners =[
    SmartTuner(4, {4: 0.5, 5: 4, 6: .7, 7: .7, 8: .7, 9: .7, 10: .7})
            ]
    model_provider = two_level_gru(embedding_weights, vocab_size, max_sentences, max_sentence_length, bonus_info_shapes=(all_mesh.shape[1], all_genes.shape[1], all_organisms.shape[1], all_keywords.shape[1]), bi=True)

    run_and_report(tuners, model_provider, [all_sentences, all_mesh, all_genes, all_organisms, all_keywords], labels)

if __name__ == "__main__":
    print("2018 cross")
    crossvalidation(data2018)
    print("2017 cross")
    crossvalidation(data2017)
    print("2017 -> 2018")
    perform_cross_experiment(data2017,data2018)
    print("2018 -> 2017")
    perform_cross_experiment(data2018,data2017)


rows = open('input', 'r').read().split('\n')

depart = int(rows[0])
closestBusId = 0
closestT = 100000

for busId in rows[1].split(','):
  if busId != 'x':
    inServiceBusId = int(busId)
    t = int(round((1 - ((depart / float(busId)) % 1)) * inServiceBusId))

    if t < closestT:
      closestBusId = int(busId)
      closestT = t

print(closestT * closestBusId)


import pandas as pd
import os
from get_dataframe import get_dataframe

if __name__ == '__main__':

    directory = '../csv/'
    for file in os.listdir(directory):
        filename = os.fsdecode(file)
        filename = os.path.join(directory, filename)

        df = get_dataframe(filename)
        # print(df)
        f1 = df['metrics.f1'].mean()
        prec = df['metrics.precision'].mean()
        recall = df['metrics.recall'].mean()

        print(f"""
        {filename}
        precision: {prec}
        recall: {recall}
        f1-score: {f1}
        """)


import cv2
import matplotlib.pyplot as plt
import numpy as np
import time
import thrusters

hsv = None
img = None
bounding_rect = None
empty = None
cam_dex = 0
baud_rate = 115200
thrust_manager = thrusters.ThrustManager()
error_queue = None
target_orientation = 0
current_orientation = None  #link controls orientation list here
# BECAUSE PARAMETERS ARE CRINGE

def detect_rope():
    global hsv
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower_red = np.array([0,50,50])
    upper_red = np.array([10,255,255])
    mask0 = cv2.inRange(hsv, lower_red, upper_red)

    lower_red = np.array([170,50,50])
    upper_red = np.array([180,255,255])
    mask1 = cv2.inRange(hsv, lower_red, upper_red)

    mask_red = mask0+mask1
    hsv[np.where(mask_red==0)] = 0

def find_defect():
    global bounding_rect, empty
    rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
    gray = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY)

    _, thresh = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if len(contours) == 0:
        empty = True
        return (0, 0)

    cnt = contours[0]
    hull = cv2.convexHull(cnt, returnPoints = False)
    defects = cv2.convexityDefects(cnt, hull)

    if not defects:
        return (-1, -1)

    defect = defects[0, 0]
    bounding_rect = cv2.boundingRect(cnt)
    defect_pt = tuple(cnt[defect[2]][0])
    return defect_pt

def read_frame():
    global img, hsv
    vid = cv2.VideoCapture(cam_dex)
    _, img = vid.read()
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

def turn(direction):
    left = False
    right = True

    if direction == left:
        #packet =
        pass
    elif direction == right:
        #packet =
        pass

    send_packet()
    time.sleep((len(packet)+2)/baud_rate)
    get_orientation_data()

    # Get angular acceleration data, then do 0.5at2 and figure out t

def adjust_orientation(orientation):
    orientation %= 360
    if (orientation < 0):
        orientation += 360
    return orientation

def get_error(current_orientation, target_orientation):
    error = adjust_orientation(target_orientation - current_orientation[0])
    if (error > 180):
        error = 180 - error
    return error

def run():
    finished = False
    thrust_manager.multiplier = 0.1
    thrust_manager.getTSpeeds((0, 1, 0), (0, 0, 0))    # Move forward

    while(not finished):
        read_frame()
        detect_rope()
        defect_pt = find_defect()

        if defect_pt == (0, 0):

            finished = True
        elif defect_pt != (-1, -1):
            x, y, w, h = bounding_rect
            thrust_manager.multiplier = 0.1 #stop moving forward
            thrust_manager.getTSpeeds((0, 0, 0), (0, 0, 0)) # Stop moving forward
            left = False
            right = True

            if ((defect_pt[0] - x) > (w / 2.0)):
                target_orientation = current_orientation[0] + 90 #turn left
                target_orientation = adjust_orientation(target_orientation)
                #START ERROR READING IN QUEUE, DON'T READ HERE PROBABLY
                error = adjust_orientation(target_orientation - current_orientation[0])
            else:
                turn(right);    #turn right


import os, sys
dbg = False

def get_observed_pulsars(path):
    pulsars = [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))]
    pulsars.sort()
    return pulsars

def get_dates(PSR,path):
    files = os.listdir(path+'/'+PSR+'/')
    dates = []
    for file in files:
        if 'mask_' in file: dates.append(file[5:13])
    return dates

def get_bypsr(PSR,DBPATH):
    if dbg: print(PSR)
    lines = " \n"
    lines += '

'+PSR+'
 \n'
    lines += '
Historical Tempo Plot
 \n'
    lines += ' \n'
    lines += ' \n'
    lines += '
 \n'
    for date in get_dates(PSR,DBPATH):
        if dbg: print(date)
        lines += date[0:4]+'/'+date[4:6]+'/'+date[6:8] +'\n'
        #FUTURE: ADD LINES WITH INFO FROM OBSERVATION FROM DATABASE
        lines += 'Mask \n'
        lines += 'Presto \n'
        lines += '
 \n'
    lines += '
 \n'
    lines += '
 \n'
    if dbg: print()
    return lines

def write_bypsr(pulsars,HEADER,FOOTER,WEBPATH,DBPATH):
    header = open(WEBPATH+HEADER).readlines()
    footer = open(WEBPATH+FOOTER).readlines()

    content = ''
    for psr in pulsars:
        content += get_bypsr(psr,DBPATH)

    file = open(WEBPATH+'by_psr.html','w')
    file.writelines(header)
    file.writelines(content)
    file.writelines(footer)
    file.close()
    return 0

def get_lastobs(PSR,DBPATH):
    if dbg: print(PSR)
    #FUTURE: READ THIS INFO FROM DATABASE
    LAST_DATE = '2020/01/10'
    LAST_EXP  = '2.75'

    lines = " \n"
    lines += '

'+PSR+'
 \n'
    lines += '
Observed on '+LAST_DATE+' for a total of '+LAST_EXP+' hr
 \n'
    lines += '

 \n'
    lines += '

 \n'

    lines += '

 \n'
    lines += ' \n'
    lines += '

 \n'
    lines += '

 \n'
    lines += ' \n'
    lines += '

 \n'
    lines += '

 \n'
    lines += ' \n'
    lines += '

 \n'

    lines += '

 \n'
    lines += '

 \n'
    lines += '
 \n'
    if dbg: print()
    return lines

def write_lastobs(pulsars,HEADER,FOOTER,WEBPATH,DBPATH):
    header = open(WEBPATH+HEADER).readlines()
    footer = open(WEBPATH+FOOTER).readlines()

    content = ''
    for psr in pulsars:
        content += get_lastobs(psr,DBPATH)

    file = open(WEBPATH+'last_obs.html','w')
    file.writelines(header)
    file.writelines(content)
    file.writelines(footer)
    file.close()
    return 0

#RUN MAIN CODE
if __name__ == "__main__":

    WEBPATH = "/home/fgarcia/github/puma/puglieseweb/"
    DBPATH  = WEBPATH+'database/'
    # DBPATH/database/PSRNAME/mask_DATE.png presto_DATE.png tempo.png
    # DBPATH/last_obs/PSRNAME/mask.png presto.png tempo.png

    dbg=False
    print()
    print('READING PULSARS FROM DB AT '+DBPATH)
    pulsars = get_observed_pulsars(DBPATH)
    print()

    #by_psr.html
    HEADER  = 'by_psr_header.txt'
    FOOTER  = 'by_psr_footer.txt'
    print('-----------------')
    print('START by_psr.html')
    if write_bypsr(pulsars,HEADER,FOOTER,WEBPATH,DBPATH)==0: print('WRITTEN by_psr.html')
    else: print('ERROR by_psr.html')
    print()

    #last_obs.html
    HEADER  = 'last_obs_header.txt'
    FOOTER  = 'last_obs_footer.txt'
    print('-------------------')
    print('START last_obs.html')
    if write_lastobs(pulsars,HEADER,FOOTER,WEBPATH,DBPATH)==0: print('WRITTEN last_obs.html')
    else: print('ERROR last_obs.html')
    print()
    #EXIT PROGRAM
    print()
    print('FINISHED UPDATING WEBPAGE AT '+WEBPATH)
    print()


import numpy as np
import pytest

from kalm_benchmark.evaluation.scanner.kubeaudit import Scanner
from kalm_benchmark.evaluation.scanner.scanner_evaluator import CheckCategory

class TestCheckCategorization:
    @pytest.mark.parametrize(
        "check_id",
        [
            "AppArmorAnnotationMissing",
            "AppArmorDisabled",
            "AppArmorInvalidAnnotation",
        ],
    )
    def test_apparmor_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "AutomountServiceAccountTokenDeprecated",
            "AutomountServiceAccountTokenTrueAndDefaultSA",
        ],
    )
    def test_automount_sa_token_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        ["CapabilityAdded", "CapabilityShouldDropAll", "CapabilityOrSecurityContextMissing"],
    )
    def test_capabilities_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "NamespaceHostNetworkTrue",
            "NamespaceHostIPCTrue",
            "NamespaceHostPIDTrue",
        ],
    )
    def test_hostns_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "ImageTagMissing",
            "ImageTagIncorrect",
            "ImageCorrect",
        ],
    )
    def test_image_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "LimitsNotSet",
            "LimitsCPUNotSet",
            "LimitsMemoryNotSet",
            "LimitsCPUExceeded",
            "LimitsMemoryExceeded",
        ],
    )
    def test_limits_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.Workload

    @pytest.mark.parametrize(
        "check_id",
        [
            "SensitivePathsMounted",
        ],
    )
    def test_mounts_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "MissingDefaultDenyIngressAndEgressNetworkPolicy",
            "MissingDefaultDenyIngressNetworkPolicy",
            "MissingDefaultDenyEgressNetworkPolicy",
            "AllowAllIngressNetworkPolicyExists",
            "AllowAllEgressNetworkPolicyExists",
        ],
    )
    def test_netpol_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.Network

    @pytest.mark.parametrize(
        "check_id",
        [
            "RunAsUserCSCRoot",
            "RunAsUserPSCRoot",
            "RunAsNonRootCSCFalse",
            "RunAsNonRootPSCNilCSCNil",
            "RunAsNonRootPSCFalseCSCNil",
        ],
    )
    def test_nonroot_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "AllowPrivilegeEscalationNil",
            "AllowPrivilegeEscalationTrue",
        ],
    )
    def test_privilege_escalation_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "PrivilegedTrue",
            "PrivilegedNil",
        ],
    )
    def test_privileged_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "ReadOnlyRootFilesystemFalse",
            "ReadOnlyRootFilesystemNil",
        ],
    )
    def test_root_fs_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "SeccompAnnotationMissing",
            "SeccompDeprecatedPod",
            "SeccompDisabledPod",
            "SeccompDeprecatedContainer",
            "SeccompDisabledContainer",
        ],
    )
    def test_seccomp_checks(self, check_id: str):
        cat = Scanner.categorize_check(check_id)
        assert cat == CheckCategory.PodSecurity

    @pytest.mark.parametrize(
        "check_id",
        [
            "NotAValidCheck",
            "",
            None,
            np.nan,
        ],
    )
    def test_invalid_or_unknown_ids(self, check_id: str | None):
        cat = Scanner.categorize_check(check_id)
        assert cat is None  # no category assigned


# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
import pytz
from dateutil import rrule
import logging

from openerp import api, models, fields
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DTF
from openerp.tools.translate import _
from openerp.exceptions import ValidationError

from openerp.addons.resource.resource import seconds
import openerp.addons.decimal_precision as dp
from openerp.osv import fields as old_api_fields, osv

_logger = logging.getLogger(__name__)

SLOT_START_DELAY_MINS = 15
SLOT_DURATION_MINS = 60

class ResourceResource(models.Model):
    _inherit = 'resource.resource'

    to_calendar = fields.Boolean('Display on calendar')
    color = fields.Char('Color')
    has_slot_calendar = fields.Boolean('Use Working Time as Slots Definition')

class ResourceCalendar(models.Model):
    _inherit = 'resource.calendar'

    @api.multi
    def get_working_accurate_hours(self, start_dt=None, end_dt=None):
        """
            Replacement of resource calendar method get_working_hours
            Allows to handle hour_to = 00:00
            Takes in account minutes
            Adds public holidays time (resource leaves with reason = PH)
        """
        leave_obj = self.env['resource.calendar.leaves']
        for calendar in self:
            id = calendar.id
            hours = timedelta()
            for day in rrule.rrule(rrule.DAILY, dtstart=start_dt,
                                   until=end_dt.replace(hour=23, minute=59, second=59),
                                   byweekday=calendar.get_weekdays()[0]):
                day_start_dt = day.replace(hour=0, minute=0, second=0)
                if start_dt and day.date() == start_dt.date():
                    day_start_dt = start_dt
                day_end_dt = day.replace(hour=23, minute=59, second=59)
                if end_dt and day.date() == end_dt.date():
                    day_end_dt = end_dt
                work_limits = []
                work_limits.append((day_start_dt.replace(hour=0, minute=0, second=0), day_start_dt))
                work_limits.append((day_end_dt, day_end_dt.replace(hour=23, minute=59, second=59)))

                intervals = []
                work_dt = day_start_dt.replace(hour=0, minute=0, second=0)
                working_intervals = []
                for calendar_working_day in calendar.get_attendances_for_weekdays([day_start_dt.weekday()])[0]:
                    min_from = int((calendar_working_day.hour_from - int(calendar_working_day.hour_from)) * 60)
                    min_to = int((calendar_working_day.hour_to - int(calendar_working_day.hour_to)) * 60)
                    x = work_dt.replace(hour=int(calendar_working_day.hour_from), minute=min_from)
                    if calendar_working_day.hour_to == 0:
                        y = work_dt.replace(hour=0, minute=0) + timedelta(days=1)
                    else:
                        y = work_dt.replace(hour=int(calendar_working_day.hour_to), minute=min_to)
                    working_interval = (x, y)
                    working_intervals += calendar.interval_remove_leaves(working_interval, work_limits)
                for interval in working_intervals:
                    hours += interval[1] - interval[0]

            # Add public holidays
            leaves = leave_obj.search([('name', '=', 'PH'), ('calendar_id', '=', calendar.id)])
            leave_intervals = []
            for l in leaves:
                leave_intervals.append((datetime.strptime(l.date_from, DTF),
                                        datetime.strptime(l.date_to, DTF)
                                        ))
            clean_intervals = calendar.interval_remove_leaves((start_dt, end_dt), leave_intervals)

            for interval in clean_intervals:
                hours += (end_dt - start_dt) - (interval[1] - interval[0])

        return seconds(hours) / 3600.0

    @api.multi
    def validate_time_limits(self, booking_start, booking_end):
        # localize UTC dates to be able to compare with hours in Working Time
        tz_offset = self.env.context.get('tz_offset')
        if tz_offset:
            start_dt = datetime.strptime(booking_start, DTF) - timedelta(minutes=tz_offset)
            end_dt = datetime.strptime(booking_end, DTF) - timedelta(minutes=tz_offset)
        else:
            user_tz = pytz.timezone(self.env.context.get('tz') or 'UTC')
            start_dt = pytz.utc.localize(fields.Datetime.from_string(booking_start)).astimezone(user_tz)
            end_dt = pytz.utc.localize(fields.Datetime.from_string(booking_end)).astimezone(user_tz)
        for calendar in self:
            hours = calendar.get_working_accurate_hours(start_dt, end_dt)
            duration = seconds(end_dt - start_dt) / 3600.0
            if round(hours, 2) != round(duration, 2):
                return False
        return True

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    resource_id = fields.Many2one('resource.resource', 'Resource')
    booking_start = fields.Datetime(string="Date start")
    booking_end = fields.Datetime(string="Date end")
    calendar_id = fields.Many2one('resource.calendar', related='product_id.calendar_id')
    project_id = fields.Many2one('account.analytic.account', compute='_compute_dependent_fields', store=False, string='Contract')
    partner_id = fields.Many2one('res.partner', compute='_compute_dependent_fields', store=False, string='Customer')
    overlap = fields.Boolean(compute='_compute_date_overlap', default=False, store=True)
    automatic = fields.Boolean(default=False, store=True, help='automatically generated booking lines')
    active = fields.Boolean(default=True)
    resource_trigger = fields.Integer(help='''we use this feild in _compute_date_overlap instead of resource_id
    because resource_id is related to pitch in pitch_booking module. If we hadn't done it then _compute_date_overlap would be called
    for each line with the same resource instead of only only for current new line''')

    @api.one
    def write(self, vals):
        result = super(SaleOrderLine, self).write(vals)
        if vals.get('resource_id'):
            vals['resource_trigger'] = vals.get('resource_id')
        return result

    @api.multi
    def _compute_dependent_fields(self):
        for line in self:
            line.partner_id = line.order_id.partner_id
            line.project_id = line.order_id.project_id

    @api.multi
    @api.depends('resource_trigger', 'booking_start', 'booking_end', 'active')
    def _compute_date_overlap(self):
        for line in self:
            if not line.active:
                line.overlap = False
                continue
            overlaps = 0
            if line.resource_id and line.booking_start and line.booking_end:
                ids = getattr(self, '_origin', False) and self._origin.ids or bool(line.id) and [line.id] or []
                overlaps = line.search_count([('active', '=', True),
                                              '&', '|', '&', ('booking_start', '>=', line.booking_start), ('booking_start', '<', line.booking_end),
                                              '&', ('booking_end', '>', line.booking_start), ('booking_end', '<=', line.booking_end),
                                              ('resource_id', '!=', False),
                                              ('id', 'not in', ids),
                                              ('resource_id', '=', line.resource_id.id),
                                              ('state', '!=', 'cancel')])
                overlaps += line.search_count([('active', '=', True),
                                               ('id', 'not in', ids),
                                               ('booking_start', '=', line.booking_start),
                                               ('booking_end', '=', line.booking_end),
                                               ('resource_id', '=', line.resource_id.id),
                                               ('state', '!=', 'cancel')])
            line.overlap = bool(overlaps)

    @api.multi
    @api.constrains('overlap')
    def _check_overlap(self):
        for line in self:
            if line.overlap:
                overlaps_with = self.search([('active', '=', True),
                                             '&', '|', '&', ('booking_start', '>', line.booking_start), ('booking_start', '<', line.booking_end),
                                             '&', ('booking_end', '>', line.booking_start), ('booking_end', '<', line.booking_end),
                                             ('resource_id', '!=', False),
                                             ('id', '!=', line.id),
                                             ('resource_id', '=', line.resource_id.id),
                                             ('state', '!=', 'cancel')])
                overlaps_with += self.search([('active', '=', True),
                                              ('id', '!=', line.id),
                                              ('booking_start', '=', line.booking_start),
                                              ('booking_end', '=', line.booking_end),
                                              ('resource_id', '=', line.resource_id.id),
                                              ('state', '!=', 'cancel')])

                msg = 'There are bookings with overlapping times: %(this)s and %(those)s' % {'this': [line.id], 'those': overlaps_with.ids}
                raise ValidationError(msg)

    @api.multi
    @api.constrains('calendar_id', 'booking_start', 'booking_end')
    def _check_date_fit_product_calendar(self):
        for line in self.sudo():
            if line.state == 'cancel':
                continue
            if line.calendar_id and line.booking_start and line.booking_end:
                if not line.calendar_id.validate_time_limits(line.booking_start, line.booking_end):
                    raise ValidationError(_('Not valid interval of booking for the product %s.') % line.product_id.name)

    @api.multi
    @api.constrains('resource_trigger', 'booking_start', 'booking_end')
    def _check_date_fit_resource_calendar(self):
        for line in self.sudo():
            if line.state == 'cancel':
                continue
            if line.resource_id and line.resource_id.calendar_id and line.booking_start and line.booking_end:
                if not line.resource_id.calendar_id.validate_time_limits(line.booking_start, line.booking_end):
                    raise ValidationError(_('Not valid interval of booking for the resource %s.') % line.resource_id.name)

    @api.multi
    @api.constrains('booking_start')
    def _check_booking_start(self):
        for line in self:
            if not line.booking_start:
                continue
            if datetime.strptime(line.booking_start, DTF) + timedelta(minutes=SLOT_START_DELAY_MINS) < datetime.now():
                raise ValidationError(_('Please book on time in %s minutes from now.') % SLOT_START_DELAY_MINS)

    @api.model
    def search_booking_lines(self, start, end, domain):
        domain.append(('state', '!=', 'cancel'))
        domain.append(('booking_end', '>=', fields.Datetime.now()))
        domain.append('|')
        domain.append('|')
        domain.append('&')
        domain.append(('booking_start', '>=', start))
        domain.append(('booking_start', '<', end))
        domain.append('&')
        domain.append(('booking_end', '>', start))
        domain.append(('booking_end', '<=', end))
        domain.append('&')
        domain.append(('booking_start', '<=', start))
        domain.append(('booking_end', '>=', end))
        return self.search(domain)

    @api.model
    def get_bookings(self, start, end, offset, domain):
        bookings = self.sudo().search_booking_lines(start, end, domain)
        return [{
            'className': 'booked_slot resource_%s' % b.resource_id.id,
            'id': b.id,
            'title': b.resource_id.name,
            'start': '%s+00:00' % b.booking_start,
            'end': '%s+00:00' % b.booking_end,
            'resource_id': b.resource_id.id,
            'editable': False,
            'color': b.resource_id.color
        } for b in bookings]

    @api.onchange('booking_start', 'booking_end')
    def _on_change_booking_time(self):
        domain = {'product_id': []}
        if self.venue_id:
            domain['product_id'].append(('venue_id', '=', self.venue_id.id))
        if self.booking_start and self.booking_end:
            start = datetime.strptime(self.booking_start, DTF)
            end = datetime.strptime(self.booking_end, DTF)
            self.product_uom_qty = (end - start).seconds / 3600
            booking_products = self.env['product.product'].search([('calendar_id', '!=', False)])
            domain_products = []
            domain_products = [p.id for p in booking_products
                               if p.calendar_id.validate_time_limits(self.booking_start, self.booking_end)]
            if domain_products:
                domain['product_id'].append(('id', 'in', domain_products))
        return {'domain': domain}

    @api.onchange('partner_id', 'project_id')
    def _on_change_partner(self):
        if self.order_id and self.order_id.partner_id != self.partner_id:
            self.order_id = None
        if self.order_id and self.order_id.project_id != self.project_id:
            self.order_id = None
        return self.env['sale.order'].onchange_partner_id(self.partner_id.id)

    @api.onchange('order_id')
    def _on_change_order(self):
        if self.order_id:
            self.partner_id = self.order_id.partner_id
            self.project_id = self.order_id.project_id

    @api.model
    def read_color(self, color_field):
        return self.env['resource.resource'].browse(color_field).color

    @api.model
    def create(self, values):
        if not values.get('order_id') and values.get('partner_id'):
            order_obj = self.env['sale.order']
            order_vals = order_obj.onchange_partner_id(values.get('partner_id'))['value']
            order_vals.update({
                'partner_id': values.get('partner_id'),
                'project_id': values.get('project_id')
            })
            order = order_obj.create(order_vals)
            values.update({'order_id': order.id})
        return super(SaleOrderLine, self).create(values)

    @api.onchange('product_id')
    def _on_change_product_id(self):
        if self.product_id:
            name = self.product_id.name_get()[0][1]
            if self.product_id.description_sale:
                name += '\n' + self.product_id.description_sale
            self.name = name
            warning = {}
            if self.product_id.sale_line_warn != 'no-message':
                title = _("Warning for %s") % self.product_id.name
                message = self.product_id.sale_line_warn_msg
                warning['title'] = title
                warning['message'] = message
                if self.product_id.sale_line_warn == 'block':
                    return {'value': {'product_id': False}, 'warning': warning}
                else:
                    return {'warning': warning}

    @api.onchange('product_id', 'partner_id', 'product_uom_qty')
    def _on_change_product_partner_id(self):
        if self.product_id and self.partner_id:
            pricelist = self.partner_id.property_product_pricelist
            if pricelist:
                data = self.product_id_change(pricelist.id, self.product_id.id,
                                              qty=self.product_uom_qty, partner_id=self.partner_id.id)
                for k in data['value']:
                    if not k in ['name']:
                        setattr(self, k, data['value'][k])

    @api.model
    def get_resources(self, venue_id, pitch_id):
        pitch_obj = self.env['pitch_booking.pitch'].sudo()
        venue_obj = self.env['pitch_booking.venue'].sudo()
        if not venue_id:
            venues = venue_obj.search([])
            venue_id = venues[0].id if venues else None
        resources = []
        if pitch_id:
            resources = [pitch_obj.browse(int(pitch_id)).resource_id]
        elif venue_id:
            resources = [p.resource_id for p in pitch_obj.search([('venue_id', '=', int(venue_id))])]
        return [{
            'name': r.name,
            'id': r.id,
            'color': r.color
        } for r in resources]

    @api.model
    def generate_slot(self, r, start_dt, end_dt):
        return {
            'start': start_dt.strftime(DTF),
            'end': end_dt.strftime(DTF),
            'title': r.name,
            'color': r.color,
            'className': 'free_slot resource_%s' % r.id,
            'editable': False,
            'resource_id': r.id
        }

    @api.model
    def del_booked_slots(self, slots, start, end, resources, offset, fixed_start_dt, end_dt):
        now = datetime.now() - timedelta(minutes=SLOT_START_DELAY_MINS) - timedelta(minutes=offset)
        lines = self.search_booking_lines(start, end, [('resource_id', 'in', [r['id'] for r in resources])])
        for l in lines:
            line_start_dt = datetime.strptime(l.booking_start, '%Y-%m-%d %H:%M:00') - timedelta(minutes=offset)
            line_start_dt -= timedelta(minutes=divmod(line_start_dt.minute, SLOT_DURATION_MINS)[1])
            line_end_dt = datetime.strptime(l.booking_end, DTF) - timedelta(minutes=offset)
            while line_start_dt < line_end_dt:
                if line_start_dt >= end_dt:
                    break
                elif line_start_dt < fixed_start_dt or line_start_dt < now:
                    line_start_dt += timedelta(minutes=SLOT_DURATION_MINS)
                    continue
                try:
                    del slots[l.resource_id.id][line_start_dt.strftime(DTF)]
                except:
                    _logger.warning('cannot free slot %s %s' % (
                        l.resource_id.id,
                        line_start_dt.strftime(DTF)
                    ))
                line_start_dt += timedelta(minutes=SLOT_DURATION_MINS)
        return slots

    @api.model
    def get_free_slots_resources(self, domain):
        resources = self.env['resource.resource'].search([('to_calendar', '=', True)])
        return resources

    @api.model
    def get_free_slots(self, start, end, offset, domain):
        leave_obj = self.env['resource.calendar.leaves']
        start_dt = datetime.strptime(start, DTF) - timedelta(minutes=offset)
        end_dt = datetime.strptime(end, DTF) - timedelta(minutes=offset)
        fixed_start_dt = start_dt
        resources = self.get_free_slots_resources(domain)
        slots = {}
        now = datetime.now() - timedelta(minutes=SLOT_START_DELAY_MINS) - timedelta(minutes=offset)
        for r in resources:
            if r.id not in slots:
                slots[r.id] = {}
            start_dt = fixed_start_dt
            while start_dt < end_dt:
                if start_dt < now:
                    start_dt += timedelta(minutes=SLOT_DURATION_MINS)
                    continue
                if r.calendar_id:
                    for calendar_working_day in r.calendar_id.get_attendances_for_weekdays([start_dt.weekday()])[0]:
                        min_from = int((calendar_working_day.hour_from - int(calendar_working_day.hour_from)) * 60)
                        min_to = int((calendar_working_day.hour_to - int(calendar_working_day.hour_to)) * 60)
                        x = start_dt.replace(hour=int(calendar_working_day.hour_from), minute=min_from)
                        if calendar_working_day.hour_to == 0:
                            y = start_dt.replace(hour=0, minute=0) + timedelta(days=1)
                        else:
                            y = start_dt.replace(hour=int(calendar_working_day.hour_to), minute=min_to)
                        if r.has_slot_calendar and x >= now and x >= start_dt and y <= end_dt:
                            slots[r.id][x.strftime(DTF)] = self.generate_slot(r, x, y)
                        elif not r.has_slot_calendar:
                            while x < y:
                                if x >= now:
                                    slots[r.id][x.strftime(DTF)] = self.generate_slot(r, x, x + timedelta(minutes=SLOT_DURATION_MINS))
                                x += timedelta(minutes=SLOT_DURATION_MINS)
                    start_dt += timedelta(days=1)
                    start_dt = start_dt.replace(hour=0, minute=0, second=0)
                else:
                    slots[r.id][start_dt.strftime(DTF)] = self.generate_slot(r, start_dt, start_dt + timedelta(minutes=SLOT_DURATION_MINS))
                    start_dt += timedelta(minutes=SLOT_DURATION_MINS)
                    continue
            leaves = leave_obj.search([('name', '=', 'PH'), ('calendar_id', '=', r.calendar_id.id)])
            for leave in leaves:
                from_dt = datetime.strptime(leave.date_from, '%Y-%m-%d %H:%M:00') - timedelta(minutes=offset)
                to_dt = datetime.strptime(leave.date_to, '%Y-%m-%d %H:%M:00') - timedelta(minutes=offset)
                if r.has_slot_calendar:
                    if from_dt >= now and from_dt >= start_dt and to_dt <= end_dt:
                        slots[r.id][from_dt.strftime(DTF)] = self.generate_slot(r, from_dt, end_dt)
                    else:
                        continue
                else:
                    from_dt = max(now, from_dt)
                    while from_dt < to_dt:
                        slots[r.id][from_dt.strftime(DTF)] = self.generate_slot(r, from_dt, from_dt + timedelta(minutes=SLOT_DURATION_MINS))
                        from_dt += timedelta(minutes=SLOT_DURATION_MINS)

        res = []
        for slot in self.del_booked_slots(slots, start, end, resources, offset, fixed_start_dt, end_dt).values():
            for pitch in slot.values():
                res.append(pitch)
        return res

    @api.multi
    def action_open_sale_order(self):
        view_id = self.env.ref('sale.view_order_form')
        order_obj = self.env['sale.order'].search([('id', '=', self.order_id.id)])
        return {
            'type': 'ir.actions.act_window',
            'name': 'Booking',
            'view_type': 'form',
            'view_mode': 'form',
            'view_id': view_id.id,
            'res_id': order_obj.id,
            'res_model': 'sale.order',
            'target': 'current',
        }

class ProductTemplate(models.Model):
    _inherit = 'product.template'

    calendar_id = fields.Many2one('resource.calendar', string='Working time')

class SaleOrderAmountTotal(osv.osv):
    _inherit = 'sale.order'

    def _amount_all_wrapper(self, cr, uid, ids, field_name, arg, context=None):
        return super(SaleOrderAmountTotal, self)._amount_all_wrapper(cr, uid, ids, field_name, arg, context=None)

    def _get_order(self, cr, uid, ids, context=None):
        result = {}
        for line in self.pool.get('sale.order.line').browse(cr, uid, ids, context=context):
            result[line.order_id.id] = True
        return result.keys()

    _columns = {
        'amount_total': old_api_fields.function(_amount_all_wrapper, digits_compute=dp.get_precision('Account'), string='Total',
                                                store={
                                                    'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
                                                    'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty', 'state'], 10),
        },
            multi='sums', help="The total amount."),
    }

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    @api.multi
    @api.constrains('state')
    def _check_state(self):
        if self.search_count([('state', 'not in', ['draft'])]) and \
           self.env['sale.order.line'].search_count([('order_id', '=', self.id), ('overlap', '=', 'True')]):
            raise ValidationError(_('There are lines with overlap in this order. Please move overlapping lines to another time or resource'))


import time

from arena_api.callback import callback, callback_function
from arena_api.system import system

def create_devices_with_tries():
    """
    This function waits for the user to connect a device before raising
    an exception
    """

    tries = 0
    tries_max = 6
    sleep_time_secs = 10
    while tries < tries_max:  # Wait for device for 60 seconds
        devices = system.create_device()
        if not devices:
            print(
                f'Try {tries+1} of {tries_max}: waiting for {sleep_time_secs} '
                f'secs for a device to be connected!')
            for sec_count in range(sleep_time_secs):
                time.sleep(1)
                print(f'{sec_count + 1 } seconds passed ',
                      '.' * sec_count, end='\r')
            tries += 1
        else:
            print(f'Created {len(devices)} device(s)')
            return devices
    else:
        raise Exception(f'No device found! Please connect a device and run '
                        f'the example again.')

# Must have the decorator on the callback function
@callback_function.system.on_device_disconnected
def print_disconnected_device_info(device):
    """
    Print information from the callback
        When registered device is disconnected
        System fire a callback which pass
        disconnected device to this function.
    """
    print(f'\nDevice was disconnected:\n\t{device}\n')
    print('Press enter to cotinue')

def example_entry_point():
    """
    Callbacks: On Device Disconnected
        This example demonstrates how to register a callback to get
        notified when a device has disconnected. At first this example
        will enumerate devices then if there is any device fount it will
        regsiter a disconnect callback for a discovered device.
        Next the program will wait until a user inputs an exit
        command. While this example waits for input, feel free to
        disconnect the device. When the device is disconnected the callback
        will be triggered and it will print out info of the device
        that was removed by using print_disconnected_device_info function.
    """

    # Create a device
    devices = create_devices_with_tries()
    device = devices[0]

    print(f'Device used in the example:\n\t{device}')

    # -------------------------------------------------------------------------
    # Register a disconnect callback test

    handle = callback.register(
        system, print_disconnected_device_info, watched_device=device)

    input(f'Waiting for user to disconnect a device'
          f' or press enter to continue\n')

    print('Check if device is connected:')
    if device.is_connected() is False:
        print('Device is disconnected\n')
    else:
        print('Device is connected\n')

    # -------------------------------------------------------------------------
    # Clean up

    # Deregester an individual disconnect callback
    callback.deregister(handle)

    # Destroy device
    #   stop_stream() call is optional and will
    #   automatically be called for any remaining devices when the system
    #   module is unloading.
    system.destroy_device()
    print('Destroyed all created devices')

if __name__ == '__main__':
    print('\nWARNING:\nTHIS EXAMPLE MIGHT CHANGE THE DEVICE(S) SETTINGS!')
    print('\nExample started\n')
    example_entry_point()
    print('\nExample finished successfully')


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import warnings
import sys
import argparse

from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Flatten
from tensorflow.python.keras.layers import Dense
from tensorflow.python.keras.applications import vgg16

class Runner(object):

    def __init__(self):

        self.logDirectory, self.configs = self.parseArgs()
        self.currentDir = os.path.dirname(os.path.abspath(__file__))
        self.pathToAdvertismentDetectionSourceCode = self.currentDir + '/src'
        self.pathToDataPathesFile = self.currentDir + '/src/pathVariables.txt'
        self.pathToWeights = str(self.logDirectory) + '/model.h5'
        self.pathToSaveHistory = str(self.logDirectory) + '/history'

        sys.path.insert(0, self.pathToAdvertismentDetectionSourceCode)
        self.data = self.readInData()
        self.testIndices = self.data.testIndices
        self.model = self.getModel(input_shape = self.data.imageShape)

    def start(self):
        from advertisementDetection import RecognitionSystem
        recogSystem = RecognitionSystem(data = self.data, pathToWeights = self.pathToWeights, pathToSaveHistory = self.pathToSaveHistory, configs = self.configs, model = self.model, testIndices=self.testIndices)
        recogSystem.data.printInformationAboutData()
        recogSystem.printModelSummary()
#        recogSystem.trainModel()
        recogSystem.evaluateModel()

    def readInData(self):
        with open(self.pathToDataPathesFile) as pathVariables:
            pathes = pathVariables.read().splitlines()
            imagesPath = pathes[0]
            labelsPath = pathes[1]
        normalizeData = self.configs['normalizeData'] if 'normalizeData' in self.configs else False
        from advertisementDetection import Preprocessor
        preprocessedData = Preprocessor(imagesPath, labelsPath, normalizeData = normalizeData)
        return preprocessedData

    def getModel(self, input_shape, classes=1):
        vgg16_model = vgg16.VGG16(include_top = False, weights = 'imagenet', input_shape = input_shape)

        model = Sequential()
        for layer in vgg16_model.layers:
            model.add(layer)
        for layer in model.layers:
            layer.trainable = False

        model.add(Flatten(name='flatten'))
        model.add(Dense(1000, activation='relu'))
        model.add(Dense(classes, activation = 'sigmoid'))

        return model

    def parseArgs(self):
        configs = {
            'learningRate':1e-4,
            'decay':1e-6,
            'momentum':0.9,
    #        'normalizeData':True,
            'nesterov':True,
            'batchSize':20,
            'epochs':15,
            'loss':'binary_crossentropy',
            'metrics':['accuracy']
        }

        parser = argparse.ArgumentParser(description='Description of your program')
        parser.add_argument('--logDir', help='The folder to save everything', required=True)
        parser.add_argument('--learningRate')
        parser.add_argument('--decay')
        parser.add_argument('--momentum')
        parser.add_argument('--batchSize')
        parser.add_argument('--epochs')

        args = vars(parser.parse_args())

        logDir = args['logDir']

        for arg in configs:
            if arg in args and args[arg] is not None:
                if(arg in ['learningRate','decay', 'momentum']):
                        configs[arg] = float(args[arg])
                else:
                        configs[arg] = int(args[arg])

        print(configs)
        return logDir, configs

if __name__ == "__main__":
    runner = Runner()
    runner.start()


"""
This bot listens to port 5002 for incoming connections from Facebook. It takes
in any messages that the bot receives and echos it back.
"""
from flask import Flask, request
from pymessenger.bot import Bot
import requests
import ipdb
app = Flask(__name__)
TOKEN = "<access_token>"
bot = Bot(TOKEN)

@app.route("/webhook", methods = ['GET', 'POST'])
def hello():
    if request.method == 'GET':
        if (request.args.get("hub.verify_token") == "<token you define during"\
                "the verification phase>"):
                return request.args.get("hub.challenge")
    if request.method == 'POST':
        output = request.json
        event = output['entry'][0]['messaging']
        for x in event:
            if (x.get('message') and x['message'].get('text')):
                message = x['message']['text']
                recipient_id = x['sender']['id']
                bot.send_text_message(recipient_id, message)
            else:
                pass
        return "success"

if __name__ == "__main__":
    app.run(port=5002, debug=True)


import sys
from collections import deque

def bfs(n,r):
    q = deque()
    q.append(r)
    visited = set(range(1,n+1))
    visited.remove(r)
    answer[r] = 0
    while q:
        cur_node = q.popleft()
        cut[cur_node] = set(cut[cur_node])
        for i in visited - cut[cur_node]:
            q.append(i)
            visited.remove(i)
            answer[i] = answer[cur_node]+1

n,m = map(int,input().split())
cut = [[j]for j in range(n+1)]
answer = [-1 for _ in range(n+1)]
for i in range(m):
    u,v = map(int,sys.stdin.readline().split())
    cut[u].append(v)
    cut[v].append(u)
bfs(n,1)

for i in range(1,n+1):
    print(answer[i])


from sys import float_repr_style
from typing import Optional, List, Dict
from pydantic import BaseModel, ValidationError, root_validator, validator
from datetime import date, datetime
from dateutil.relativedelta import relativedelta

class stock(BaseModel):
    stock_code: str
    stock_name: str
    sector_code: str

    @root_validator()
    def check_stock(cls, values):
        assert (
            len(values.get("stock_code")) >= 3 and len(values.get("stock_code")) <= 5
        ), "stock_code must be between 3 and 5 characters long"
        assert (
            len(values.get("stock_name")) <= 30
        ), "stock_name must be less than 30 characters long"
        assert (
            len(values.get("sector_code")) == 3
        ), "sector_code must be exactly 3 characters long"
        return values

class stock_collection:
    stockCollection = []

    def __init__(self, stocks: List):
        # make sure there aren't any duplicate stock codes passed in
        if self.checkUnique(stocks):
            [
                self.stockCollection.append(
                    stock(
                        stock_code=x.stock_code,
                        stock_name=x.stock_name,
                        sector_code=x.sector_code,
                    )
                )
                for x in stocks
            ]
        else:
            return False

    def diffCollection(self, queryStocks: List):
        # make sure there aren't any duplicate stocks being queried
        assert self.checkUnique(queryStocks), (
            "Duplicate stock_codes in list: [ "
            + ", ".join([str(elem) for elem in queryStocks])
            + " ]"
        )
        notInCollection = []

        if all(elem in self.stockCollection for elem in queryStocks):
            return []
        else:
            notFound = []
            for qStock in queryStocks:
                found = False
                for cStock in self.stockCollection:
                    if qStock == cStock.stock_code:
                        found = True
                        break
                if not found:
                    notFound.append(qStock)
            return notFound

    def checkUnique(self, someList: List):
        return len(someList) == len(set(someList))

    def getDuplicates(self, someList: List):
        seen = set()
        uniq = [x for x in someList if x in seen or seen.add(x)]
        return seen

class stock_filter(BaseModel):
    stock_code: Optional[List] = None

    @root_validator()
    def check_stock_filter(cls, values: Dict[str, List[str]]) -> Dict[str, List[str]]:
        # optional, so none is okay
        if values.get("stock_code") == None:
            # but just make sure there's no other attributes set
            assert len(values) == 0, "invalid attribute: " + str(values.keys())
            return values

        assert len(values) == 1, "multiple attributes given, expecting just stock_code"
        assert "stock_code" in values, "unknown attribute given in " + str(
            values.keys()
        )
        for x in values.get("stock_code"):
            assert len(x) >= 2 and len(x) <= 6, (
                "stock_codes must be between 3 and 5 characters long.  Failed on '"
                + x
                + "'"
            )

        return values

class sector_filter(BaseModel):
    sector_code: Optional[List] = None

    @root_validator()
    def check_sector_filter(cls, values: Dict[str, List[str]]) -> Dict[str, List[str]]:
        # optional, so none is okay
        if values.get("sector_code") == None:
            # but just make sure there's no other attributes set
            assert len(values) == 0, "invalid attribute: " + str(values.keys())
            return values

        assert len(values) == 1, "multiple attributes given, expecting just sector_code"
        assert "sector_code" in values, "unknown attribute given in " + str(
            values.keys()
        )
        for x in values.get("sector_code"):
            assert len(x) == 3, (
                "sector_codes must be between 3 and 5 characters long.  Failed on " + x
            )

        return values

class date_filter(BaseModel):
    # inputs
    start_date: Optional[str] = None
    end_date: Optional[str] = None
    period: Optional[str] = None

    # date values that we'll search with
    start: Optional[date] = None
    end: Optional[date] = None
    periodSymbols = ["d", "w", "m", "y"]

    @validator("start_date", "end_date", pre=True)
    def check_date_type(cls, v):
        try:
            datetime.strptime(v, "%Y-%m-%d")
            return v
        except:
            assert False, "dates must be formatted as yyyy-mm-dd"

    @root_validator()
    def check_attributes(cls, values):
        # can't set period and start/end
        if values.get("period") != None:
            # make sure they haven't also set a start or end date
            assert (
                values.get("start_date") == None
            ), "Cannot specify 'period' and 'start_date'"
            assert (
                values.get("end_date") == None
            ), "Cannot specify 'period' and 'end_date'"

            assert (
                len(values.get("period")) > 1
            ), "Must specify an integer and a period symbol.  Examples: 1d, 4w, 7y"
            periodSymbol = values.get("period")[-1]
            assert periodSymbol in values.get("periodSymbols"), (
                "Unrecognised period symbol '" + periodSymbol + "'"
            )
        else:
            # can't set end to be before start
            # don't need to worry about typing for start_date or end_date since its validated already
            if values.get("start_date") != None and values.get("end_date") != None:
                start = datetime.strptime(values.get("start_date"), "%Y-%m-%d")
                end = datetime.strptime(values.get("end_date"), "%Y-%m-%d")
                assert start < end, "Cannot specify 'end_date' before 'start_date'"
        return values

    def processSearchDates(self):
        # they didn't give any input at all
        if self.period == None and self.start_date == None and self.end_date == None:
            # search without a date range
            # this technically should never run, given the driver has to check for this anyway when issuing the query
            return True
        elif self.period != None:
            # use period
            return self.setPeriod()
        elif self.start_date == None and self.end_date != None:
            # no start, but end specified. go from the beginning of records
            self.start = datetime.strptime("2001-01-01", "%Y-%m-%d")
            self.end = self.end_date
            return True
        elif self.start_date != None and self.end_date == None:
            # specified start, but no end. go from start until today
            self.start = datetime.strptime(self.start_date, "%Y-%m-%d")
            self.end = date.today()
            return True
        elif self.start_date != None and self.end_date != None:
            # specified a start and an end date
            self.start = datetime.strptime(self.start_date, "%Y-%m-%d")
            self.end = datetime.strptime(self.end_date, "%Y-%m-%d")
            return True
        else:
            # logically this can't happen.... famous last words
            return False

    def setPeriod(self):
        # try catches any issues with date and relativedelta
        try:
            self.end = date.today()
            if self.period[-1] == "d":
                self.start = date.today() + relativedelta(days=-int(self.period[:-1]))
            elif self.period[-1] == "w":
                self.start = date.today() + relativedelta(weeks=-int(self.period[:-1]))
            elif self.period[-1] == "m":
                self.start = date.today() + relativedelta(months=-int(self.period[:-1]))
            elif self.period[-1] == "y":
                self.start = date.today() + relativedelta(years=-int(self.period[:-1]))
            else:
                # default to days
                self.start = date.today() + relativedelta(days=-int(self.period[:-1]))
            return True
        except:
            return False


from .. import subparsers
from . import load_mixin, save_mixin, weights_mixin
from .utils import OptionStringHelpFormatter, formatter_factory

compile_parser = subparsers.add_parser(
    "compile",
    description="configure the model for training",
    formatter_class=formatter_factory(
        OptionStringHelpFormatter,
        max_help_position=30
    )
)

compile_mixins = {
    weights_mixin: {},
    load_mixin: {},
    save_mixin: {
        "required": True
    }
}
for mixin, kwargs in compile_mixins.items():
    mixin(compile_parser, **kwargs)

compile_group = compile_parser.add_argument_group(
    "compilation parameters"
)
compile_group.add_argument(
    "--optimizer",
    help="name of optimizer",
    metavar="<optimizer>",
),
compile_group.add_argument(
    "--loss",
    help="name of objective function",
    metavar="<loss>",
),
compile_group.add_argument(
    "--metric",
    action="append",
    help="metric to be evaluated by the model during training and testing",
    metavar="<metric>",
)