"""ConvLSTM model, ConvLSTMHyperparameter and random hyperparameter generator"""

import numpy as np
import tensorflow as tf
import tensorflow.contrib.slim as slim
from base import BaseModel
from saver import Saver

class ConvLSTM(BaseModel):
    """ConvLSTM model

    The ConvLSTM model is built with stack of convolution and LSTM layers. The model configuration
    is set with constructor's `hyperparameter` argument.

    Args:
        - `hyperparameter`: instance of `ConvLSTMHyperparameter` as the model's configuration
        - `logdir`:         directory path to save summary and checkpoint

    """
    def __init__(self, hyperparamter, logdir):
        super(ConvLSTM, self).__init__()

        self.hyperparameter = hyperparamter

        self.build_graph()

        self.session = tf.InteractiveSession(graph=self.target.graph)
        self.saver = Saver(self.session, logdir)

        self.session.run(tf.global_variables_initializer())
        self.session.run(tf.local_variables_initializer())

    def build_graph(self):
        """Construct the graph of neural network

        As of 18-07-2017, the architecture is constructed with these configuration:
            1. Convolution layers
            2. LSTM layers
            3. Dropout
            4. Softmax
            5. Cross entropy loss function
            6. RMSProp optimizer

        Each layer's hyperparameter is defined in `self.hyperparameter`.

        """
        features = self.magnitude()
        conv_input = tf.reshape(features, [-1, 100, 8])
        conv = slim.stack(conv_input, slim.convolution, self.hyperparameter.conv_layers,
                          scope='conv')
        lstm = self._lstm_stack(conv)
        lstm_dropout = slim.dropout(lstm, self.hyperparameter.keep_prob,
                                    is_training=self.is_training, scope='lstm_dropout')
        self.output = slim.fully_connected(lstm_dropout, 6, activation_fn=tf.nn.softmax,
                                           scope='output')
        self.train_op = self.create_train_op(self.hyperparameter.learning_rate)
        self.accuracy_op = self.create_accuracy_op()

    def _lstm_stack(self, tensor_in):
        with tf.name_scope('LSTM'):
            lstm_input = tf.transpose(tensor_in, [1, 0, 2])
            lstm = [tf.contrib.rnn.BasicLSTMCell(num_units) for num_units in
                    self.hyperparameter.lstm_layers]
            lstm_cells = tf.contrib.rnn.MultiRNNCell(lstm)
            lstm_outputs, _ = tf.nn.dynamic_rnn(lstm_cells, lstm_input, dtype=tf.float32,
                                                time_major=True)

            return lstm_outputs[-1]

class ConvLSTMHyperparameter:
    """Hyperparameter for `ConvLSTM` model

    Args:
        - `conv_layers`:    configuration for convolutional layers
        - `lstm_layers`:    configuration for LSTM layers
        - `keep_prob`:      keep probability for dropout
        - `learning_rate`:  learning rate for optimizer

    Example:
        - `conv_layers = [(128, 5), (128, 5)]` creates two convolution layers, each with 128 output
          and kernel size of 5
        - `lstm_layers = [128, 128]` creates two LSTM layers, each with 128 hidden unit

    """
    def __init__(self, conv_layers, lstm_layers, keep_prob, learning_rate):
        self.conv_layers = conv_layers
        self.lstm_layers = lstm_layers
        self.keep_prob = keep_prob
        self.learning_rate = learning_rate

def generate_hyperparameters(variations, conv_layers=None, lstm_layers=None, keep_prob=None,
                             learning_rate=None):
    """Generate a list of random `ConvLSTMHyperparameter` with length of `variations`

    If `conv_layers`, `lstm_layers`, `keep_prob` or `learning_rate` is `None`, a random value will
    be provided for each parameter.

    Args:
        - `variations`: number of variation to generate
        - `conv_layers`: convolutional layers hyperparameter
        - `lstm_layers`: LSTM layers hyperparameter
        - `keep_prob`: dropout keep probability
        - `learning_rate`: optimizer learning rate

    Returns:
        list of `ConvLSTMHyperparameter` with random value

    """
    hyperparameters = []

    for _ in range(variations):
        hyperparameter = ConvLSTMHyperparameter(
            conv_layers if conv_layers else random_conv_layers(),
            lstm_layers if lstm_layers else random_lstm_layers(),
            keep_prob if keep_prob else random_keep_prob(),
            learning_rate if learning_rate else random_learning_rate(-4, -3)
        )
        hyperparameters.append(hyperparameter)

    return hyperparameters

def random_conv_layers():
    """Generates random convolutional layer hyperparameter

    Returns:
        list of hyperparameter for each convolutional layer

    """
    number_of_layers = np.random.randint(2, 5)
    num_outputs = np.random.choice([32, 64, 128])

    layers = []
    for _ in range(number_of_layers):
        layers.append((num_outputs, 5))

    return layers

def random_lstm_layers():
    """Generates random LSTM layer hyperparameter

    Returns:
        list of hyperparameter for each LSTM layer

    """
    number_of_layers = np.random.randint(2, 5)
    num_units = np.random.choice([32, 64, 128])

    layers = []
    for _ in range(number_of_layers):
        layers.append(num_units)

    return layers

def random_keep_prob():
    """Generates random dropout keep probability"""
    return np.random.uniform(0.2, 0.8)

def random_learning_rate(lr_min, lr_max):
    """Generates random learning rate"""
    return 10 ** np.random.uniform(lr_min, lr_max)


# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""
import pandas as pd
import numpy as np
result = pd.read_csv('denco.csv')
result
result.columns
df=result

df1=df.groupby('custname').size()
df1
df2=df.groupby('custname').agg({ "custname" : ["count"] })
df2

df3=df.pivot_table(aggfunc ={'revenue':np.sum},index=['custname'])
df3.sort_values('revenue',ascending=False)

df4=df.pivot_table(index=["partnum"],aggfunc ={'revenue':np.sum})
df4.sort_values('revenue',ascending= False)

df5=df.pivot_table(index=["partnum"],aggfunc ={'margin':np.sum})
df5.sort_values('margin',ascending= False)


"""
Compare Game of Life grids represented in the Full-matrix (FM) format.

Every file's first row will indicate the total number of rows and cols of GoL's matrix, followed by a line for each row, wherein 'X' will indicate alive cells, whereas blank spaces dead cells. That matrix will represent the initial state (0-th generation) of GoL's evolution. A delimiter of 100 '*' characters will separate it from the final state matrix (N-th generation).
"""

import argparse
import os

import numpy as np

from concurrent.futures import thread # Parallelize comparisons

DELIMITER = "*" * 100

def parse_args():
    parser = argparse.ArgumentParser(add_help=False,
                            description='Comparing results from Game of Life experiments.')

    # Split required/optional args
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')

    # Add back help
    optional.add_argument(
        '-h',
        '--help',
        action='help',
        default=argparse.SUPPRESS,
        help='Show this help message and exit'
    )

    required.add_argument('--gt',  type=str, required=True, nargs=None,
                        help="The filename of GoL's ground-truth grid")
    required.add_argument('--cmp', type=str, required=True, nargs='+',
                        help="The list of filenames of GoL's grids to compare. ")

    return parser.parse_args()

if __name__ == "__main__":
    args = parse_args()

    print("[*] Reading GoL's initial ground-truth matrix...")

    # Read the first line of the ground-truth file,
    # which contains GoL matrix's number of rows and columns
    gt_file = open(args.gt, "r")

    first_line_gt = gt_file.readline().split()
    rows, cols = list(map(lambda val: int(val.strip()),
                          first_line_gt))

    ###############################
    # 1. Compare initial matrices #
    ###############################

    # Initialize the ground-truth's NumPy matrix with
    # that number of rows and columns
    gt = np.zeros((rows, cols)).astype(int)

    # Fill the ground-truth matrix
    for i, line in enumerate(gt_file):
        line = line.rstrip("\n")
        if (line == DELIMITER):
            break

        row = list(map(lambda val: 1 if val == 'X' else 0, line))
        gt[i] = np.array(row)

    print("[*] Read GoL's initial ground-truth matrix.\n")

    def compare_initial(filename):
        cmp_file = open(filename, "r")
        first_line_cmp = cmp_file.readline().split()

        rows_cmp, cols_cmp = list(map(lambda val: int(val.strip()),
                                      first_line_cmp))

        if rows_cmp != rows or cols_cmp != cols:
            return [False, cmp_file]
        else:
            cmp = np.zeros((rows, cols)).astype(int)

            for i, line in enumerate(cmp_file):
                line = line.rstrip("\n")
                if (line == DELIMITER):
                    break

                row = list(map(lambda val: 1 if val == 'X' else 0, line))
                cmp[i] = np.array(row)

            return [np.allclose(gt, cmp), cmp_file, cmp]

    print("[*] Reading GoL's initial comparison matrices...")

    with thread.ThreadPoolExecutor(max_workers=16) as exec:
        cmp_results = list(exec.map(compare_initial, args.cmp)) # Store comparison results

    print("[*] Read GoL's initial comparison matrices.\n")

    basename_cmps = []
    basename_gt = os.path.basename(args.gt)

    # Print initial comparison results
    for i, filename in enumerate(args.cmp):
        basename_cmp = os.path.basename(filename)
        basename_cmps.append(basename_cmp)

        # cmp_results[i][0] := Initial matrix comparison result
        # cmp_results[i][1] := Open file pointer or None
        # cmp_results[i][2] := Initial matrix, if it exists

        if cmp_results[i][0]:
            print(basename_gt, "initial matrix is equal to", basename_cmp)
        else:
            print(basename_gt, "initial matrix is different from", basename_cmp)

            # Close file pointers whose initial matrix
            # is different from the ground-truth.
            cmp_results[i][1].close() # Contains the open file pointer
            cmp_results[i][1] = None

    #############################
    # 2. Compare final matrices #
    #############################

    print("\n[*] Reading GoL's final ground-truth matrix...")

    # Fill the ground-truth matrix
    for i, line in enumerate(gt_file):
        line = line.rstrip("\n")
        if (line == DELIMITER):
            break

        row = list(map(lambda val: 1 if val == 'X' else 0, line))
        gt[i] = np.array(row)

    gt_file.close()

    print("[*] Read GoL's final ground-truth matrix.\n")

    def compare_final(data):
        # data[0] := Initial matrix comparison result
        # data[1] := Open file pointer or None
        # data[2] := Initial matrix, if it exists

        if not data[0]:
            return False
        else:
            for i, line in enumerate(data[1]):
                line = line.rstrip("\n")
                if (line == DELIMITER):
                    break

                row = list(map(lambda val: 1 if val == 'X' else 0, line))
                data[2][i] = np.array(row)

            data[1].close() # Close file pointer

            return np.allclose(gt, data[2])

    print("[*] Reading GoL's final comparison matrices...")

    with thread.ThreadPoolExecutor(max_workers=16) as exec:
        cmp_results = list(exec.map(compare_final, cmp_results)) # Store comparison results

    print("[*] Read GoL's final comparison matrices.\n")

    # Print final comparison results
    for i, filename in enumerate(args.cmp):
        basename_cmp = basename_cmps[i]

        if cmp_results[i]:
            print(basename_gt, "final matrix is equal to", basename_cmp)
        else:
            print(basename_gt, "final matrix is different from", basename_cmp)


"""
DO NOT RUN THIS INSIDE A VIRTUAL ENVIORMENT, THIS WILL BREAK IF YOU DO. I DO NOT KNOW WHY
"""

import time
import os

#For annotation
from typing import List

#For error handling
import traceback

from pynput import keyboard as Keyboard
#Import controllers to simulate keyboard and mouse movements of recorded keys
from pynput.keyboard import Controller as KeyboardController
from pynput.keyboard import Listener as KeyboardListener
from pynput.keyboard import Key
#Import listeners to listen to keyboard/mouse inputs
from pynput.mouse import Button, Controller as MouseController
from pynput.mouse import Listener as MouseListener
from sys import platform

def _get_os_config_directory() -> str:
    #directory where macros and keybins are stored. initialized with illegial characters to stop accidental macros being stored in root...
    set_os_macroconfig_store = "!?[]{]\""

    if platform == "linux" or platform == "linux2":
        set_os_macroconfig_store = os.environ['HOME'] + "/.local/pymacromaker"
        pass
        # linux
    elif platform == "darwin":
        raise Exception("No keybind/macro directory set for this OS X. Fix that then remove this exception")
        pass
        # OS X
    elif platform == "win32":
        raise Exception("No keybind/macro directory set for windows. Fix that then remove this exception.")
        pass
    else:
        raise Exception("Huh, what OS is this? Anyway, no keybind/macro directory set for this OS. ")
        # Windows...
    return set_os_macroconfig_store

place_to_round_to = 2

#print debug stuff if true
debug = False

#Keys which are ignored due to them being used to input other keys(caps lock, shift, etc..), or by merit of them being inconsistent
ignored_keys = ["Key.shift"]

#stirng used to seperate variables in macro storage.
sep_str = " | "

###
#Macro variable name space. Since pointing to in-code variables themselves would cause any pre-existing macro file to break anytime a variable name is changed in new versions, I've instead opted to make a big list of unsorted variables
#that correlate to respective in-code key_clss variables. This way, when the macro is being read from a .txt, the name in code and in the macro file can be indepdendent and or different.

#I.E:
# In code name of mouse position: mouse_pos_xy
# in macro file name of mouse position: mouse_pos

# If I want to change mouse_pos name in code, I can, without breaking macro files made before the variable name change.
###
control_type_variable_name = "control_type"
key_name_variable_name = "key"
hold_duration_variable_name = "hold_duration_s"
press_end_at_epoch_variable_name = "press_end_time_at_epoch"
mouse_pos_variable_name = "mouse_pos"

#For some reason, pynput doesnt have an internal dictionary to convert non alphabetic keys to pynput presses, so I need to make a dictionary to do that..
key_to_object_dict = {
    #non alpha keys
    "Key.enter": Key.enter,
    "Key.ctrl": Key.ctrl,
    "Key.ctrl_r": Key.ctrl_r,
    "Key.space": Key.space,
    "Key.tab": Key.tab,
    "Button.left": Button.left,
    "Button.right": Button.right
}

#Sometimes, when keys are pressed and released, the press event is not caught due to typing too fast/other factors. this is the value the hold duration defaults to if that happens.
default_press_hold_if_press_event_not_triggered = 0.1

#nice website to test keypresses/durations:
#https://www.onlinepianist.com/virtual-piano

class key_presses():
    """ Object keypresses are stored in

    mouse/keyboard use pynput mouse/keyboard control. See: https://www.tutorialspoint.com/how-to-control-your-mouse-and-keyboard-using-the-pynput-library-in-python

    hold_duration_s: how long key is held for in s
    key: the key it self, stored as a string/keyboard/mouse object. Read as a string and do not modify.
    press_end_time_at_epoch: Used for press_stored_key, see there for details.
    """
    def __init__(self):

        self.mouse = MouseController()
        self.keyboard = KeyboardController()
        #how long the key/click was help down for.
        self.hold_duration_s = 0.0

        self.keys= None

        #Mouse pos at time of click/press
        self.mouse_pos_xy = None

        #(If enabled) track when keypress ended at time epoch, so that another key that comes after, it will wait for the duration of time the user waited
        self.press_end_time_at_epoch = 0

        #Control type, weather the key is a mouse key or a keyboard key. determiens how the program should handle simulating inputs
        self._control_type = None

        self.keyboard_listener = KeyboardListener(on_press=self._on_press, on_release=self._on_release)
        self.mouse_listener = MouseListener(on_click=self._on_click)

    def __str__(self):
        #I could probably recycle the variable names here, but then theres an issue of "oh no, I broke everyone's macros because I changed keys to key!"
        return control_type_variable_name + "]" + str(self._control_type) + sep_str + key_name_variable_name + "]" + str(self.keys) + sep_str + hold_duration_variable_name + "]" + str(self.hold_duration_s) + sep_str + press_end_at_epoch_variable_name + "]" + str(self.press_end_time_at_epoch) + sep_str + mouse_pos_variable_name + "]" + str(self.mouse_pos_xy)

    def __repr__(self):
        return control_type_variable_name + "]" + str(self._control_type) + sep_str + key_name_variable_name + "]" + str(self.keys) + sep_str + hold_duration_variable_name + "]" + str(self.hold_duration_s) + sep_str + press_end_at_epoch_variable_name + "]" + str(self.press_end_time_at_epoch) + sep_str + mouse_pos_variable_name + "]" + str(self.mouse_pos_xy)

    def press_stored_key(self, epoch_time_to_wait_before_press=0, hold_duration_override=0):
        """
        press a stored keypress based on how it was pressed when they object that represents its keypressed was stored.

        This method handles the finickyness of pynput keypresses, and also has optional perameters for modifiers on how/when to press keys
         1. epoch_time_to_wait_before_press: Pass a different key's "press_end_time_at_epoch", and the key will wait to press for the duration of time between when the two keys were pressed.
         simulate user input delay
         2. hold_duration_override: override the durration of time the original keypress was held down for, and instead hold it down for the time the override time in seconds. Keep at 0 for no
         override

        NOTE: Currently, "epoch_time_to_wait_before_press" is experimental, and I havent found a way to get the sleep difference between the times to be accurate. there is a small but noticable
        delay, that gets worse the larger you hold the key down for, and im not sure how to fix it.
        """
        if(hold_duration_override != 0):
            self.hold_duration_s = hold_duration_override

        #Prevent accidental pressing of mouse key by releasing the mouse key press
        self.mouse.release(Button.left)
        self.mouse.release(Button.right)

        if(self._control_type == "Mouse"):

            self.mouse.position = self.mouse_pos_xy

            if(epoch_time_to_wait_before_press != 0):
                if(debug == True):
                    print("waiting + " + str(self.press_end_time_at_epoch - epoch_time_to_wait_before_press))
                time.sleep(self.press_end_time_at_epoch - epoch_time_to_wait_before_press)
            #if(debug):
            #    print(type(self.keys))
            self.mouse.press(self.keys)
            time.sleep(self.hold_duration_s)
            self.mouse.release(self.keys)
        elif(self._control_type == "Keyboard"):

            self.mouse.position = self.mouse_pos_xy
            try:
                if(epoch_time_to_wait_before_press != 0):
                    if debug == True:
                        print("waiting + " + str(self.press_end_time_at_epoch - epoch_time_to_wait_before_press))
                        time.sleep(self.press_end_time_at_epoch - epoch_time_to_wait_before_press)

                self.keyboard.press(self.keys)
                time.sleep(self.hold_duration_s)
                self.keyboard.release(self.keys)
            except Exception as e:
                print("ran into error for keyboard press.")
                print("Actual error: " + traceback.format_exc() )
        else:
            raise Exception("Unknown control type: entered control type: " + str(self._control_type))

    #start listening for presses/mouse presses
    def listen_start(self):
        """To start listening for a keypress, call this method.
        Once a keypress/mouse-click is detected, relevant information about when the key was pressed, how long, and where, etc.. is stored inside the Key object used to call this method."""
        self.keyboard_listener.start()
        self.mouse_listener.start()
        self.keyboard_listener.join()
        self.mouse_listener.join()

    #Stop listening for keyboard presses/mouse presses
    def _listen_stop(self):
        self.mouse_listener.stop()
        self.keyboard_listener.stop()

    def _on_press(self, input_key):
        """
        method that is called when a keyboard keypress is detected.
        """
        if(ignored_keys.__contains__(str(input_key))):
            pass
        else:
            #print(str(input_key) + 'key pressed')

            if(str(input_key ) == "Key.shift"):
                print("shifting key")

            if self.hold_duration_s == 0:
                self.hold_duration_s = time.time()

    def _on_release(self, input_key):
        #print(str(input_key) + "key released")

        if(ignored_keys.__contains__(str(input_key))):
            pass
            #print(str(input_key) + " was released, but is classed as a key to ignore. Will not be entered as a part of the macro.")
        else:
            self._control_type, self.keys, self.hold_duration_s, self.press_end_time_at_epoch, self.mouse_pos_xy = "Keyboard", input_key, round(time.time() - self.hold_duration_s, place_to_round_to), time.time(), self.mouse.position

            if(debug):
                print(self._control_type + " pressed, current key is now set to " + str(self))

            #sometimes, if you type keys too fast, the press event for the key is not triggered and its only caught as a release. this sets it to 0.1 seconds by default
            if(self.hold_duration_s > 999999):
                print("press event not triggered, setting keypress duration to " + str(default_press_hold_if_press_event_not_triggered) + " seconds")
                self.hold_duration_s = default_press_hold_if_press_event_not_triggered

            self._listen_stop()

    def _on_click(self, mouse_x, mouse_y, button, click):

        if(click):
            self.captured_time = time.time()
            self.hold_duration_s = self.captured_time

        else:
            self.press_end_time_at_epoch = self.captured_time

            self._control_type, self.keys, self.hold_duration_s, self.press_end_time_at_epoch, self.mouse_pos_xy = "Mouse", button, round(time.time() - self.hold_duration_s, place_to_round_to), time.time(), self.mouse.position
            self._listen_stop()

            if(debug):
                print(self._control_type + " pressed, current key is now set to " + str(self))

def save_macro(name, keys_to_store: List[key_presses]):
    macro_config_directory = _get_os_config_directory() + "/macros/"
    """Save macros in /macros folder in the same directory as input handler."""
    #Store macro same directory as python file is being executed in
    if(os.path.exists(macro_config_directory) == False):
        print("No config folder found, creating a new config folder at: " + macro_config_directory)
        os.makedirs(macro_config_directory)
    with open((macro_config_directory + name + '.txt'), 'w') as filehandle:
        for listitem in keys_to_store:
            #Keycodes encase alphabetical characters in single quotes, I.E, e becomes 'e'. this needs to be removed becasue pynput cant read its own formating.
            #print(listitem)
            listitem = str(listitem).replace("'", "")
            filehandle.write('%s\n' % listitem)

#Construct macro(keypress list) based on saved macro file.
def load_macro(name) -> List[key_presses]:
    macro_config_directory = _get_os_config_directory() + "/macros/"
    """
    Load macros in /macros folder in the same directory as input handler.
    exclude file extension
    """

    #Macro list to construct
    current_macro = []

    #Setup config folder to store macros if no config folder already exists
    if(os.path.exists(macro_config_directory) == False):
        raise Exception("No macro folder found! Create or load some macros into: " + macro_config_directory)
        #print("No config folder found, creating a new config folder at: " + macro_config_directory() + "/macros/")
        #os.makedirs(_get_os_config_directory)
    try:
        with open((macro_config_directory + name + '.txt'), 'r') as filehandle:
            for line in filehandle:
                constructed_key = key_presses()

                #remove \n at begining of readline
                line = line.rstrip('\n')
                unfilt_currentLine = line.split(sep_str)
                #print("unfilt line is " + str(unfilt_currentLine))
                currentLine = [s.split("]") for s in unfilt_currentLine]

                #print("current line is " + str(currentLine))
                #param_name = curr.split("]")[:-1]

                #print(param_name)
                if(debug):
                    print("<<MACRO LOAD>> current read line is: " + str(currentLine))
                #constructed_key.key.key_object = currentLine[1]

                #python doesnt have pointers, so putting things into a big list is variables that cor
                for setting in currentLine:
                    #print("setting is " + str(setting))
                    #check for hcontrol type
                    if(setting[0] == control_type_variable_name):
                        constructed_key._control_type = setting[1]
                        pass
                    #check for key
                    elif(setting[0] == key_name_variable_name):
                        #Correlate non-alphabetical key-codes to their pynput counterpart via dictionary containing them, if that fails, assign to macro list as string(will work for alphabetical characters)
                        try:
                            constructed_key.keys = key_to_object_dict[setting[1]]
                        except:
                            constructed_key.keys = setting[1]

                    #check for hold duration
                    elif(setting[0] == hold_duration_variable_name):
                        constructed_key.hold_duration_s = float(setting[1])

                    #check for time press ended at epoch
                    elif(setting[0] == press_end_at_epoch_variable_name):
                        constructed_key.press_end_time_at_epoch = float(setting[1])

                    #check for mouse_pos
                    elif(setting[0] == mouse_pos_variable_name):
                        #print(setting)
                        #cleanup string to add as mouse pos
                        setting[1] = setting[1].replace("(", "")
                        setting[1] = setting[1].replace(")", "")
                        setting[1] = setting[1].replace(" ", "")

                        setting[1] = setting[1].split(",")
                        #print("mouse setting is " + str(setting[1]))
                        constructed_key.mouse_pos_xy = (int(setting[1][0]), int(setting[1][1]))

                if(debug):
                    print("<<MACRO LOAD>> final constructed key is: " + str(constructed_key))

                current_macro.append(constructed_key)
    except Exception as e:
        print("<<MACRO LOAD>> ran into error constructing macro, investigate.")
        print("<<MACRO LOAD>> Actual error: " + traceback.format_exc())

    #print(current_macro)
    return current_macro


import math
import random
from Functions import *
from DataMap import DataMap

from program2 import *

class Slime():
    slimes = []

    sensor_angle = 22.5
    sensor_distance = 20
    turn_per_step = 10

    deposition_amount = 1

    leftSensorVec = [math.cos(math.radians(sensor_angle)), math.sin(math.radians(sensor_angle))]
    rightSensorVec = [math.cos(math.radians(-sensor_angle)), math.sin(math.radians(-sensor_angle))]

    vectorLeft = [math.cos(math.radians(turn_per_step)), math.sin(math.radians(turn_per_step))]
    vectorRight = [math.cos(math.radians(-turn_per_step)), math.sin(math.radians(-turn_per_step))]

    def __init__(self, x=SCREEN_WIDTH/2, y=SCREEN_HEIGHT/2, vector=[1,0], angle=None, speed=3):
        self.x = x
        self.y = y

        self.vector = vector

        self.speed = speed
        self.turningAwayFromWall = None

        if angle != None:
            vx = math.cos(math.radians(angle)) * self.speed
            vy = math.sin(math.radians(angle)) * self.speed
            self.vector = [vx, vy]

    @staticmethod
    def add(slimeObject):
        Slime.slimes.append(slimeObject)

    @staticmethod
    def updateAll():
        for slime in Slime.slimes:
            slime.update()

    @staticmethod
    def drawAll(screen):
        for slime in Slime.slimes:
            slime.draw(screen)

    def update(self):
        for i in range(self.speed):
            self.sense()
            self.move()
            self.trail(DataMap.trail_map)

    def getSensorCoords(self):
        vector = rotateVec(normalize(self.vector, Slime.sensor_distance), Slime.leftSensorVec)
        sensor1 = [int(self.x + vector[0]), int(self.y + vector[1])]
        vector = normalize(self.vector, Slime.sensor_distance)
        sensor2 = [int(self.x + vector[0]), int(self.y + vector[1])]
        vector = rotateVec(normalize(self.vector, Slime.sensor_distance), Slime.rightSensorVec)
        sensor3 = [int(self.x + vector[0]), int(self.y + vector[1])]
        return [sensor1, sensor2, sensor3]

    def sense(self):
        sensor_coords = self.getSensorCoords()

        # Describes whether one sensor is out of the wall.
        # Will be set to true if even one sensor is out.
        outing = False

        # If front sensor is out
        if Slime.sensorOut(sensor_coords[1]):
            outing = True

            # If already turning away
            if self.turningAwayFromWall != None:
                # Check which way was decided to turn, turn that way
                if self.turningAwayFromWall == 0:
                    self.turnLeft()
                else:
                    self.turnRight()
            # Not turning away already
            else:
                # Generate a direction, turn and set turningAwayFromWall to rememeber that direction
                if random.randint(0,1) == 0:
                    self.turnLeft()
                    self.turningAwayFromWall = 0
                else:
                    self.turnRight()
                    self.turningAwayFromWall = 1
        # Front not out so check other sensors and turn
        else:
            if Slime.sensorOut(sensor_coords[0]):
                outing = True
                self.turnRight()
            if Slime.sensorOut(sensor_coords[2]):
                outing = True
                self.turnLeft()

        # All sensors in, so DataMap values are checked
        if not outing:
            # Not outing so not turning away from wall anymore, reset turningAwayFromWall
            if self.turningAwayFromWall != None:
                self.turningAwayFromWall = None

            # Get values of DataMap at sensor corrds
            sensor_values = [DataMap.trail_map[item[1]][item[0]] for item in sensor_coords]

            # Front > both, do nothing
            if sensor_values[1] > sensor_values[0] and sensor_values[1] > sensor_values[2]:
                pass
            # Front < both, so trails are on both sides, choose one at random
            elif sensor_values[1] < sensor_values[0] and sensor_values[1] < sensor_values[2]:
                if random.randint(0,1) == 0:
                    self.turnLeft()
                else:
                    self.turnRight()
            # Front > one of them, check which one is greater and turn that way
            # Right > Left
            elif sensor_values[2] > sensor_values[0]:
                self.turnRight()
            # Left > Right
            elif sensor_values[0] > sensor_values[2]:
                self.turnLeft()

    @staticmethod
    def sensorOut(sensor):
        if sensor[0] < 0 or sensor[0] >= SCREEN_WIDTH or sensor[1] < 0 or sensor[1] >= SCREEN_HEIGHT:
            return True
        return False

    def turnLeft(self):
        self.vector = normalize(rotateVec(self.vector, Slime.vectorLeft),1)

    def turnRight(self):
        self.vector = normalize(rotateVec(self.vector, Slime.vectorRight),1)

    def trail(self, trail_map):
        for i in range(int(self.y)-Slime.deposition_amount+1, int(self.y)+Slime.deposition_amount):
            for j in range(int(self.x)-Slime.deposition_amount+1, int(self.x)+Slime.deposition_amount):
                try:
                    trail_map[i][j] = 1.25
                except:
                    pass

    def move(self):
        self.x += self.vector[0]
        self.y += self.vector[1]
        self.hitWalls()

    def hitWalls(self):
        if self.x < 0:
            self.x = 0
        if self.y < 0:
            self.y = 0

        if self.x > SCREEN_WIDTH:
            self.x = SCREEN_WIDTH
        if self.y > SCREEN_HEIGHT:
            self.y = SCREEN_HEIGHT

    def thruWalls(self):
        if self.x < 0:
            self.x = SCREEN_WIDTH
        if self.y < 0:
            self.y = SCREEN_HEIGHT

        if self.x > SCREEN_WIDTH:
            self.x = 0
        if self.y > SCREEN_HEIGHT:
            self.y = 0

    def draw(self, screen):
        pygame.draw.rect(screen, white, (int(self.x*SCALE), int(self.y*SCALE), SCALE, SCALE), 0)


import numpy as np
import pandas as pd

DATASET_PATH=r'2000cellsPA20220407 all peaks hepg2.csv'
cell_data_df= pd.read_csv(DATASET_PATH,low_memory=False)
cell_data_df.head()
cell_data_df.columns
#specify the 990 features column names to be modelled
to_model_columns=cell_data_df.columns[1:990]

from sklearn.ensemble import IsolationForest
clf=IsolationForest(n_estimators=100, max_samples='auto', \
                        max_features=1.0, bootstrap=False, n_jobs=-1, random_state=42, verbose=0)
clf.fit(cell_data_df[to_model_columns])

pred = clf.predict(cell_data_df[to_model_columns])
cell_data_df['anomaly']=pred
outliers=cell_data_df.loc[cell_data_df['anomaly']==-1]
outlier_index=list(outliers.index)
#print(outlier_index)
#Find the number of anomalies and normal points here points classified -1 are anomalous
print(cell_data_df['anomaly'].value_counts())
print(outliers)
outliers.to_csv(r'Outliers HepG2 32 in 1000-052311.csv')

#3D PCA
#HepG2 #66c2a5
#MCF7 #fc8d62
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from mpl_toolkits.mplot3d import Axes3D
pca = PCA(n_components=3)  # Reduce to k=3 dimensions
scaler = StandardScaler()
#normalize the cell_data
X = scaler.fit_transform(cell_data_df[to_model_columns])
X_reduce = pca.fit_transform(X)

figsize=(6, 6)
fig = plt.figure(figsize=figsize, dpi=300)
ax = fig.add_subplot(111, projection='3d')
ax.set_zlabel("x_composite_3")

# Plot the compressed data points
ax.scatter(X_reduce[:, 0], X_reduce[:, 1], zs=X_reduce[:, 2], s=8, lw=1, label="Normal",c="#a6d854")

# Plot x's for the ground truth outliers
ax.scatter(X_reduce[outlier_index,0],X_reduce[outlier_index,1], X_reduce[outlier_index,2],
           lw=2, s=33, marker="x", c="red", label="Outliers")
ax.legend()
plt.show()

#2D PCA
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

pca2 = PCA(n_components=2)# Reduce to k=2 dimensions
scaler = StandardScaler()
#normalize the cell_data
XT = scaler.fit_transform(cell_data_df[to_model_columns])
pca2.fit(XT)
res=pd.DataFrame(pca2.transform(XT))

Z = np.array(res)
figsize=(8, 8)
plt.figure(figsize=figsize, dpi=300)
plt.title("Isolation Forest")
#plt.contourf(Z, cmap=plt.cm.Blues_r)

b1 = plt.scatter(res[0], res[1], c='#a6d854', s=33,label="Normal")

b1 = plt.scatter(res.iloc[outlier_index,0],res.iloc[outlier_index,1], c='red',
                 s=33, edgecolor="red",label="Outliers")
plt.legend(loc="upper right")
plt.show()


import logging
from argparse import Namespace
from pathlib import Path
from typing import Callable, Optional

from protostar.cli import (
    LIB_PATH_ARG,
    LibPathResolver,
    ProtostarArgument,
    ProtostarCommand,
)
from protostar.cli.common_arguments import PACKAGE_ARG
from protostar.configuration_file import ConfigurationFile
from protostar.io.log_color_provider import LogColorProvider
from protostar.package_manager import extract_info_from_repo_id

from .install_package_from_repo import install_package_from_repo
from .pull_package_submodules import pull_package_submodules

EXTERNAL_DEPENDENCY_REFERENCE_DESCRIPTION = """- `GITHUB_ACCOUNT_NAME/REPO_NAME[@TAG]`
    - `OpenZeppelin/cairo-contracts@v0.4.0`
- `URL_TO_THE_REPOSITORY`
    - `https://github.com/OpenZeppelin/cairo-contracts`
- `SSH_URI`
    - `git@github.com:OpenZeppelin/cairo-contracts.git`
"""

class InstallCommand(ProtostarCommand):
    def __init__(
        self,
        project_root_path: Path,
        lib_path_resolver: LibPathResolver,
        log_color_provider: LogColorProvider,
    ) -> None:
        super().__init__()
        self._project_root_path = project_root_path
        self._lib_path_resolver = lib_path_resolver
        self._log_color_provider = log_color_provider

    @property
    def name(self) -> str:
        return "install"

    @property
    def description(self) -> str:
        return "Install a dependency as a git submodule."

    @property
    def example(self) -> Optional[str]:
        return "$ protostar install https://github.com/OpenZeppelin/cairo-contracts"

    @property
    def arguments(self):
        return [
            LIB_PATH_ARG,
            PACKAGE_ARG,
            ProtostarArgument(
                name="name",
                description="A custom package name. Use it to resolve name conflicts.",
                type="str",
            ),
        ]

    async def run(self, args: Namespace):
        logging.info("Executing install")
        try:
            self.install(
                package_name=args.package,
                libs_path=self._lib_path_resolver.resolve(args.lib_path),
                on_unknown_version=lambda: logging.warning(
                    (
                        "Fetching from the mainline. The mainline can be in the non-releasable state.\n"
                        "Installing packages without providing specific version/tag is strongly discouraged."
                    )
                ),
                alias=args.name,
            )
        except BaseException as exc:
            logging.error("Installation failed")
            raise exc
        logging.info("Installed successfully")

    def install(
        self,
        package_name: Optional[str],
        libs_path: Path,
        on_unknown_version: Callable,
        alias: Optional[str] = None,
    ) -> None:
        if package_name:
            package_info = extract_info_from_repo_id(package_name)
            if package_info.version is None:
                on_unknown_version()
            install_package_from_repo(
                alias or package_info.name,
                package_info.url,
                project_root_path=self._project_root_path,
                destination=libs_path,
                tag=package_info.version,
            )
            logging.info(ConfigurationFile.create_appending_cairo_path_suggestion())
        else:
            if not libs_path.exists():
                logging.warning(
                    "Directory %s doesn't exist.\n"
                    "Did you install any package before running this command?",
                    libs_path,
                )
                return
            pull_package_submodules(
                on_submodule_update_start=lambda package_info: logging.info(
                    "Installing %s%s%s %s(%s)%s",
                    self._log_color_provider.get_color("CYAN"),
                    package_info.name,
                    self._log_color_provider.get_color("RESET"),
                    self._log_color_provider.get_color("GRAY"),
                    package_info.url,
                    self._log_color_provider.get_color("RESET"),
                ),
                repo_dir=self._project_root_path,
                libs_dir=libs_path,
            )


#!/usr/bin/env python3
#
#  ██████╗  █████╗ ██╗  ██╗██████╗    ███╗   ██╗███████╗████████╗
# ██╔════╝ ██╔══██╗██║  ██║██╔══██╗   ████╗  ██║██╔════╝╚══██╔══╝
# ██║  ███╗███████║███████║██║  ██║   ██╔██╗ ██║█████╗     ██║
# ██║   ██║██╔══██║██╔══██║██║  ██║   ██║╚██╗██║██╔══╝     ██║
# ╚██████╔╝██║  ██║██║  ██║██████╔╝██╗██║ ╚████║███████╗   ██║
#  ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═════╝ ╚═╝╚═╝  ╚═══╝╚══════╝   ╚═╝
#   ____  ___  _   _ ____
#  / ___|/ _ \| | | |  _ \   minions/minions.py
# | |  _| |_| | |_| | | | |
# | |_| |  _  |  _  | |_| |  Gustavo Huarcaya
#  \____|_| |_|_| |_|____/   https://gahd.net
#
# Python minions main menu
#

import os
import sys

from python.isocalendar import today_isocalendar, custom_isocalendar
from python.util import SEPARATOR, menu_header

__filename = os.path.basename(__file__).upper()

header = menu_header(__filename)

menu = dict([
    ("1", "Today Isocalendar"),
    ("2", "Custom Isocalendar"),
    ("0", "Exit"),
])

menu_options = tuple(set(tuple(menu.keys()) + ("q",)))

def clear():
    """Clear console"""
    os.system("clear")

def display_header():
    """Show menu header"""
    clear()
    for i in header:
        print(i)

def display_menu():
    """Display menu"""
    for k, v in menu.items():
        print(f" [{k}] {v}")
    print(SEPARATOR)

def ask_option():
    """Ask the user which minion he wants to use"""
    valid_option = False
    while(not valid_option):
        user_input = input("Select an option: ")
        valid_option = user_input in menu_options
    return user_input

def ask_continue():
    """Ask the user if he wants to continue using another minion"""
    user_input = input("Press [1] to return to the main menu, [0] to exit: ")

    if user_input == "1":
        minions()
    elif user_input == "0" or user_input.lower() == "q":
        sys.exit()
    else:
        ask_continue()

def principal():
    opt = ask_option()

    if opt == "1":
        clear()
        iso_calendar = today_isocalendar()
        print(os.system("cal -1"))
        print(f"Week: \t\t{iso_calendar['week']}")
        print(f"Weekday: \t{iso_calendar['weekday']}")

        print()
        ask_continue()
    elif opt == "2":
        clear()
        year = input("Year: ")
        month = input("Month (from Jan = 1 to Dec = 12): ")
        day = input("Day of the month: ")
        clear()
        print((os.system(f"cal {day} {month} {year}")))
        iso_calendar = custom_isocalendar(int(year), int(month), int(day))
        print(f"Week: \t\t{iso_calendar['week']}")
        print(f"Weekday: \t{iso_calendar['weekday']}")
    elif opt == "0" or "q":
        clear()
        sys.exit()

def minions():
    display_header()
    display_menu()
    principal()

if __name__ == "__main__":
    minions()


import json
from flask import request, _request_ctx_stack, abort, Flask
from functools import wraps
from jose import jwt
from urllib.request import urlopen

AUTH0_DOMAIN = 'dev-04zvrt8l.us.auth0.com'
ALGORITHMS = ['RS256']
API_AUDIENCE = 'Casting-Agency'

'''
AuthError Exception
A standardized way to communicate auth failure modes
'''
class AuthError(Exception):
    def __init__(self, error, status_code):
        self.error = error
        self.status_code = status_code

## Auth Header
def get_token_auth_header():
    auth_header = request.headers.get('Authorization', None)
    if auth_header is None:
        print("ZZZZZZZZZZZZZZZZZZZ=11111111")
        raise AuthError({
            'code': 'authorization_header_missing',
            'description': 'Authorization header is expected within the request.'
        }, 401)

    # the token format is "Bearer <Token-Characters>" and token_parts length must be 2
    token_parts = auth_header.split()
    if (token_parts[0].lower() != 'bearer') or len(token_parts) != 2:
        raise AuthError({
            'code': 'invalid_header',
            'description': 'Authorization header must contains "Bearer Token".'
        }, 401)

    token = token_parts[1]
    return token

def check_permissions(permission, payload):
    # the payload is deccoded
    if 'permissions' not in payload:
        raise AuthError({
            'code': 'invalid_claims',
            'description': 'Permissions not found in JWT payload.'
        }, 400)

    if permission not in payload['permissions']:
        raise AuthError({
            'code': 'unauthorized',
            'description': 'Permission not found.'
        }, 403)
    return True

def verify_decode_jwt(token):
    # Get the public key from AUTH0
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())

    # Get the data in the header:
    # to unpack the header of the (jwt)token to determine if we have the correct key!
    # cuz the jwt header contains the key id we are looking for
    # to pick the right key used in validation
    unverified_header = jwt.get_unverified_header(token)

    rsa_key = {}
    if 'kid' not in unverified_header:
        print("ZZZZZZZZZZZZZZZZZZZ")
        raise AuthError({
            'code': 'invalid_header',
            'description': 'Authorization malformed.'
        }, 401)
    # Choose our key by Iterate over all keys received
    for key in jwks['keys']:
        if key['kid'] == unverified_header['kid']:
            rsa_key = {
                'kty': key['kty'],
                'kid': key['kid'],
                'use': key['use'],
                'n': key['n'],
                'e': key['e']
            }
    # Finally, verify and decode the payload!!!
    if rsa_key:
        try:
            # Use the Token, Key to validate JWT
            payload = jwt.decode(
                token,
                rsa_key,
                algorithms=ALGORITHMS,
                audience=API_AUDIENCE,
                issuer='https://' + AUTH0_DOMAIN + '/'
            )
            return payload

        # some standard Auth0 exceptions
        except jwt.ExpiredSignatureError:
            raise AuthError({
                'code': 'token_expired',
                'description': 'Token expired.'
            }, 401)

        except jwt.JWTClaimsError:
            raise AuthError({
                'code': 'invalid_claims',
                'description': 'Incorrect claims. Please, check the audience and issuer.'
            }, 401)
        except Exception:
            raise AuthError({
                'code': 'invalid_header',
                'description': 'Unable to parse authentication token.'
            }, 400)
    raise AuthError({
                'code': 'invalid_header',
                'description': 'Unable to find the appropriate key.'
            }, 400)

def requires_auth(permission=''):
    def requires_auth_decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            token = get_token_auth_header()
            try:
                payload = verify_decode_jwt(token)
                check_permissions(permission, payload)
            except:
                abort(403)

            return f(payload, *args, **kwargs)

        return wrapper
    return requires_auth_decorator


n=10
if n==0:
    print(0)
primes=[True for i in range(n+1)]
p=2
count=0
while p*p<=n:
    if primes[p] is True:
        for i in range(p*2,n+1,p):
            primes[i]=False
    p+=1
primes[0],primes[1]=False,False
for t in range(n):
    if primes[t] is True:
        count+=1
print(count)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
from nltk.corpus import stopwords
import spacy
import en_core_web_sm
import pandas as pd
from gensim.models import Word2Vec
from gensim.models.phrases import Phrases, Phraser
from tqdm import tqdm
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

# Call in and clean data
now_articles = pd.read_csv('./now_articles.txt', sep = "\t",
                          names = ['date', 'period', 'outlet', 'outlet_type', 'politics', 'tag', 'text', 'title'],
                          skip_blank_lines = True).dropna()
now_articles['year'] = pd.to_datetime(now_articles.date).apply(lambda x: x.year)
df = now_articles.loc[(now_articles.year.isin([2013, 2014, 2015, 2016, 2017, 2018])) &\
                       (now_articles.outlet.isin(['Daily Mail', 'Guardian']))]
df['mods'] = df.outlet + "_" +  df.year.apply(lambda x: 'Pre' if x < 2016 else 'Post')

# Retokenize entities
class EntityRetokenizeComponent:
  def __init__(self, nlp):
    pass
  def __call__(self, doc):
    for entity in doc.ents:
        if entity.label_ in ["PERSON", "ORG", "GPE", "NORP"]:
            with doc.retokenize() as retokenizer:
                retokenizer.merge(entity)
    return doc

nlp = en_core_web_sm.load()
retokenizer = EntityRetokenizeComponent(nlp)
nlp.add_pipe(retokenizer, name='merge_phrases', last=True)
StopWords = set(stopwords.words('english'))
StopWords.update(['-PRON-'])

for mod in ['Guardian_Pre', 'Guardian_Post', 'Daily Mail_Pre', 'Daily Mail_Post']:
    raw_data = df.loc[df.mods == mod]

    articles = []
    for art in tqdm(nlp.pipe(raw_data.text, n_process=12, batch_size =500)):
        articles.append([tok.lemma_.lower().strip() for tok in art if len(tok.text.strip()) > 1])

    phrases = Phrases(articles, common_terms = StopWords)
    bigram = Phraser(phrases)
    tphrases = Phrases(bigram[articles], common_terms = StopWords)
    trigram = Phraser(tphrases)

    phrased_articles = [trigram[bigram[art]] for art in articles]

    model = Word2Vec(phrased_articles, size=300, window=7, min_count=200, workers=12, sg = 1, iter = 15)
    model.save("./word2vec/{}.model".format(mod))


# https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/1/ALDS1_1_D
# O(n**2)のプログラムを書かないように注意

n=int(input())
R=[int(input()) for _ in range(n)]

# dp的な考え方？
# 各時刻における損益の最大値は、前の時刻における損益の最大値と現時刻の最小値から計算可能
# 最小値にぶち当たるたびに、そこにひっつきながら収益がもっと上がるか見張る感じ
r_min = R[0]
ans = -10**9
for r in R[1:]:
    ans = max(ans, r-r_min)
    r_min = min(r, r_min)

print(ans)


import os
import json

from .get_com import get_commits

# 监控信息文件
current_dir = os.path.join(os.path.dirname(__file__), 'config.json')

# 监控
async def watch_depo(gid, uid, url):
    with open(current_dir, 'r', encoding="UTF-8") as f:
        file_data = json.load(f)
    group_info = file_data.get(gid, {})
    user_info = group_info.get(uid, {})
    if user_info.get(url, {}): return '你已经监控过该仓库了，无需再次监控'
    data_list = await get_commits(url)
    priv_time = str(data_list[0]['time'])
    user_info[url] = priv_time
    group_info[uid] = user_info
    file_data[gid] = group_info
    with open(current_dir, 'w', encoding="UTF-8") as f:
        json.dump(file_data, f, indent=4, ensure_ascii=False)
    return f'您已成功在群{gid}里监控仓库：{url}'

# 取消监控
async def unwatch_depo(gid, uid, url):
    with open(current_dir, 'r', encoding="UTF-8") as f:
        file_data = json.load(f)
    group_info = file_data.get(gid, {})
    user_info = group_info.get(uid, {})
    if not user_info.get(url, {}): return '你还未监控过该仓库，请先使用命令监控'
    file_data[gid][uid].pop(url)
    with open(current_dir, 'w', encoding="UTF-8") as f:
        json.dump(file_data, f, indent=4, ensure_ascii=False)
    return f'您已成功在群{gid}里取消监控仓库：{url}'

# 监控查询
async def query_depo(gid, uid):
    with open(current_dir, 'r', encoding="UTF-8") as f:
        file_data = json.load(f)
    group_info = file_data.get(gid, {})
    user_info = group_info.get(uid, {})
    return '您暂未监控任何仓库呢！' if not user_info else '您所监控的仓库有：\n' + '\n'.join(list(user_info.keys()))


import os
import sys
from webbrowser import get

from pydantic import ValidationError
from pydantic.error_wrappers import ErrorWrapper
from dataclasses import dataclass
from typing import Sequence, Tuple
import pathlib

from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import SecurityContentType
from bin.contentctl_project.contentctl_core.domain.entities.detection_tags import DetectionTags
from bin.contentctl_project.contentctl_core.application.builder.basic_builder import BasicBuilder
from bin.contentctl_project.contentctl_core.application.builder.detection_builder import DetectionBuilder
from bin.contentctl_project.contentctl_core.application.builder.story_builder import StoryBuilder
from bin.contentctl_project.contentctl_core.application.builder.director import Director
from bin.contentctl_project.contentctl_core.application.factory.utils.utils import Utils

@dataclass(frozen=True)
class BAFactoryInputDto:
    input_path: str
    basic_builder: BasicBuilder
    detection_builder: DetectionBuilder
    director: Director
    attack_enrichment: dict

@dataclass(frozen=True)
class BAFactoryOutputDto:
     detections: list

class BAFactory():
    input_dto: BAFactoryInputDto
    output_dto: BAFactoryOutputDto
    ids: dict[str,list[pathlib.Path]] = {}

    def __init__(self, output_dto: BAFactoryOutputDto) -> None:
        self.output_dto = output_dto

    def execute(self, input_dto: BAFactoryInputDto) -> None:
        self.input_dto = input_dto
        print("Creating Security Content - SSA. This may take some time...")

        validation_errors = self.createSecurityContent(SecurityContentType.detections)

        if len(validation_errors) != 0:
            print(f"There were [{len(validation_errors)}] error(s) found while parsing security_content")
            for ve in validation_errors:
                file_path = ve[0]
                error = ve[1]
                print(f'\nValidation Error for file [{file_path}]:\n{str(error)}')
            #raise(Exception("Error(s) validating Security Content"))

    def createSecurityContent(self, type: SecurityContentType) -> list[Tuple[pathlib.Path,  ValidationError]]:
        objects = []
        files = Utils.get_all_yml_files_from_directory(os.path.join(self.input_dto.input_path, 'ssa_detections'))

        validation_errors:list[Tuple[pathlib.Path,  ValidationError]] = []

        files_with_ssa = [f for f in files if f.name.startswith('ssa_')]

        already_ran = False
        progress_percent = 0
        type_string = "UNKNOWN TYPE"
        for index,file in enumerate(files_with_ssa):

            #Index + 1 because we are zero indexed, not 1 indexed.  This ensures
            # that printouts end at 100%, not some other number
            progress_percent = ((index+1)/len(files_with_ssa)) * 100

            progress_percent = ((index+1)/len(files_with_ssa)) * 100
            #try:
            type_string = "UNKNOWN TYPE"
            if type == SecurityContentType.detections:
                type_string = "Detections"
                self.input_dto.director.constructDetection(self.input_dto.detection_builder, file, [], [], [], self.input_dto.attack_enrichment, [], [])
                detection = self.input_dto.detection_builder.getObject()
                Utils.add_id(self.ids, detection, file)

                tag_and_nist_errors = []

                if detection.tags.cis20 == None:
                    error = TypeError(f"Detection Tags missing cis20 field")
                    tag_and_nist_errors.append(ErrorWrapper(error, loc="cis20"))

                if detection.tags.nist == None:
                    error = TypeError(f"Detection Tags missing nist field")
                    tag_and_nist_errors.append(ErrorWrapper(error, loc="nist"))

                if len(tag_and_nist_errors) > 0:
                    raise ValidationError( tag_and_nist_errors , DetectionTags)

                if detection.status in ["production","validation"]:
                    self.output_dto.detections.append(detection)
            else:
                raise(Exception(f"Unsupported content type: [{type}]"))

            if (sys.stdout.isatty() and sys.stdin.isatty() and sys.stderr.isatty()) or not already_ran:
                already_ran = True
                print(f"\r{f'{type_string} Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True)

            # except ValidationError as e:
            #     validation_errors.append((pathlib.Path(file), e))
            # except Exception as e:
            #     print(f"Unknown exception caught while Creating BA Security Content: {str(e)}")
            #     sys.exit(1)

        print(f"\r{f'{type_string} Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True)
        print("Done!")

        return validation_errors


"""Utilities."""

import sys
from typing import Dict, Optional

RGB_RANGE = 0b11111111

def bit_mask(size: int) -> int:
    """Return a bit mask with `size` number of 1-s."""
    if size < 0:
        raise ValueError('{0:d} B TOO SMALL BB'.format(size))
    elif size == 0:
        return 0
    else:
        return int('1' * size, base=2)

def query_user(question: str, default: Optional[bool]=None) -> bool:
    """Ask the user a yes/no question and return the response.

    Seeded from from
    https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input

    Args:
        question: A prompt to provide to the user.
        default: An optional presumed answer, if the user just hits <Enter>.
            It must be "yes" (the default), "no" or None (meaning
            an answer is required of the user).

    Returns:
        True if the user specifies a truthy variant, False if the user specifies
        a falsy variant, or the default value.
    """
    if default is None:
        prompt = '[y/n]'
    elif default is True:
        prompt = '[Y/n]'
    elif default is False:
        prompt = '[y/N]'
    else:
        raise ValueError(f'invalid default answer: "{default}"')

    response_to_bool: Dict[str, bool] = {
        'yes': True,
        'y': True,
        'no': False,
        'n': False
    }
    while True:
        sys.stdout.write(f'{question} {prompt}: ')
        choice = input().lower()
        if default is not None and not choice:
            return default
        elif choice in response_to_bool:
            return response_to_bool[choice]
        else:
            print(
                'Please respond with one of "{0:s}"'.format(
                    '", "'.join(response_to_bool.keys())))


import numpy as np
import pandas as pd
from flask import Flask, request, jsonify
import pickle

app = Flask(__name__)

#if it crashes go to root folder "version1"
#then cd classification_and_data
#run "python3 RandomForestClassifier.py"
#copy randomForestModel.pkl to version1/server/
model = pickle.load(open('randomForestModel.pkl','rb'))

@app.route('/api',methods=['POST'])
def predict():
    data = request.get_json(force=True)

    age = data['age']
    budget = data['budget']
    season = 0

    if data['season'] == 'spring':
        season = 0
    elif data['season'] == 'autumn':
        season = 1
    elif data['season'] == 'winter':
        season = 2
    elif data['season'] == 'summer':
        season = 3

    sample = [age, budget, season]
    sampleData = pd.DataFrame([sample], columns=['age', 'budget', 'season'])
    prediction = model.predict(sampleData)
    output = {'city': int(prediction[0])}
    print(prediction)
    return jsonify(output)

if __name__ == '__main__':
    app.run(port=5000, debug=True)


import csv

def louput(my_list):
    # output txt
    # with open('output.txt', 'w') as output_file:
    #    for item in my_list:
    #        output_file.write("%s\n" % item)
    # output csv
    keys = my_list[0].keys()
    with open('output.csv', 'w', newline='')  as output_file:
        dict_writer = csv.DictWriter(output_file, keys)
        dict_writer.writeheader()
        dict_writer.writerows(my_list)


import csv
import os
from math import ceil

import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from sklearn.cluster import KMeans
from tqdm import tqdm

class ColorGenerator:
    def __init__(self, path: str, csv_path: str):
        self.path = path
        self.csv_path = csv_path
        self.headers = [
            'file_name',
            'color_1',
            'color_2',
            'color_3',
            'color_4',
            'color_5',
            'color_6',
        ]

    def _get_kmeans_centers(self, img, nclusters: int):
        return KMeans(n_clusters=nclusters).fit(img).cluster_centers_

    def _get_image(self, path: str):
        with open(path, "rb") as f:
            return np.array(Image.open(f))

    def _preprocess_image(self, image):
        return image.reshape((-1, 3)).astype("float32") / 255

    def _plot_palette(self, centers: np.ndarray) -> None:
        plt.figure(figsize=(14, 6))
        plt.imshow(centers[
            np.concatenate(
                [[i] * 100 for i in range(len(centers))]).reshape((-1, 10)).T
        ])
        plt.grid()
        plt.axis('off')
        plt.show()

    def generate_colors(self, nclusters: int, show_palette: bool) -> None:
        dataset = os.listdir(self.path)
        file = open(self.csv_path, 'w', encoding='UTF8', newline='')
        writer = csv.writer(file)
        writer.writerow(self.headers)

        for image in tqdm(dataset):
            entry = [image]
            img = self._get_image(os.path.join(self.path, image))
            rgb_pixels = self._preprocess_image(img)
            centers = self._get_kmeans_centers(rgb_pixels, nclusters)
            entry.extend(
                [
                    ';'.join(map(lambda a: str(ceil(a * 255)), i))
                    for i in centers
                ]
            )
            if show_palette:
                self._plot_palette(centers)

            writer.writerow(entry)

gen = ColorGenerator(path='dataset', csv_path='data_test.csv')
gen.generate_colors(6, False)


# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json

class ScrapyCambadaPipeline(object):

    def open_spider(self, spider):
        self.arquivo = open('frases_historicas.json', 'w')

    def close_spider(self, spider):
        self.arquivo.close()

    def process_item(self, item, spider):
        line = {
            'pk': None,
            'model': 'frases_historicas.FraseHistorica',
            'fields': dict(item)
        }
        line = json.dumps(line)
        self.arquivo.write(line + ',\n')
        return item


'''

Topic to be covered - Detect Outliers using Elliptic Envelopes

'''

import pandas as pd
import numpy as np

from sklearn.covariance import EllipticEnvelope

dataset = pd.read_csv('Salary.csv')

X = np.array([[100,100],
              [1,1],
              [2,4],
              [5,6],
              [6,8]])

outlier = EllipticEnvelope(contamination=0.1)

outlier.fit(X)
prediction1 = outlier.predict(X)
print(prediction1)

#--------------------------------------#

features = dataset.iloc[:,[1,2]].values

outlier1 = EllipticEnvelope(contamination=0.1)

outlier1.fit(features)
prediction2 = outlier1.predict(features)

print(prediction2)

dataset['outliers'] = prediction2