import pandas as pd

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVR
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingRegressor

from utils import downcast_dtypes, encode_features, rmse

# https://www.kaggle.com/dlarionov/feature-engineering-xgboost

train = pd.read_pickle('./training_set2.pkl')

X = train.drop(['item_cnt_month'], axis=1)
y = train['item_cnt_month']

# Split into validation and training data
train_X, val_X, train_y, val_y = train_test_split(X, y, random_state=1)

# Specify Model
dt_model = DecisionTreeRegressor(random_state=1)
dt_model.fit(train_X, train_y)

val_predictions = dt_model.predict(val_X)
val_rmse = rmse(val_y, val_predictions)
print("Validation RMSE when not specifying max_leaf_nodes: {}".format(val_rmse))
# Validation RMSE when not specifying max_leaf_nodes: 2.5498269967793057

# Using best value for max_leaf_nodes
dt_model100 = DecisionTreeRegressor(max_leaf_nodes=100, random_state=1)
dt_model100.fit(train_X, train_y)

val_predictions = dt_model100.predict(val_X)
val_rmse = rmse(val_predictions, val_y)
print("Validation RMSE for best value of max_leaf_nodes: {}".format(val_rmse))
# Validation RMSE for best value of max_leaf_nodes: 2.825573731965393

# Define the model. Set random_state to 1
rf_model = RandomForestRegressor(random_state=1, verbose=3)
rf_model.fit(train_X, train_y)

val_predictions = rf_model.predict(val_X)
rf_val_rmse = rmse(val_predictions, val_y)
print("Validation RMSE for Random Forest Model: {}".format(rf_val_rmse))
# Validation RMSE for Random Forest Model: 2.238423610462634

model = LinearRegression()
model.fit(train_X, train_y)

val_predictions = model.predict(val_X)
rf_val_rmse = rmse(val_predictions, val_y)
print("Validation RMSE for Linear Regression: {}".format(rf_val_rmse))
# Validation RMSE for Linear Regression: 3.37160140437921

model = SVR(kernel='linear', verbose=True)
model.fit(train_X, train_y)

val_predictions = model.predict(val_X)
rf_val_rmse = rmse(val_predictions, val_y)
print("Validation RMSE for SVR rbf: {}".format(rf_val_rmse))

model = LogisticRegression(verbose=3)
model.fit(train_X, train_y)

val_predictions = model.predict(val_X)
rf_val_rmse = rmse(val_predictions, val_y)
print("Validation RMSE for SVR rbf: {}".format(rf_val_rmse))

model = GradientBoostingRegressor(verbose=3)
model.fit(train_X, train_y)

val_predictions = model.predict(val_X)
rf_val_rmse = rmse(val_predictions, val_y)
print("Validation RMSE for GradientBoostingRegressor: {}".format(rf_val_rmse))


# -*- coding: utf-8 -*-
from pathlib import Path

import yaml
from fastapi import File, UploadFile, HTTPException, status
from fastapi.responses import FileResponse
from fastapi_utils.cbv import cbv
from fastapi_utils.inferring_router import InferringRouter

router = InferringRouter(tags=['Mixer Table'])

@cbv(router)
class SpectrumProfilesCRUD:
    mixer_table_0 = Path('MixerTableExcels/MixerTable.xlsx')
    mixer_table_1 = Path('MixerTableExcels/MixerTable_1.xlsx')
    mixer_table_2 = Path('MixerTableExcels/MixerTable_2.xlsx')

    @router.get("/MixerTableExcels/")
    def get_file(self):
        """Retrieves a ONLY the first file"""
        return FileResponse(self.mixer_table_0, filename='MixerTable.xlsx')

    @router.put("/MixerTableExcels/0")
    async def update_file0(self, file: UploadFile = File(...)):
        return await self.update_files(file, self.mixer_table_0)

    @router.put("/MixerTableExcels/1")
    async def update_file1(self, file: UploadFile = File(...)):
        return await self.update_files(file, self.mixer_table_1)

    @router.put("/MixerTableExcels/2")
    async def update_file2(self, file: UploadFile = File(...)):
        return await self.update_files(file, self.mixer_table_2)

    async def update_files(self, file, file_path: Path):
        if file.filename != file_path.name:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"File name is not matching.")
        try:
            import pandas as pd
            cont = await file.read()
            read_file = pd.read_excel(cont)
            read_file.to_excel(file_path)
            from devices.system import sys
            sys.load_system()
            return read_file.values.tolist()
        except yaml.YAMLError:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"File is not valid YAML format.")


import gzip
import json
from sklearn.model_selection import train_test_split
import numpy as np
from tensorflow.python.keras import models, layers
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score
import re
from keras import backend as BK

###########################################################
# taking the input, applying the tanh function and scaling
# to output from -1 to 1 to the wanted scale
# Parameters:
#   - x (input float)
#   - target_min (lower bound of the wanted scale)
#   - target_max (upper bound of the wanted scale)
# Returns
#   - scaled input
def mapping_to_target_range(x, target_min=1, target_max=5):
    x02 = BK.tanh(x) + 1
    scale = (target_max - target_min) / 2.
    return x02 * scale + target_min

###########################################################
# Main supervised learning with neural network method.
# Loads the dataset, applies preprocessing, trains the
# model, saves the model parameters and prints the
# classification report
# Parameters:
#   - load (Bool if the weights should be loaded)
# Returns
#   -
def supervised_learning(load):
    # Loading dataset
    data = []
    g = gzip.open("Software.json.gz", 'r')
    print("Loading dataset ...")
    for l in g:
        data.append(json.loads(l))
    N = 100000
    print("The dataset used has ", len(data), "entries! Of this dataset", N, "entries are used to train the model.")

    reviews = []
    ratings = []
    print("Text preprocessing ...")
    for d in data[:N]:
        if d.get('reviewText') is None:
            continue
        # remove all unwanted chars
        review = re.compile(r'[^a-z0-9\s]').sub(r'', re.compile(r'[\W]').sub(r' ', d.get('reviewText').lower()))
        reviews.append(review)
        rating = float(d.get('overall'))
        ratings.append(rating)

    # vectorized the input texts
    max_features = 200000
    tokenizer = Tokenizer(num_words=max_features)
    tokenizer.fit_on_texts(reviews)
    reviews = tokenizer.texts_to_sequences(reviews)

    # calculating the maximal review length & pad all inputs to the same length for the neural network
    max_length = max(len(train_r) for train_r in reviews)
    reviews = tf.keras.preprocessing.sequence.pad_sequences(reviews, maxlen=max_length)

    # split the data into training set, test set and validation set
    print("Splitting dataset ...")
    train_reviews, test_reviews, train_ratings, test_ratings = train_test_split(np.array(reviews), np.array(ratings),
                                                                                test_size=0.1)
    train_reviews, validation_reviews, train_ratings, validation_ratings = train_test_split(train_reviews,
                                                                                train_ratings,
                                                                                test_size=0.2)

    # Create the neural network. Input size was calculated above
    input = layers.Input(shape=(max_length,))
    x = layers.Embedding(max_features, 64)(input)
    # three times, use a convolutional layer, normalization and max pooling layer
    x = layers.Conv1D(64, 5, activation='relu')(x)
    x = layers.BatchNormalization()(x)
    x = layers.MaxPool1D(3)(x)
    x = layers.Conv1D(64, 5, activation='relu')(x)
    x = layers.BatchNormalization()(x)
    x = layers.MaxPool1D(5)(x)
    x = layers.Conv1D(64, 5, activation='relu')(x)
    x = layers.GlobalMaxPool1D()(x)
    x = layers.Flatten()(x)
    # two normally connected layers to condense the output to a single number
    x = layers.Dense(64, activation='relu')(x)
    output = layers.Dense(1, activation=mapping_to_target_range)(x)
    model = models.Model(inputs=input, outputs=output)

    # Adam (a stochastic gradient descent variant) as optimization function
    opt = tf.keras.optimizers.Adam(learning_rate=0.001)

    # compiling the model. As error the MSE is specified since the output and target are floats
    model.compile(optimizer=opt, loss='mean_squared_error')

    # loading model weights if wanted
    if load:
        print("\nLoading previous model weights:\n")
        model.load_weights('weights/supervisedLearning')

    # training the model
    print("Training Model:\n")
    model.fit(train_reviews, train_ratings, batch_size=64, epochs=3,
              validation_data=(validation_reviews, validation_ratings))

    # calculating the predictions on the test set
    test_pred = model.predict(test_reviews)

    # printing the classification report
    print(classification_report(test_ratings,np.round(test_pred)))

    # testing the model with 3 examples (positive, negative, neutral review)
    print("\nTesting model: ")
    x = "I really like this book. It is one of the best I have read."
    x = re.compile(r'[^a-z\s]').sub(r'', re.compile(r'[\W]').sub(r' ', x.lower()))
    x = tokenizer.texts_to_sequences(np.array([x]))
    x = tf.keras.preprocessing.sequence.pad_sequences(x, maxlen=max_length)
    result = model.predict(x)
    print("'I really like this book. It is one of the best I have read.' got the rating: ", round(result[0][0]))

    x = "I really hate this book. It is one of the worst I have read."
    x = re.compile(r'[^a-z\s]').sub(r'', re.compile(r'[\W]').sub(r' ', x.lower()))
    x = tokenizer.texts_to_sequences(np.array([x]))
    x = tf.keras.preprocessing.sequence.pad_sequences(x, maxlen=max_length)
    result = model.predict(x)
    print("'I really hate this book. It is one of the worst I have read.' got the rating: ", round(result[0][0]))

    x = "This book is ok. It is very average."
    x = re.compile(r'[^a-z\s]').sub(r'', re.compile(r'[\W]').sub(r' ', x.lower()))
    x = tokenizer.texts_to_sequences(np.array([x]))
    x = tf.keras.preprocessing.sequence.pad_sequences(x, maxlen=max_length)
    result = model.predict(x)
    print("'This book is ok. It is very average.' got the rating: ", round(result[0][0]))

    # saving the model weights
    print("\n\nSaving model weights ...")
    model.save_weights('weights/supervisedLearning')


"""
Sentencizer is a class that contains rule-based algorithms created
to split a text into sentences
"""
import nltk as nltk

class Sentencizer:

    def __init__(self, text, split_characters=['.', '?', '!', ':', ';'],
                 delimiter_token='$$'):
        self.raw_text = self.preprocessing(text)
        self._delimiter_token = delimiter_token
        self._split_characters = split_characters
        self.sentences = []
        self.splitter_by_punctuation()
        self.split_skscs()
        self.splitter_by_2grams()
        self.splitter_by_unigrams()
        self.split_kscs()
        self.sentence_cleaning()

    # this method will preprocess the text: basically transform abbreviations
    # to its long form
    def preprocessing(self, text):
        text = text.replace("’", "'")
        keywords = [("he's", "he is"), ("'re", " are"), ("'m", " am"),
                    ("'ll", " will"), ("n't", " not"), ("it's", "it is"),
                    ("she's", "she is"), ("That's", "that is")]
        for keyword in keywords:
            if keyword[0] in text:
                text = text.replace(keyword[0], keyword[1])
        return text

    # this method is based on punctuations to split the text into sentences.
    def splitter_by_punctuation(self):
        work_sentence = self.raw_text
        for character in self._split_characters:
            work_sentence = work_sentence.replace(character, character + "" +
                                                  self._delimiter_token)
        self.sentences = work_sentence.split(self._delimiter_token)

    # this method is based on uni-gram keywords to split the text into
    # sentences
    def splitter_by_unigrams(self):
        self.sentences = filter(None, self.sentences)
        s = []  # list of sentences
        # list of keywords
        unigrams_split = ['because', 'hence', 'consequently', 'while', 'next',
                          'then', 'when', 'but']
        # list of keywords that come after a comma
        unigrams_comma_split = ['moreover', 'so', 'hence', 'particularly',
                                'especially', 'however', 'nevertheless',
                                'although', 'but', 'yet', 'despite', 'whereas',
                                'then', 'which', 'and', "or"]
        for phrase in self.sentences:
            tokens = nltk.word_tokenize(phrase)
            for i in range(len(tokens)):
                for unigram in unigrams_comma_split:
                    # check if it's a keyword
                    if tokens[i] == unigram:
                        # check if there is a comma before the keyword, also
                        # check that the number of words in the
                        # sentence is grater or equal to 3
                        if tokens[i - 1] == ',' and i >= 3 and 2 > (
                                i - len(tokens)):
                            tokens[i] = '$$'
                            tokens[i - 1] = ''
                for unigram in unigrams_split:
                    # check if it's a keyword, also check that the number of
                    # words in the sentence is grater than 3
                    if tokens[i] == unigram and i >= 3 and 2 > (
                            i - len(tokens)):
                        tokens[i] = '$$'
            sentences = ' '.join(tokens)
            sentences = sentences.split('$$')
            for sentence in sentences:
                s.append(sentence)
        self.sentences = s

    # auxiliary method to divide a sentence by a comma: it replaces the
    # following comma with a special character which marks the boundaries
    # of the sentences
    def split_first_comma(self, text, begin):
        for i in range(begin, len(text)):
            if text[i] == ',':
                text[i] = self._delimiter_token
        return text

    # this method is based on keywords which divide the sentences in the form:
    # Keyword + Sentence + comma + Sentence (kscs)
    def split_kscs(self):
        self.sentences = filter(None, self.sentences)
        s = []
        keywords = ['Despite', 'Although', 'While', 'When', 'Even if',
                    'Even though', 'Even']
        for phrase in self.sentences:
            for keyword in keywords:
                if keyword in phrase:
                    phrase = phrase.replace(',', '$$', 1)
                    phrase = phrase.replace(keyword, '')
            sentences = phrase.split('$$')
            for sentence in sentences:
                s.append(sentence)
        self.sentences = s

    # this method is based on keywords which divide the sentences in the form:
    # Sentence + keyword + Sentence + comma + Sentence (kscs)
    def split_skscs(self):
        self.sentences = filter(None, self.sentences)
        s = []
        keywords = ['but when']
        for phrase in self.sentences:
            for keyword in keywords:
                if keyword in phrase:
                    subphrase = phrase[:phrase.find(keyword)]
                    phrase = phrase[phrase.find(keyword):]
                    phrase = phrase.replace(',', self._delimiter_token, 1)
                    phrase = phrase.replace(keyword, self._delimiter_token)
                    phrase = subphrase + phrase
            sentences = phrase.split(self._delimiter_token)
            for sentence in sentences:
                s.append(sentence)
        self.sentences = s

    # this method is based on 2-gram keywords to split the text into sentences
    def splitter_by_2grams(self):
        self.sentences = filter(None, self.sentences)
        s = []
        keywords = ['and then', 'even though', 'but then',
                    'even so', 'and sometimes', 'when sometimes',
                    'as long as', 'as far as', 'as soon as', 'if and only if']
        for phrase in self.sentences:
            for keyword in keywords:
                if keyword in phrase:
                    phrase = phrase.replace(keyword, self._delimiter_token)
            sentences = phrase.split(self._delimiter_token)
            for sentence in sentences:
                s.append(sentence)
        self.sentences = s

    # this function removes transition words like 'In addition', 'To sum
    # up', 'Therefore' ... the transition words are used to link the
    # sentences to each other and do not form sentences so I will delete
    # them .
    def sentence_cleaning(self):
        clean_sentences = []
        self.sentences = filter(None, self.sentences)
        transition_words = ['In addition', 'As a result', 'Thus', 'To sum up',
                            'But', 'In fact', 'In conclusion', 'To summarise',
                            'Due To', 'For example', 'For instance', 'Such as',
                            'Because of', 'In Brief', 'First', 'Firstly',
                            'Second', 'Secondly', 'Next', 'Finally',
                            'Furthermore', 'Also', 'Moreover', 'Therefore',
                            'Consequently', 'Hence', 'Undoubtedly', 'Indeed',
                            'Clearly', 'Because', 'Since', 'However', 'Then',
                            'Although', 'Nevertheless', 'Unfortunately',
                            'Perhaps', 'Maybe']
        for sentence in self.sentences:
            sentence = sentence.lstrip()
            if sentence.startswith(","):
                sentence = sentence[1:]
            for keyword in transition_words:
                if keyword in sentence:
                    sentence = sentence.replace(keyword, "")
            clean_sentences.append(sentence)
        self.sentences = clean_sentences


from dataclasses import dataclass

@dataclass(order=True)
class LinkBuilder():
    url: str
    client_id: str
    scope: str
    redirect_uri: str
    response_type: str
    state: str

    def get(self) -> str:
        link = self.url + '?' + ''.join([
            key + '=' + self.__dict__[key] + '&'
            for key in self.__dict__ if key != 'url'
        ])
        return link[0:-1]


# -*- coding: utf-8 -*-
"""
Created on Mon Apr 25 19:54:44 2022

@author: ICD/CA
"""

import os
import pandas as pd
import matplotlib.pyplot as plt
import json

CONST_PATH = r"./"

def createObjectivesDF():
    """
    This function reads all log files from the CONST_PATH and
    generates a data frame of objectives for each algorithm used.
    all data frames are stored in a dictionary where the keys are the algorithm names
    """
    files = []
    objeectiveDataFrames = {}

    for file in os.listdir(CONST_PATH):
        if file.endswith(".json"):
            files.append(file)

    # check for size of logs file and set minfile to the smallest size
    count = []
    for i, file in enumerate(files):
        with open(CONST_PATH + file, "r") as f:
            data = json.load(f)
            count.append(len(list(data.keys())))
    minfile = min(count)

    # read all log files and store them in a dictionary of data frames
    for file in files:
        with open(CONST_PATH + file, "r") as f:
            data = json.load(f)
            objectivesList = []
            keys = list(data.keys())
            keys.sort(key=lambda x: data[x]["time"], reverse=False)
            for j, key in enumerate(keys):
                if j < minfile:
                    for objName in data[key]["objectives"].keys():
                        objectivesList.append(data[key]["objectives"][objName])
                algoName = file.split("_")[0]
            objectivesList.sort(reverse=False)
            if algoName not in objeectiveDataFrames.keys():
                objeectiveDataFrames[algoName] = pd.DataFrame()
                objeectiveDataFrames[algoName][file.split(".")[0]] = objectivesList
            else:
                objeectiveDataFrames[algoName][file.split(".")[0]] = objectivesList
    return objeectiveDataFrames

def processConvergence(objectiveDf, bolMinimize):
    """Calculates the median objective per function evaluation and solver.
    Returns data frame with the median objective for each iteration and per solver"""
    print("\nProcessing convergence ...")

    # Median objective per iterations and solver
    keys = objectiveDf.keys()

    print(objectiveDf)

    solvers = keys
    allMedians = [objectiveDf[hvDf].median(axis=1).tolist() for hvDf in keys]

    # Sort by performance
    if bolMinimize is True:
        allMedians = [sorted(median, reverse=True) for median in allMedians]
    else:
        allMedians = [sorted(median, reverse=False) for median in allMedians]

    # Create dataframe with labelled columns
    mediansDf = pd.DataFrame(allMedians).transpose()

    mediansDf.columns = solvers

    # Print last 5 rows
    print(mediansDf.tail(5))

    return mediansDf

def processRobustness(objectiveDf, bolMinimize):
    """Returns data frame with variance and median per solver."""
    print("\nProcessing variance ...")
    results = []
    variances = []

    keys = objectiveDf.keys()
    for i, key in enumerate(keys):
        if bolMinimize:
            lastRow = objectiveDf[key].iloc[0]
            result = lastRow.tolist()
            result.sort(reverse=False)
        else:
            lastRow = objectiveDf[key].iloc[-1]
            result = lastRow.tolist()
            result.sort(reverse=True)
        variances.append(lastRow.var())  # Variance for console

        results.append(result)

    medians = [sum(results[i]) / len(results[i]) for i in range(len(results))]

    # Print variance
    varsDf = pd.DataFrame(results).transpose()
    varsDf.columns = keys
    print("\nVariance")
    print(varsDf.transpose())

    return varsDf, medians

def plotData(
    plotType,
    data,
    save=False,
    fig_size=(8, 6),
    figDPI=300,
    title=None,
    xLabel=None,
    yLabel=None,
):
    if title == None:
        title = "myPlot"

    if plotType == "lineplot":
        plt.figure()
        data.plot.line(figsize=fig_size, title=title, xlabel=xLabel, ylabel=yLabel)

    elif plotType == "boxplot":
        plt.figure()
        ax = data.plot(kind="box", figsize=fig_size)
        ax.set_xlabel(xLabel)
        ax.set_ylabel(yLabel)
        ax.set_title(title)

    if save:
        plt.savefig(CONST_PATH + title + ".png", dpi=figDPI)

    plt.show()

if __name__ == "__main__":
    objectivesDfs = createObjectivesDF()

    mediansDf = processConvergence(objectivesDfs, True)
    plotData(
        "lineplot",
        mediansDf,
        False,
        title="Convergence",
        xLabel="Function Evaluations",
        yLabel="Objective",
    )

    varsDf, bestMedians = processRobustness(objectivesDfs, True)
    plotData(
        "boxplot",
        varsDf,
        False,
        title="Robustness",
        xLabel="Final Results",
        yLabel="Objective",
    )


from datetime import datetime
from pydantic import validate_arguments

class PainelDTO:
    @validate_arguments
    def __init__(self, id_configuracao:int, id_secretaria:int, status:bool, data_criado:datetime, total_ativo:int, total_presentes:int, total_ausentes:int, total_presentes_curso:int, total_ativo_curso:int, total_ausente_curso:int):
        self.id_configuracao = id_configuracao
        self.id_secretaria = id_secretaria
        self.status = status
        self.data_criado = data_criado
        self.total_ativo = total_ativo
        self.total_presentes = total_presentes
        self.total_ausentes = total_ausentes
        self.total_presentes_curso = total_presentes_curso
        self.total_ativo_curso = total_ativo_curso
        self.total_ausente_curso = total_ausente_curso


class Solution(object):
    def trimMean(self, arr):
        """
        :type arr: List[int]
        :rtype: float
        """
        arr.sort()
        fiveP = int(len(arr) * 0.05)
        newArr = arr[fiveP:len(arr) - fiveP]

        return float(sum(newArr)) / float(len(newArr))


from __future__ import division
from math import ceil, log10
import sys
import os
import numpy as np
import matplotlib
matplotlib.use("Agg")

from lalsimulation import SimInspiralTaylorF2ReducedSpinComputeChi, SimIMRPhenomBComputeChi

from lalinspiral.sbank.waveforms import compute_mchirp
from lalinspiral.sbank.tau0tau3 import m1m2_to_tau0tau3

from h5py import File as H5File

matplotlib.rcParams.update({
    "text.usetex": True,
    "text.verticalalignment": "center",
    "font.size": 18,
    "axes.titlesize": 22,
    "axes.labelsize": 22,
    "xtick.labelsize": 18,
    "ytick.labelsize": 18,
    "legend.fontsize": 16,
    "figure.figsize": [12,9],
   })

fname = sys.argv[1]

def find_process_id(process_table, prog_name):
    for program, pid in process_table["program", "process_id"]:
        if program == prog_name:
            return pid
    return None

def find_process_param(pp_table, process_id, param):
    for pid, row_param, value in pp_table["process_id", "param", "value"]:
        if pid == process_id and row_param == param:
            return value

# grab data
with H5File(fname, "r") as h5file:
    match = h5file["/match_map"]["match"]

    # order data by descending match so that low matches are plotted on top
    order = match.argsort()[::-1]
    inj_ind = h5file["/match_map"]["inj_index"][order]
    tmplt_ind = h5file["/match_map"]["best_match_tmplt_index"][order]
    match = match[order]

    # extract columns of interest and apply row ordering
    inj_arr = h5file["/sim_inspiral"]["mass1", "mass2", "spin1x", "spin1y", "spin1z", "spin2x", "spin2y", "spin2z", "inclination"][inj_ind]
    tmplt_arr = h5file["/sngl_inspiral"]["mass1", "mass2", "spin1z", "spin2z"][tmplt_ind]

    # extract waveforms
    pid = find_process_id(h5file["/process"], u"lalapps_cbc_sbank_sim")
    pparams = h5file["/process_params"]
    inj_approx = find_process_param(pparams, pid, u"--injection-approx"),
    tmplt_approx = find_process_param(pparams, pid, u"--template-approx")

    # get other useful quantities
    pid = find_process_id(h5file["/process"], u"lalapps_cbc_sbank")
    min_match = float(find_process_param(pparams, pid, u"--match-min"))
    flow = float(find_process_param(pparams, pid, u"--flow"))

# derived quantities
# NB: Named fields in dtypes (see ligolw_table_to_array in lalapps_cbc_sbank_sim)
# allow dict-like access to columns: e.g. arr["mass1"].
inj_M = inj_arr["mass1"] + inj_arr["mass2"] #total mass
inj_eta = inj_arr["mass1"] * inj_arr["mass2"] / (inj_arr["mass1"] * inj_arr["mass2"])
tmplt_M = tmplt_arr["mass1"] + tmplt_arr["mass2"]
tmplt_eta = tmplt_arr["mass1"] * tmplt_arr["mass2"] / (tmplt_arr["mass1"] * tmplt_arr["mass2"])
inj_tau0, inj_tau3 = m1m2_to_tau0tau3(inj_arr["mass1"], inj_arr["mass2"], flow)
tmplt_tau0, tmplt_tau3 = m1m2_to_tau0tau3(tmplt_arr["mass1"], tmplt_arr["mass2"], flow)
tmplt_mchirp = compute_mchirp(tmplt_arr["mass1"], tmplt_arr["mass2"])
inj_mchirp = compute_mchirp(inj_arr["mass1"], inj_arr["mass2"])

#
# compute effective/reduced spin parameter for templates
#
if tmplt_approx == "TaylorF2RedSpin":
    tmplt_chi = [SimInspiralTaylorF2ReducedSpinComputeChi(float(row["mass1"]), float(row["mass2"]), float(row["spin1z"]), float(row["spin2z"])) for row in tmplt_arr]
elif tmplt_approx in ["IMRPhenomB", "IMRPhenomC", "IMRPhenomP"]:
    tmplt_chi = [SimIMRPhenomBComputeChi(float(row["mass1"]), float(row["mass2"]), float(row["spin1z"]), float(row["spin2z"])) for row in tmplt_arr]
else:
    raise NotImplementedError("Only know how to compute chi for TaylorF2RedSpin (reduced spin) and IMRPhenomB/C (effective spin) templates.")

#
# compute effective/reduced spin parameter for injections
#
if inj_approx == "TaylorF2RedSpin" or "SpinTaylorT5" in inj_approx: # reduced spin
    inj_chi = [SimInspiralTaylorF2ReducedSpinComputeChi(float(row["mass1"]), float(row["mass2"]), float(row["spin1z"]), float(row["spin2z"])) for row in inj_arr]
elif "SpinTaylorT4" in inj_approx: # reduced spin (requires coordinate transformation)
    chi1 = [row["spin1x"] *np.sin(row["inclination"]) + row["spin1z"] *np.cos(row["inclination"]) for row in inj_arr]
    chi2 = [row["spin2x"] *np.sin(row["inclination"]) + row["spin2z"] *np.cos(row["inclination"]) for row in inj_arr]
    inj_chi = [SimIMRPhenomBComputeChi(float(row["mass1"]), float(row["mass2"]), s1z, s2z) for row, s1z, s2z in zip(inj_arr, chi1, chi2)]
else: # default to effective spin
    inj_chi = [SimIMRPhenomBComputeChi(float(row["mass1"]), float(row["mass2"]), float(row["spin1z"]), float(row["spin2z"])) for row in inj_arr]

if "PhenomP" in inj_approx: # seriously wtf?
    inj_chi *= np.cos(inj_arr["inclination"])

smallest_match = match.min()

from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

name, ext =  os.path.splitext(os.path.basename(fname))

fig = Figure()
ax = fig.add_subplot(111)
coll = ax.hexbin(inj_M, inj_chi, C=match, gridsize=50, vmin=smallest_match, vmax=1)
ax.set_xlabel("Total Mass ($M_\odot$)")
ax.set_ylabel("$\chi$")
ax.set_xlim([min(inj_M), max(inj_M)])
ax.set_ylim([min(inj_chi), max(inj_chi)])
fig.colorbar(coll, ax=ax).set_label("Mean Fitting Factor")
ax.grid(True)
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injM_vs_injchi_hexbin.png")

fig = Figure()
ax = fig.add_subplot(111)
coll = ax.hexbin(inj_arr["mass1"], inj_arr["mass2"], C=match, gridsize=50, vmin=smallest_match, vmax=1)
ax.set_xlabel("$m_1$ ($M_\odot$)")
ax.set_ylabel("$m_2$ ($M_\odot$)")
ax.set_xlim([min(inj_arr["mass1"]), max(inj_arr["mass1"])])
ax.set_ylim([min(inj_arr["mass2"]), max(inj_arr["mass2"])])
fig.colorbar(coll, ax=ax).set_label("Mean Fitting Factor")
ax.grid(True)
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injm1_vs_injm2_hexbin.png")

fig = Figure()
ax = fig.add_subplot(111)
ax.plot(inj_arr["mass1"], match, marker = '.', linestyle="None")
ax.set_xlabel("Injection $m_1$ ($M_\odot$)")
ax.set_ylabel("Fitting Factor Between Injection and Template Bank")
ax.grid(True)
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injm1.png")

fig = Figure()
ax = fig.add_subplot(111)
ax.plot(inj_arr["mass2"], match, marker = ".", linestyle="None")
ax.set_xlabel("Injection $m_2$ ($M_\odot$)")
ax.set_ylabel("Fitting Factor Between Injection and Template Bank")
ax.grid(True)
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injm2.png")

fig = Figure()
ax = fig.add_subplot(111)
ax.plot(inj_M, match, marker = ".",linestyle="None")
ax.set_xlabel("Injection $M$ ($M_\odot$)")
ax.set_ylabel("Fitting Factor Between Injection and Template Bank")
ax.grid(True)
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injM.png")

fig = Figure()
ax = fig.add_subplot(111)
ax.plot(inj_mchirp, match, marker = ".", linestyle="None")
ax.set_xlabel("Injection $M_c$ ($M_\odot$)")
ax.set_ylabel("Fitting Factor Between Injection and Template Bank")
ax.grid(True)
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injMc.png")

fig = Figure()
ax = fig.add_subplot(111)
ax.plot(inj_eta, match , marker = ".", linestyle="None")
ax.set_xlabel("Injection $\eta$")
ax.set_ylabel("Match Between Injection and Template Bank")
ax.set_xlim([inj_eta.min(), inj_eta.max()])
ax.grid(True)
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injeta.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_arr["mass1"], tmplt_arr["mass1"], c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Injection $m_1$")
ax.set_ylabel("Best Matching Template $m_1$ ($M_\odot$)")
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_tmpltm1_vs_injm1.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_arr["mass2"], tmplt_arr["mass2"], c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Injection $m_2$")
ax.set_ylabel("Best Matching Template $m_2$ ($M_\odot$)")
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_tmpltm2_vs_injm2.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_chi, tmplt_chi, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Injection $\chi$")
ax.set_ylabel("Best Matching Template $\chi$")
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_tmpltchi_vs_injchi.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_eta, tmplt_eta, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Injection $\eta$")
ax.set_ylabel("Best Matching Template $eta$")
ax.set_xlim([inj_eta.min(), inj_eta.max()])
ax.set_ylim([tmplt_eta.min(), tmplt_eta.max()])
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injeta_vs_tmplteta.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_M, tmplt_M, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Injection total mass, $M$ ($M_\odot$)")
ax.set_ylabel("Best Matching Template $M$ ($M_\odot$)")
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injM_vs_tmpltM.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(tmplt_arr["mass1"], tmplt_arr["mass2"], c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Template $m_1$ ($M_\odot$)")
ax.set_ylabel("Template $m_2$ ($M_\odot$)")
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_tmpltm2_vs_tmpltm1.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_arr["mass1"], inj_arr["mass2"], c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Injected $m_1$ ($M_\odot$)")
ax.set_ylabel("Injected $m_2$ ($M_\odot$)")
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injm2_vs_injm1.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_arr["spin1z"], inj_arr["spin2z"], c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Injected $s_{1z}$")
ax.set_ylabel("Injected $s_{2z}$")
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injs1z_vs_injs2z.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_tau0, inj_tau3, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel(r"Injected $\tau_0$ (s)")
ax.set_ylabel(r"Injected $\tau_3$ (s)")
ax.set_title(r"Colorbar is Fitting Factor; assuming $f_\mathrm{low}=%d\,\mathrm{Hz}$" % flow)
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injtau0_vs_injtau3.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_tau0, inj_chi, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel(r"Injected $\tau_0$ (s)")
ax.set_ylabel(r"Injected $\chi$ (s)")
ax.set_title(r"Colorbar is Fitting Factor; assuming $f_\mathrm{low}=%d\,\mathrm{Hz}$" % flow)
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injtau0_vs_injchi.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(tmplt_tau0, tmplt_tau3, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel(r"Template $\tau_0$ (s)")
ax.set_ylabel(r"Template $\tau_3$ (s)")
ax.set_title(r"Colorbar is Fitting Factor; assuming $f_\mathrm{low}=%d\,\mathrm{Hz}$" % flow)
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_tmplttau0_vs_tmplttau3.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(tmplt_tau0, tmplt_chi, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel(r"Template $\tau_0$ (s)")
ax.set_ylabel(r"Template $\chi$ (s)")
ax.set_title(r"Colorbar is Fitting Factor; assuming $f_\mathrm{low}=%d\,\mathrm{Hz}$" % flow)
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_tmplttau0_vs_tmpltchi.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(tmplt_M, tmplt_chi, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel(r"Template $M_{total}$ ($M_\odot$)")
ax.set_ylabel(r"Template $\chi$ (s)")
ax.set_title(r"Colorbar is Fitting Factor; assuming $f_\mathrm{low}=%d\,\mathrm{Hz}$" % flow)
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_tmpltM_vs_tmpltchi.png")

fig = Figure()
ax = fig.add_axes((0.1, 0.1, 0.85, 0.85), xscale="log", yscale="log")
count, bin_edges = np.histogram(np.log(1 - match), bins=40)
bin_centers = np.exp(-(bin_edges[:-1] * bin_edges[1:])**0.5)
ax.plot(bin_centers, count, linewidth=2.5)
ax.plot((1 - min_match, 1 - min_match), (1, 10**ceil(log10(count.max()))), "k--")
ax.set_xlabel("mismatch (1 - fitting factor)")
ax.set_ylabel("Number")
ax.set_title(r'$N_\mathrm{inj}=%d$, $N_{\mathrm{FF} < %.2f} = %d$' % (len(match), min_match, (match < min_match).sum()))
ax.grid(True)
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_hist.png")

fig = Figure()
ax = fig.add_subplot(111)
collection = ax.scatter(inj_M, inj_chi, c=match, s=20, vmin=smallest_match, linewidth=0, alpha=0.5, vmax=1)
ax.set_xlabel("Injected Total Mass")
ax.set_ylabel("Injected Chi")
ax.grid(True)
fig.colorbar(collection, ax=ax).set_label("Fitting Factor")
canvas = FigureCanvas(fig)
fig.savefig(name+"_match_vs_injM_vs_injchi.png")


def main():

    a = 1
    b = 1
    index = 2

    found = False

    while not found:
        index += 1
        a, b = b, a + b
        if len(str(b)) >= 1000:
            found = True
            print(index)

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
import numpy as np

import megengine.functional as F
from megengine import tensor
from megengine.module import Elemwise

def test_module_elemwise():
    def test_func(method, *inps):
        elemwise = Elemwise(method)
        outputs = elemwise(*inps)
        return outputs.numpy()

    x = np.random.rand(100).astype("float32")
    y = np.random.rand(100).astype("float32")
    x, y = tensor(x), tensor(y)
    np.testing.assert_almost_equal(
        test_func("h_swish", x), F.hswish(x).numpy(), decimal=6
    )
    np.testing.assert_almost_equal(
        test_func("add", x, y), F.add(x, y).numpy(), decimal=6
    )


"""Implementation of Rule LT13."""
from typing import Optional

from sqlfluff.core.rules import BaseRule, LintFix, LintResult, RuleContext
from sqlfluff.core.rules.crawlers import RootOnlyCrawler
from sqlfluff.utils.functional import Segments, rsp, sp

class Rule_LT13(BaseRule):
    """Files must not begin with newlines or whitespace.

    **Anti-pattern**

    The file begins with newlines or whitespace. The ``^``
    represents the beginning of the file.

    .. code-block:: sql
       :force:

        ^

        SELECT
            a
        FROM foo

        -- Beginning on an indented line is also forbidden,
        -- (the • represents space).

        ••••SELECT
        ••••a
        FROM
        ••••foo

    **Best practice**

    Start file on either code or comment. (The ``^`` represents the beginning
    of the file.)

    .. code-block:: sql
       :force:

        ^SELECT
            a
        FROM foo

        -- Including an initial block comment.

        ^/*
        This is a description of my SQL code.
        */
        SELECT
            a
        FROM
            foo

        -- Including an initial inline comment.

        ^--This is a description of my SQL code.
        SELECT
            a
        FROM
            foo
    """

    name = "layout.start_of_file"
    aliases = ("L050",)
    groups = ("all", "layout")
    targets_templated = True
    # Use the RootOnlyCrawler to only call _eval() ONCE, with the root segment.
    crawl_behaviour = RootOnlyCrawler()
    lint_phase = "post"
    is_fix_compatible = True

    def _eval(self, context: RuleContext) -> Optional[LintResult]:
        """Files must not begin with newlines or whitespace."""
        # Only check raw segments. This ensures we don't try and delete the same
        # whitespace multiple times (i.e. for non-raw segments higher in the
        # tree).
        raw_segments = []
        whitespace_types = {"newline", "whitespace", "indent", "dedent"}
        for seg in context.segment.recursive_crawl_all():
            if not seg.is_raw():
                continue

            if seg.is_type(*whitespace_types):
                raw_segments.append(seg)
                continue

            raw_stack = Segments(*raw_segments, templated_file=context.templated_file)
            # Non-whitespace segment.
            if (
                not raw_stack.all(sp.is_meta())
                # It is possible that a template segment (e.g.
                # {{ config(materialized='view') }}) renders to an empty string
                # and as such is omitted from the parsed tree. We therefore
                # should flag if a templated raw slice intersects with the
                # source slices in the raw stack and skip this rule to avoid
                # risking collisions with template objects.
                and not raw_stack.raw_slices.any(rsp.is_slice_type("templated"))
            ):
                return LintResult(
                    anchor=context.segment,
                    fixes=[LintFix.delete(d) for d in raw_stack],
                )
            else:
                break
        return None


import discord
import random
import os

TOKEN=os.environ['TOKEN']
ol=['Bind','Haven','Split','Ascent','Icebox','Breeze','Fracture']
client=discord.Client()

ol=['Bind','Split','Breeze','Fracture','Haven','Icebox','Ascent']
l=ol.copy()

@client.event
async def on_ready():
    print('Hi {0.user}'.format(client))

@client.event
async def on_message(message):
    n=['1','2','3','4','5','6','7']
    uname=str(message.author).split('#')[0]
    user_message=str(message.content)
    channel=str(message.channel.name)
    print(f'{uname}:{user_message} {channel}')
    global l,ol

    if message.author==client.user:
        return
    if message.channel.name=='toss':
        if user_message.lower()=='/toss':
            tt=['heads','tails']
            num=random.randrange(1000)
            response=f'Result: {tt[num%2]}'
            await message.channel.send(response)
            return
        if user_message.lower()=='/reset':
            l=[]
            l=ol.copy()
            await message.channel.send('MAP RESET')
            return
        if user_message.lower()=='/map':
            maps=''
            for i in range(len(l)):
                maps+=str(i+1)+'.'+l[i]+'  '
            await message.channel.send(maps)
        if user_message in n:
            print(int(user_message)-1)
            print(l[int(user_message)-1])
            l.pop(int(user_message)-1)
            if len(l)==3:
                res=random.randint(0,2)
                await message.channel.send('THE RANDOM MAP IS : '+l[res])
                return
            maps=''
            for i in range(len(l)):
                maps+=str(i+1)+'.'+l[i]+'  '
            await message.channel.send(maps)
            return

            return

client.run(TOKEN)


import bs4
import requests

from supybot import callbacks, i18n
from supybot.commands import wrap, optional

_ = i18n.PluginInternationalization('GoogleTranslate')

class GoogleTranslate(callbacks.Plugin):
    """
    This plugin lets you use Google Translate without an API key.
    """

    @wrap(['somethingWithoutSpaces', 'somethingWithoutSpaces', 'text'])
    def translate(self, irc, msg, args, source_lang, target_lang, text):
        """<source language> <target language> <text>

        Translates <text> from <source language> to <target language> using Google Translate. Use language codes, e.g. "en" for English and "es" for Spanish. To auto-detect the source language, use "auto".
        """

        r = requests.get('https://translate.google.com/m', params={
            'sl': source_lang,
            'hl': target_lang,
            'q': text
        })

        if not r.ok:
            irc.error(_('HTTP Error %d: %s'), r.status_code, r.reason.title(),
                      Raise=True)

        soup = bs4.BeautifulSoup(r.text)

        result = soup.find('div', class_='t0')

        if not result.text:
            irc.error(_('Nothing returned by Google Translate'), Raise=True)

        irc.reply(result.text)

Class = GoogleTranslate


from ghpythonlib.componentbase import dotnetcompiledcomponent as component
import Grasshopper, GhPython
import System
import Rhino
import rhinoscriptsyntax as rs
import clr
import json
import traceback
import System
from System import Array
from System.Text import Encoding
from System.Net import WebRequest, WebHeaderCollection, WebProxy, WebException

# FUNCTION TO SEND API CALL
def send_request(user_prompt, Description, API_Key):
    plugin_context = "You are GrasshopperAI, an AI tool working within Grasshopper to manipulate Grasshopper scripts through natural language. You will be given a description of the entire script and data about the sliders in the format <SLIDER_NAME> - <SLIDER_VALUE>. After understanding the prompt, you have to understand what slider to change and what the new slider value would be. To do that, all you have to do is call a function that I have already programmed which is change_slider_value(str(<SLIDER_NAME>), <NEW_SLIDER_VALUE>). Remember to respond only with the function and enclose the name in an str() function." # system prompt for gpt
    url = "https://api.openai.com/v1/chat/completions"  # reference api url
    data = { # prepare data for request
        "model": "gpt-3.5-turbo-16k", # gpt model, gpt-3.5 is much cheaper to run than gpt4
        "messages": [
            {
                "role": "system",
                "content": str(plugin_context) + "\n" + "\n" + str(Description)  # system prompt is set up here
            },
            {
                "role": "user",
                "content": user_prompt  # user prompt goes here
            }
        ],
        "temperature": 0.5,
        "max_tokens": 4096,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0
    }
    data_string = json.dumps(data)
    data_bytes = Encoding.UTF8.GetBytes(data_string)
    request = WebRequest.Create(url) # create a web request
    request.Method = "POST"
    request.ContentType = "application/json"
    request.Headers.Add("Authorization", "Bearer " + str(API_Key)) # authentication
    request_stream = request.GetRequestStream() # write request to data stream
    request_stream.Write(Array[System.Byte](data_bytes), 0, len(data_bytes))
    request_stream.Close()
    try:
        response = request.GetResponse()
        response_stream = response.GetResponseStream()
        response_reader = System.IO.StreamReader(response_stream)
        response_text = response_reader.ReadToEnd()

        response_json = json.loads(response_text) # get response from openai
        return response_json

    except WebException as e: # error handling
        display_error(str(e))
        return None

# DEFINE USER PROMPT HERE
def construct_prompt(param_data):
    sliders = str(param_data)[1:-1] # get slider data
    user_prompt = rs.StringBox(message="Enter prompt", title="Brain")
    if user_prompt is None:  # check if user cancelled the input
        return None
    prompt = str(sliders) + "\n" + "\n" + str(user_prompt) # construct prompt
    return prompt

class Brain(component): # set up component class
    def __new__(cls):
        instance = Grasshopper.Kernel.GH_Component.__new__(cls,
            "Brain", "Brain", """Uses GPT to manipulate Grasshopper scripts through natural language.""", "Params", "Util") # component info
        return instance

    def get_ComponentGuid(self):
        return System.Guid("bc7f32af-9b9c-4cf6-938a-21b24702c0da")

    def SetUpParam(self, p, name, nickname, description): # set up component parameters
        p.Name = name
        p.NickName = nickname
        p.Description = description
        p.Optional = True

    def RegisterInputParams(self, pManager):
        p = Grasshopper.Kernel.Parameters.Param_Number()
        self.SetUpParam(p, "Parameters", "P", "Parameters to control")
        p.Access = Grasshopper.Kernel.GH_ParamAccess.list
        self.Params.Input.Add(p)

        p = Grasshopper.Kernel.Parameters.Param_String()
        self.SetUpParam(p, "API_Key", "K", "OpenAI API Key")
        p.Access = Grasshopper.Kernel.GH_ParamAccess.item
        self.Params.Input.Add(p)

        p = Grasshopper.Kernel.Parameters.Param_String()
        self.SetUpParam(p, "Description", "D", "A brief description of the GH definition")
        p.Access = Grasshopper.Kernel.GH_ParamAccess.item
        self.Params.Input.Add(p)

        p = Grasshopper.Kernel.Parameters.Param_Boolean()
        self.SetUpParam(p, "Trigger", "R", "Runs the component")
        p.Access = Grasshopper.Kernel.GH_ParamAccess.item
        self.Params.Input.Add(p)

    def RegisterOutputParams(self, pManager):
        pass

    def SolveInstance(self, DA):
        p0 = self.marshal.GetInput(DA, 0)
        p1 = self.marshal.GetInput(DA, 1)
        p2 = self.marshal.GetInput(DA, 2)
        p3 = self.marshal.GetInput(DA, 3)
        result = self.RunScript(p0, p1, p2, p3)

    def get_Internal_Icon_24x24(self): # component icon
        o = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAI6SURBVEhLvdVJyE5RHMfxa54zZYqQspAsJDZkLgtZGBYoUli9xcKwYMdKWFmYsjBmWGBhxUqRjQgrJXNKUobM0/d77jk99z3v875vj0d+9em553Tv+d9znnPvLRpMn/j7TzIBY9AVk3AFvyt+4TrGoaGsxWM4gO7jG37iAtZhYzy20FtMQ6fpi4vwouc4hZOx/QJTkWcxPsEbGmhHR0mD7URvO8guOIsZoVWme9QPw7ABXteCdjMbnrQ3tMpMgX2HQ6sopuMdLPgFLpm+w/NeYyHqxkE8aVRoFUUX3MQHjLCDOLiDPcFRrMECWNhZW9QxDsEZtspdeHHKSnjyptAql+8HVoVW/YzEPnjdETuquQOna9yWz2Dbfe9SfcV7WHg1lkbL4u9wGGd+BhaZZUfKHtjpfjdX4Yx8Fs7BYs6guuZV15AyFC7XwdCKGQ//vMuhVT48nuRWddAtGILJmIM3yIusQIpb91Z5WMtxeOL80Kr98bdDq3XcmhauFngInyXjLG+Uh7UMhmv9CP4PnvwRB5BnIqqDJ9vQAxY4hjbZDk9cH1rlVvQ14fJU41K6pHmBl3DtPV6ENvHOH8Dpb8VyWOAS5sIH8iy8w0E4gbyITqPdzIQDeIfuHPmnfYZLaHszjFs2H/wVOn0vdUOvqGc0AKMxFsa+e8gLuEz90XTSSy73FOll+dfxYfJO6xU4j6azH/UG1zw0Fb9e6c2Z8/vRdNI+r3LndPjBaSR+xZZgB3bDb3TaWf87RfEHQBfFoHsNd3QAAAAASUVORK5CYII="
        return System.Drawing.Bitmap(System.IO.MemoryStream(System.Convert.FromBase64String(o)))

    def RunScript(self, Parameters, API_Key, Description, Trigger):
        # FUNCTION FOR ERROR HANDLING
        def display_error(message): # display error box
            rs.MessageBox(message, 16, "Error")
        # FUNCTION TO CHANGE SLIDER VALUE
        def change_slider_value(nickname, value):
            ghdoc = self.OnPingDocument()
            if not ghdoc:
                display_error("Error accessing Grasshopper document.")
                return
            for obj in ghdoc.Objects:
                if isinstance(obj, Grasshopper.Kernel.Special.GH_NumberSlider) and obj.NickName == nickname:
                    if obj.Slider.Minimum <= value <= obj.Slider.Maximum: # check slider domains
                        obj.SetSliderValue(value)
                        obj.ExpireSolution(True)
                    else:
                        display_error("{} is out of range for '{}'.".format(value, nickname)) # error handling

        # START RUNSCRIPT
        ghdoc = self.OnPingDocument()
        if not ghdoc:
            display_error("Error accessing Grasshopper document.") # error handling
        else:
            input_params = self.Params.Input[0].Sources if self.Params.Input else [] # get component inputs
            param_data = [(param.NickName, param.CurrentValue) for param in input_params if isinstance(param, Grasshopper.Kernel.Special.GH_NumberSlider)] # get slider data
        if param_data:
            if Trigger:
                prompt = construct_prompt(param_data) # construct user prompt
                if prompt is not None: # avoid running when user hits cancel
                    response = send_request(prompt, Description, API_Key) # send api call
                    if response:  # check if response is not None
                        function = response['choices'][0]['message']['content'] # pick out the answer from the response json
                        try:
                            eval(str(function)) # call function
                        except Exception as e:  # catch exceptions raised during the evaluation
                            display_error("Error evaluating function: {}".format(str(e)))
                    else:
                        display_error("Failed to get a valid response from the OpenAI API.")
                else:
                    pass

import GhPython
import System

class AssemblyInfo(GhPython.Assemblies.PythonAssemblyInfo):
    def get_AssemblyName(self):
        return "Brain"

    def get_AssemblyDescription(self):
        return """"""

    def get_AssemblyVersion(self):
        return "0.1"

    def get_AuthorName(self):
        return "Sandheep Rajkumar" # haha me hahaha

    def get_Id(self):
        return System.Guid("88adbca2-bd32-4edc-9be2-9ebf3faaf3fb")


import os
import time
from datetime import datetime
from Config.selenium_config import get_browser
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

browser = get_browser()
browser.get("https://web.whatsapp.com/")

time.sleep(45)

srch_input_class = "_13NKt copyable-text selectable-text"
srch_input_class = srch_input_class.split(" ")
srch_input_class = ".".join(srch_input_class)
srch_input_elt = browser.find_element(By.CLASS_NAME, srch_input_class)
srch_input_elt.send_keys("", Keys.RETURN)

time.sleep(2)

msg_input_class = "fd365im1 to2l77zo bbv8nyr4 mwp4sxku gfz4du6o ag5g9lrv"
msg_input_class = msg_input_class.split(" ")
msg_input_class = ".".join(msg_input_class)
msg_input_elt = browser.find_element(By.CLASS_NAME, msg_input_class)
msg_input_elt.send_keys("", Keys.RETURN)

def send_message(chat, message):
    srch_input_elt.clear()
    srch_input_elt.send_keys(chat, Keys.RETURN)
    msg_input_elt = browser.find_element(By.CLASS_NAME, msg_input_class)
    for character in message:
        msg_input_elt.send_keys(character)
    msg_input_elt.send_keys("", Keys.RETURN)

def cmd(command):
    command = command + " > " + os.path.join("Assets", "command_results.txt")
    output = ""
    os.system(command)

    with open(os.path.join("Assets", "command_results.txt"), "r+") as results:
        output = results.read()

    return output

# Interactive console
def launch_interactive():
    stop = 0
    mode = "message"
    chat = "Dev Test"
    while stop == 0:
        print("Current mode : Commande") if mode == "command" else print("Current mode : Message")
        print("Current chat: " + chat)

        ask = input("Saisir la commande > ") if mode == "command" else input("Saisir le message : ")
        if (ask == "quit"):
            browser.close()
            break
        elif (len(ask) >= 8 and ask[0:8] == "set mode"):
            ask = ask[9:]
            mode = ask
        elif (len(ask) >= 8 and ask[0:8] == "set chat"):
            ask = ask[9:]
            chat = ask
        else:
            if (mode == "command"):
                output = str(cmd(ask))
                send_message(chat, output)
            elif (mode == "message"):
                send_message(chat, ask)
            else:
                send_message(chat, ask)

def get_next_hop(patterns) -> list:
    hour = datetime.utcnow().hour
    min = datetime.utcnow().minute
    hour = "0"+str(hour) if hour < 10 else str(hour)
    min = "0"+str(min) if min < 10 else str(min)
    minute_set = []
    to_return = list()

    keys = patterns.keys()
    # print("Current time : " + str(hour) + ":" + str(min))
    for key in keys:
        if (str(key) == str(hour)):
            minute_set = patterns[key]
            # print("The minute set is : " + str(minute_set))
            for minute in minute_set:
                if (minute == str(min)):
                    to_return.append(key)
                    to_return.append(minute)
                    return to_return
                elif (int(min) < int(minute)):
                    to_return.append(key)
                    to_return.append(minute)
                    return to_return
                else:
                    if (hour == "23"):
                        to_return.append("00")
                        to_return.append("00")
                        return to_return
        else:
            if (int(key) > int(hour)):
                to_return.append(key)
                to_return.append(patterns[str(key)][0])
                return to_return
            else:
                continue

def launch_automated():
    patterns = {}
    message_sent = 0
    for i in range(0, 24, 1):
        if (i<10):
            patterns["0"+str(i)] = []
        else:
            patterns[str(i)] = []

    # Add direct and reverse patterns
    keys = patterns.keys()
    for key in keys:
        if (key != "00" and key != "11" and key != "22"):
            patterns[key].append(key)
        if (int(key) not in [16, 17, 18, 19]):
            patterns[key].append(key[::-1])

    # Populating "00"
    for i in range(1, 6, 1):
        patterns["00"].append(str(i)+str(i))

    # Sorting
    for key in keys:
        patterns[key].sort()

    while 1:
        print("Listening...")
        hour = datetime.utcnow().hour
        min = datetime.utcnow().minute
        hour = "0"+str(hour) if hour < 10 else str(hour)
        min = "0"+str(min) if min < 10 else str(min)
        tmp = get_next_hop(patterns)
        print("Current time : " + str(hour) + ":" + str(min))
        print("The next hop is : "+ str(tmp[0]) + ":" + str(tmp[1]))
        if (str(tmp[0]) == str(hour) and str(tmp[1]) == str(min) and message_sent == 0):
            print("Sending message...")
            message = str(tmp[0]) + ":" + str(tmp[1])
            send_message("Marshall", message)
            print("message sent !")
            message_sent = 1
        print("____________________")
        time.sleep(1)

launch_automated()


n = int(input())
nums = list(map(int,input().split()))

m = int(input())
search_nums = list(map(int,input().split()))

nums = sorted(nums)
def binary_search(arr,value):
    left,right = 0,len(arr) - 1
    while right>=left:
        mid = (left+ right) //2
        if value == arr[mid] :
            print(1)
            return
        elif arr[mid] < value:
            left = mid+1
        elif arr[mid]>value:
            right = mid - 1
    print(0)

for i in search_nums:
    binary_search(nums,i)


"""
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形，
总共有多少种方法？
比如n=3时，2*3的矩形块有3种覆盖方法

注意：
1.考虑当输入为0的时候的输出结果
2.所以在数组中加入一个0
此时输出的下标就是number
那么也应该考虑数组长度的条件设置
"""

class Solution:
    def rectCover(self, number):
        # write code here
        res = [0, 1, 2]
        while len(res) <= number:
            res.append(res[-1]+res[-2])
            print(len(res))
        return res[number]

s = Solution()
print(s.rectCover(4))


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

# Create your models here.
class Attribute(models.Model):
    '''
    Putting the **A** in *EAV*. This holds the attributes, or concepts.
    Examples of possible *Attributes*: color, height, weight,
    number of children, number of patients, has fever?, etc...

    Each attribute has a name, and a description, along with a slug that must
    be unique.  If you don't provide a slug, a default slug (derived from
    name), will be created.

    The *required* field is a boolean that indicates whether this EAV attribute
    is required for entities to which it applies. It defaults to *False*.

    .. warning::
       Just like a normal model field that is required, you will not be able
       to save or create any entity object for which this attribute applies,
       without first setting this EAV attribute.

    There are 7 possible values for datatype:

        * int (TYPE_INT)
        * float (TYPE_FLOAT)
        * text (TYPE_TEXT)
        * date (TYPE_DATE)
        * bool (TYPE_BOOLEAN)
        * object (TYPE_OBJECT)
        * enum (TYPE_ENUM)

    Examples:

    >>> Attribute.objects.create(name='Height', datatype=Attribute.TYPE_INT)
    <Attribute: Height (Integer)>

    >>> Attribute.objects.create(name='Color', datatype=Attribute.TYPE_TEXT)
    <Attribute: Color (Text)>

    >>> yes = EnumValue.objects.create(value='yes')
    >>> no = EnumValue.objects.create(value='no')
    >>> unkown = EnumValue.objects.create(value='unkown')
    >>> ynu = EnumGroup.objects.create(name='Yes / No / Unkown')
    >>> ynu.enums.add(yes, no, unkown)
    >>> Attribute.objects.create(name='Has Fever?',
    ...                          datatype=Attribute.TYPE_ENUM,
    ...                          enum_group=ynu)
    <Attribute: Has Fever? (Multiple Choice)>

    .. warning:: Once an Attribute has been used by an entity, you can not
                 change it's datatype.
    '''

    class Meta:
        ordering = ['content_type', 'name']
        unique_together = ('site', 'content_type', 'slug')

    TYPE_TEXT = 'text'
    TYPE_FLOAT = 'float'
    TYPE_INT = 'int'
    TYPE_DATE = 'date'
    TYPE_BOOLEAN = 'bool'
    TYPE_OBJECT = 'object'
    TYPE_ENUM = 'enum'

    DATATYPE_CHOICES = (
        (TYPE_TEXT, _(u"Text")),
        (TYPE_FLOAT, _(u"Float")),
        (TYPE_INT, _(u"Integer")),
        (TYPE_DATE, _(u"Date")),
        (TYPE_BOOLEAN, _(u"True / False")),
        (TYPE_OBJECT, _(u"Django Object")),
        (TYPE_ENUM, _(u"Multiple Choice")),
    )

    name = models.CharField(_(u"name"), max_length=100,
                            help_text=_(u"User-friendly attribute name"))

    content_type = models.ForeignKey(ContentType,
                                     blank=True, null=True,
                                     verbose_name=_(u"content type"))

    site = models.ForeignKey(Site, verbose_name=_(u"site"),
                             default=settings.SITE_ID)

    slug = EavSlugField(_(u"slug"), max_length=50, db_index=True,
                        help_text=_(u"Short unique attribute label"))

    description = models.CharField(_(u"description"), max_length=256,
                                   blank=True, null=True,
                                   help_text=_(u"Short description"))

    enum_group = models.ForeignKey(EnumGroup, verbose_name=_(u"choice group"),
                                   blank=True, null=True)

    type = models.CharField(_(u"type"), max_length=20, blank=True, null=True)

    @property
    def help_text(self):
        return self.description

    datatype = EavDatatypeField(_(u"data type"), max_length=6,
                                choices=DATATYPE_CHOICES)

    created = models.DateTimeField(_(u"created"), default=timezone.now,
                                   editable=False)

    modified = models.DateTimeField(_(u"modified"), auto_now=True)

    required = models.BooleanField(_(u"required"), default=False)

    display_order = models.PositiveIntegerField(_(u"display order"), default=1)

    objects = models.Manager()
    on_site = CurrentSiteManager()

    def get_validators(self):
        '''
        Returns the appropriate validator function from :mod:`~eav.validators`
        as a list (of length one) for the datatype.

        .. note::
           The reason it returns it as a list, is eventually we may want this
           method to look elsewhere for additional attribute specific
           validators to return as well as the default, built-in one.
        '''
        DATATYPE_VALIDATORS = {
            'text': validate_text,
            'float': validate_float,
            'int': validate_int,
            'date': validate_date,
            'bool': validate_bool,
            'object': validate_object,
            'enum': validate_enum,
        }

        validation_function = DATATYPE_VALIDATORS[self.datatype]
        return [validation_function]

    def validate_value(self, value):
        '''
        Check *value* against the validators returned by
        :meth:`get_validators` for this attribute.
        '''
        for validator in self.get_validators():
            validator(value)
        if self.datatype == self.TYPE_ENUM:
            if value not in self.enum_group.enums.all():
                raise ValidationError(_(u"%(enum)s is not a valid choice "
                                        u"for %(attr)s") % \
                                      {'enum': value, 'attr': self})

    def save(self, *args, **kwargs):
        '''
        Saves the Attribute and auto-generates a slug field if one wasn't
        provided.
        '''
        if not self.slug:
            self.slug = EavSlugField.create_slug_from_name(self.name)
        self.full_clean()
        super(Attribute, self).save(*args, **kwargs)

    def clean(self):
        '''
        Validates the attribute.  Will raise ``ValidationError`` if
        the attribute's datatype is *TYPE_ENUM* and enum_group is not set,
        or if the attribute is not *TYPE_ENUM* and the enum group is set.
        '''
        if self.datatype == self.TYPE_ENUM and not self.enum_group:
            raise ValidationError(_(
                u"You must set the choice group for multiple choice" \
                u"attributes"))

        if self.datatype != self.TYPE_ENUM and self.enum_group:
            raise ValidationError(_(
                u"You can only assign a choice group to multiple choice " \
                u"attributes"))

    def get_choices(self):
        '''
        Returns a query set of :class:`EnumValue` objects for this attribute.
        Returns None if the datatype of this attribute is not *TYPE_ENUM*.
        '''
        if not self.datatype == Attribute.TYPE_ENUM:
            return None
        return self.enum_group.enums.all()

    def save_value(self, entity, value):
        '''
        Called with *entity*, any django object registered with eav, and
        *value*, the :class:`Value` this attribute for *entity* should
        be set to.

        If a :class:`Value` object for this *entity* and attribute doesn't
        exist, one will be created.

        .. note::
           If *value* is None and a :class:`Value` object exists for this
            Attribute and *entity*, it will delete that :class:`Value` object.
        '''
        ct = ContentType.objects.get_for_model(entity)
        try:
            value_obj = self.value_set.get(entity_ct=ct,
                                           entity_id=entity.pk,
                                           attribute=self)
        except Value.DoesNotExist:
            if value == None or value == '':
                return
            value_obj = Value.objects.create(entity_ct=ct,
                                             entity_id=entity.pk,
                                             attribute=self)
        if value == None or value == '':
            value_obj.delete()
            return

        if value != value_obj.value:
            value_obj.value = value
            value_obj.save()

    def __unicode__(self):
        return u"%s.%s (%s)" % (self.content_type, self.name, self.get_datatype_display())


#!/usr/bin/python3
import math
import dao
import numpy as np
import serial
import xinput
import gnoomutils as gu
import sys
import time

#python3 ball_running_test.py

mice = xinput.find_mice(model="Mouse")
m = [mice[0],mice[1]]
blenderpath = "/home/kemerelab/git/VR_Ball"
for mouse in m:
    xinput.set_owner(mouse)
    xinput.switch_mode(mouse)

if len(mice):
    s1, conn1, addr1, p1 = \
      gu.spawn_process("\0mouse0socket",
                  ['%s/evread/readout' % blenderpath, '%d' % mice[0].evno, '0'])
    s2, conn2, addr2, p2 = \
      gu.spawn_process("\0mouse1socket",
                  ['%s/evread/readout' % blenderpath, '%d' % mice[1].evno, '1'])

    conn1.send(b'start')
    conn2.send(b'start')

    gu.recv_ready(conn1)
    gu.recv_ready(conn2)

    conn1.setblocking(0)
    conn2.setblocking(0)

try:
    arduino = serial.Serial('/dev/arduino_ethernet', 9600)
    print("Pump Connected")
except:
    print("Pump not Connected")

duration = float(sys.argv[4])

def main(argv=None):
    if argv is None:
        argv = sys.argv
    start = time.time()
    while time.time() - start < duration:
        time.sleep(float(sys.argv[2]))
        gu.keep_conn([conn1, conn2])
        if conn1 is not None:
            t1, dt1, x1, y1 = gu.read32(conn1)
            t2, dt2, x2, y2 = gu.read32(conn2)
        else:
            t1, dt1, x1, y1 = np.array([0,]), np.array([0,]), np.array([0,]), np.array([0,])
            t2, dt2, x2, y2 = np.array([0,]), np.array([0,]), np.array([0,]), np.array([0,])
        z = (float(y1.sum())-float(y2.sum()))/2/1000*2.54 # distance
        dt = float(dt1.sum())
        v = z/dt
        if v > float(sys.argv[1]):
            try:
                arduino.write(b'L')
            except:
                print("no pump")
            print('%.2f'%(time.time()-start), '%.2f'%v, 'cm/s', '%.2f'%dt, 's')
            ct = 0
            while ct < float(sys.argv[3]):
                time.sleep(1)
                ct = ct + 1
                gu.keep_conn([conn1,conn2])
                t1, dt1, x1, y1 = gu.read32(conn1)
                t2, dt2, x2, y2 = gu.read32(conn2)
            print('Ready for next reward')
    print("Finished")

if __name__ == "__main__":
    sys.exit(main())


"""
    This library contains the sources codes that enables users to classify time series
    data based on the similarity measure technique called Dynamic Time Warping.
    Chatter detection application was performed using this approache in Reference :cite:`Yesilli2022`.
"""

import numpy as np
from dtw import *
import sys,os
from itertools import combinations
import multiprocessing
from multiprocessing import Pool
import time
from scipy.spatial.distance import squareform
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import socket
computer_name = socket.gethostname()
# decide the name of the disk where the data was saved
# depending on the computer you are using, find the path to Research Stuff folder
if computer_name == 'me653':
    disk_name = 'D:'
    path_to_ResearchStuff = 'D:\Research Stuff'
    path_to_DataArchive = 'D:\Data Archive'
else:
    disk_name = 'F:'
    path_to_ResearchStuff = 'G:\Other computers\My Computer\Research Stuff'
    path_to_DataArchive = 'G:\Other computers\My Computer\Data Archive'

plt.rc('text', usetex=True)
plt.rc('font', family='serif')

def DTW_Distance_Comp(ts1,ts2,WS,path_plot,dist_only):
    """

    Parameters
    ----------
    ts1 : np.array
        First time series
    ts2 : np.array
        Second time series
    WS : int
        Window size for sakoeChibaWindow
    path_plot : boolean
        Set it to True if you would like to see the warping path plot
    dist_only : boolean
        Set it to True if you woyld like to only compute the distance for faster computation
    Returns
    -------
    int
        DTW distance between given two time series

    """
    DTW = dtw(ts1, ts2,keep_internals=True,window_type=sakoeChibaWindow,window_args={'window_size': WS} , dist_method='cityblock',step_pattern='symmetricP0',distance_only=dist_only)

    if path_plot:
        DTW.plot(type="threeway")

    return DTW.distance

def DTW_Dist_Mat(TS1,TF,parallel,*args):
    """

    Parameters
    ----------
    TS1 : list
        The list of time series
    TF : boolean
        Set it to True if transfer learning will be applied
    parallel : boolean
        Set it to True for parallel computing of distance matrix
    *args :
        TS2 : list
            The list that includes the test set time series. This input is given only when
            TF is True.

    Returns
    -------
    DM : 2D np.array
        Distance matrix

    """
    # if user wants to apply transfer learning
    if TF:
        TS2 = args[0]

        if not parallel:
            # test set distance matrix-----------

            # length of combinations
            start = time.time()
            DM = np.zeros((len(TS1),len(TS2)))
            for i in range(len(TS1)):
                for j in range(len(TS2)):
                    x=np.ravel(TS1[i])
                    y=np.ravel(TS2[j])
                    DM[i,j]=DTW_Distance_Comp(x,y,1000,False,True)
            end = time.time()
            print("Elapsed time:{}".format(end-start))
        else:
            inputs = []
            for i in range(len(TS1)):
                for j in range(len(TS2)):
                    x=np.ravel(TS1[i])
                    y=np.ravel(TS2[j])
                    inputs.append((x,y,1000,False,True))

            # time the paralell computation of distances
            start = time.time()
            n_proc = multiprocessing.cpu_count()
            with Pool(processes=n_proc//2) as p:
                DM_cp  = p.starmap(DTW_Distance_Comp, inputs)
            end = time.time()
            print("Elapsed time:{}".format(end-start))
            DM_cp = np.asarray(DM_cp)
            DM = DM_cp.reshape((len(TS1),len(TS2)))

        return DM

        # training set distance matrix

    else:
        # compute the combinations between each time series
        poss_comb = np.array(list(combinations(range(0,len(TS1)), 2)))
        # lenght of combinations
        N = len(poss_comb)
        # the loop that computes the distances for all combinations
        DM_cp=[]
        if not parallel:
            start = time.time()
            for i in range(N):
                x=np.ravel(TS1[poss_comb[i,0]])
                y=np.ravel(TS1[poss_comb[i,1]])
                DM_cp.append(DTW_Distance_Comp(x,y,10000,False,True))
            end = time.time()
            print("Elapsed time:{}".format(end-start))
            DM = squareform(DM_cp)
        else:
            inputs = []
            for i in range(N):
                x=np.ravel(TS1[poss_comb[i,0]])
                y=np.ravel(TS1[poss_comb[i,1]])
                inputs.append((x,y,10000,False,True))

            # time the paralell computation of distances
            start = time.time()
            n_proc = multiprocessing.cpu_count()
            with Pool(processes=n_proc//2) as p:
                DM_cp  = p.starmap(DTW_Distance_Comp, inputs)
            end = time.time()
            print("Elapsed time:{}".format(end-start))
            DM = squareform(DM_cp)

    return DM

def kNN(k,L,b,Label_train,labels):
    """

    Parameters
    ----------
    k : int
        Nearest neighbor number
    L : int
        the number of time series in the training or test set
    b : 2D np.array
        the distance matrix between training or test set samples
    Label_train : np.array
        The array that incldues the training set labels
    labels : np.array
        the array that incldues the test set labels if user wants to compute test set accuray or
        it is training set samples for computing training set accuracy

    Returns
    -------
    true : int
        number of true predictions
    false : int
        number of false predictions

    """
    true = 0
    false = 0

    #test set classification

    for i in range(0,L):
        if k==1:
            distances = b[:,i]
            min_dist = min(distances)
            index = np.where(distances == min_dist)[0][0]
            pred = Label_train[index]
            test_class = labels[i]
            if test_class == pred:
                true = true+1
            else:
                false = false + 1
        if k>1:
            distances = b[:,i]
            Sort_dist = sorted(distances)
            del Sort_dist[k:]
            index = np.zeros((k))
            for m in range (0,k):
                index[m]=np.where(distances == Sort_dist[m])[0]
            index = index.astype(int)
            pred_neighbour = Label_train[index]
            pred_neighbour = pred_neighbour.tolist()
            numberofzeros = pred_neighbour.count(0)
            numberofones = pred_neighbour.count(1)
            if numberofzeros > numberofones:
                pred = 0
            else:
                pred = 1
            test_class = labels[i]
            if test_class == pred:
                true = true+1
            else:
                false = false + 1

    return true,false

def TS_Classification(k,TS1,labels1,DM1,TF,*args):
    """

    Parameters
    ----------
    k : int
        The nearest neighbor number.
    TS1 : list
        The list that includes the time series
    labels1 : np.array
        The list of labels belong to the set of time series
    DM1 : 2D np.array
        The pairwise distance matrix between the time series
    TF : boolean
        Set tot True if transfer learning will be applied
    *args :
        TS2 : list
            The list that includes the time series in the test set  when transfer learning is selected True
        labels2 : np.array
            The list of labels for the test set
        DM2 : 2D np.array
            The distance matrix for the test set time series data

    Returns
    -------
    output : dict
        Includes mean accuracy and standard deviation for training and test set.

    """
    accuracy_test =np.zeros((10))
    accuracy_train =np.zeros((10))
    if not TF:
        start_time_classification = time.time()
        for T in range(10):
            #split time series into test set and training set
            TS_train,TS_test, Label_train, Label_test = train_test_split(TS1, labels1, test_size=0.33)

            TS_train_L = len(TS_train)
            TS_test_L = len(TS_test)

            Label_train = Label_train
            Label_test = Label_test

            #find training set indices
            TS_train_index = np.zeros((TS_train_L))
            for i in range(0,TS_train_L):
                train_sample = TS_train[i]
                for j in range(0,len(TS1)):
                    if np.array_equal(TS1[j],train_sample):
                        TS_train_index[i] = j
            #find test set indices
            TS_test_index = np.zeros((TS_test_L))
            for i in range(0,TS_test_L):
                test_sample = TS_test[i]
                for j in range(0,len(TS1)):
                    if np.array_equal(TS1[j],test_sample):
                        TS_test_index[i] = j

            #generate distance matrix between test set and training set
            b = np.zeros(shape=(TS_train_L,TS_test_L))
            for i in range (0,TS_train_L):
                train_index = int(TS_train_index[i])
                for j in range(0,TS_test_L):
                    test_index = int(TS_test_index[j])
                    b[i,j]=DM1[train_index,test_index]

            #k-NN classification
            true,false = kNN(k,TS_test_L,b,Label_train,Label_test)
            accuracy_test[T] = true/(true+false)

            # the distance matrix between the training set samples
            b2 = np.zeros(shape=(TS_train_L,TS_train_L))
            for i in range (0,TS_train_L):
                train_index_1 = int(TS_train_index[i])
                for j in range(0,TS_train_L):
                    train_index_2 = int(TS_train_index[j])
                    b2[i,j]=DM1[train_index_1,train_index_2]

            #training set classification
            true,false = kNN(k,TS_train_L,b2,Label_train,Label_train)
            accuracy_train[T] = true/(true+false)

        mean_score_test = np.mean(accuracy_test)
        deviation_test=np.std(accuracy_test)
        mean_score_train = np.mean(accuracy_train)
        deviation_train = np.std(accuracy_train)
        end_time_classification = time.time()
        classfication_time = end_time_classification - start_time_classification

        print('Score(Test Set): {} Deviation(Test Set): {}'.format(mean_score_test,deviation_test))
        print('Score(Training Set): {} Deviation(Training Set): {}'.format(mean_score_train,deviation_train))
        print('Classification Time: {}'.format(classfication_time))

        output = {}
        output['mean_test_score'] = mean_score_test
        output['dev_test']= deviation_test
        output['mean_train_score'] = mean_score_train
        output['dev_train'] = deviation_train
        output['clf_time'] = classfication_time
    else:
        TS2 = args[0]
        labels2 = args[1]
        DM2 = args[2]
        start_time_classification = time.time()
        for T in range(0,10):
            #split time series into test set and training set
            TS_training_train,TS_training_test, Label_train_train, Label_train_test = train_test_split(TS1, labels1, test_size=0.33)
            TS_test_train,TS_test_test, Label_test_train, Label_test_test = train_test_split(TS2, labels2, test_size=0.67)

            TS_train_L = len(TS_training_train)
            TS_test_L = len(TS_test_test)

            Label_train = Label_train_train
            Label_test = Label_test_test

            #find training set indices
            TS_train_index = np.zeros((TS_train_L))
            for i in range(0,TS_train_L):
                train_sample = TS_training_train[i]
                for j in range(0,len(TS1)):
                    if np.array_equal(TS1[j],train_sample):
                        TS_train_index[i] = j
            #find test set indices
            TS_test_index = np.zeros((TS_test_L))
            for i in range(0,TS_test_L):
                test_sample = TS_test_test[i]
                for j in range(0,len(TS2)):
                    if np.array_equal(TS2[j],test_sample):
                        TS_test_index[i] = j

            #generate distance matrix between test set and training set
            b = np.zeros(shape=(TS_train_L,TS_test_L))
            for i in range (0,TS_train_L):
                train_index = int(TS_train_index[i])
                for j in range(0,TS_test_L):
                    test_index = int(TS_test_index[j])
                    b[i,j]=DM1[train_index,test_index]

            #test set classification
            true,false = kNN(k,TS_test_L,b,Label_train,Label_test)
            accuracy_test[T] = true/(true+false)

            #distance matrix for training set
            b2 = np.zeros(shape=(TS_train_L,TS_train_L))
            for i in range (0,TS_train_L):
                train_index_1 = int(TS_train_index[i])
                for j in range(0,TS_train_L):
                    train_index_2 = int(TS_train_index[j])
                    b2[i,j]=DM2[train_index_1,train_index_2]

            #training set classification
            true,false = kNN(k,TS_train_L,b2,Label_train,Label_train)
            accuracy_train[T] = true/(true+false)

        mean_score_test = np.mean(accuracy_test)
        deviation_test=np.std(accuracy_test)
        mean_score_train = np.mean(accuracy_train)
        deviation_train = np.std(accuracy_train)
        end_time_classification = time.time()
        classfication_time = end_time_classification - start_time_classification

        print('Score(Test Set): {} Deviation(Test Set): {}'.format(mean_score_test,deviation_test))
        print('Score(Training Set): {} Deviation(Training Set): {}'.format(mean_score_train,deviation_train))
        print('Classification Time: {}'.format(classfication_time))

        output = {}
        output['mean_test_score'] = mean_score_test
        output['dev_test']= deviation_test
        output['mean_train_score'] = mean_score_train
        output['dev_train'] = deviation_train
        output['clf_time'] = classfication_time

        end_time_classification = time.time()
        classfication_time = end_time_classification - start_time_classification

    return output

def TriangularInequalityLoosenes(DM):
    """

    Parameters
    ----------
    DM : 2D np.array
        The pairwise distance matrix for the time series data set

    Returns
    -------
    H : list
        The list that includes the looseness constants computed for all combinations of three time series in the data set

    """
    d_N =len(DM)
    H = []
    inc=0
    for i in range(d_N):
        for j in range(d_N):
            for k in range(d_N):

                if i==j:
                    pass
                elif j==k:
                    pass
                elif i==k:
                    pass
                else:

                    D1 = DM[i,j]
                    D2 = DM[j,k]
                    D3 = DM[i,k]

                    H.append(D1+D2-D3)
                    inc = inc+1
    return H

def plot_Looseness_Constants(H):
    """

    Parameters
    ----------
    H : list
        The list that includes the looseness constants computed for all combinations of three time series in the data set

    Returns
    -------
    fig : figure
        Returns the histogram plot of the looseness constant

    """
    fs = 20
    plt.hist(H, 500, density=True, facecolor='g', alpha=0.75)
    ax = plt.gca()
    plt.xlabel('Looseness (H)',fontsize=fs-5)
    plt.ylabel('Frequency',fontsize=fs-5)
    # plt.tick_params(axis='x',which='both',bottom=False,top=False,labelbottom=False)
    plt.xlim([0,max(H)])
    for tick in ax.xaxis.get_major_ticks():
        tick.label.set_fontsize(fs-5)
    for tick in ax.yaxis.get_major_ticks():
        tick.label.set_fontsize(fs-5)
    fig = plt.gcf()
    # textstr = Title[i]
    # props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
    # # place a text box in upper left in axes coords
    # ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14,
    #         verticalalignment='top', bbox=props)
    # plt.subplots_adjust(hspace=0.1)

    return fig

def AESA_Classification(TS,labels,H,DM,WS):
    """

    Parameters
    ----------
    TS : list
        The list that includes the time series data
    labels : np.array
        The list that includes the labels of each time series
    H : float
        the looseness constant that will be taken account during elimination
    DM : 2D np.array
        The pairwise distance matrix between the time series data
    WS : int
        Window size for sakoeChibaWindow

    Returns
    -------
    output : list of dicts
        The list that includes the results. Each dictionary includes accuracy, average number of distance computations,
        number of distance computations made for each test sample, the length of training and test sets.

    """
    # divide data set into training set and test set
    Training_set, Test_set,  Label_train, Label_test = train_test_split(TS, labels, test_size=0.33,random_state=30)

    TS_train_L = len(Training_set)
    TS_test_L = len(Test_set)

    #find training set indices
    TS_train_index = np.zeros((TS_train_L))
    for i in range(0,TS_train_L):
        train_sample = Training_set[i]
        for j in range(0,len(TS)):
            if np.array_equal(TS[j],train_sample):
                TS_train_index[i] = int(j)

    #find test set indices
    TS_test_index = np.zeros((TS_test_L))
    for i in range(0,TS_test_L):
        test_sample = Test_set[i]
        for j in range(0,len(TS)):
            if np.array_equal(TS[j],test_sample):
                TS_test_index[i] = int(j)

    #generate the distance matrix for training set
    Training_Set_DM = np.zeros(shape=(TS_train_L,TS_train_L))
    for i in range (0,TS_train_L):
        train_index_1 = int(TS_train_index[i])
        for j in range(0,TS_train_L):
            train_index_2 = int(TS_train_index[j])
            Training_Set_DM[i,j]=DM[train_index_1,train_index_2]

    #------------------AESA Algorithm------------------------------------
    test_no = np.arange(0,len(Test_set),1)
    assigned_label=np.zeros((len(test_no),1))
    number_dtw_comp = np.zeros((len(test_no),1))
    duration = np.zeros((len(test_no),1))

    inc=0
    nearest_sample = []
    true = 0
    false = 0
    for test_samp in test_no:
        start = time.time()

        P = list(range(len(Training_set)))

        #initialize the set of used samples
        U = []
        #initialize the set of eliminated samples
        E = []

        count=0
        D = []
        while np.all(np.unique(E)==P)==False:
            # select s as the pseudocentre of P in the first iteration
            if count==0:
                #select s based on the pseudocenter of the training set
                SUM = sum(Training_Set_DM)
                minimum= min(SUM)
                s = np.where(SUM==minimum)[0][0]
                #add s to used set of samples
                U.append(s)
                #current nearest sample (n)
                n = s
                #distance between nearest sample and the test sample
                x = np.ravel(TS[int(TS_test_index[test_samp])])
                t_c = np.ravel(TS[int(TS_train_index[s])])
                Dx_c = DTW_Distance_Comp(x,t_c,WS,False,True)
                D_x_n = Dx_c
                D.append(Dx_c)
                #elimination
                c=[s]
                set_p_c = list(set(P)-set(c))
                E.append(s)
                for i in range(len(set_p_c)):
                    q = set_p_c[i]
                    D_qc = Training_Set_DM[q,c]

                    if D_qc> 2*Dx_c-H or D_qc<H:
                        E.append(q)
                count = count+1
            else:
                difference_set = list(set(P)-set(E))
                Summ=[]
                for i in range(len(difference_set)):
                    p = difference_set[i]
                    Sum=0
                    for j in range(len(U)):
                        q = U[j]

                        D_p_q = Training_Set_DM[p,q]
                        D_x_q = D[j]

                        Sum = Sum+abs(D_p_q-D_x_q)
                    Summ.append(Sum)
                minimum = min(Summ)
                ind = np.where(Summ==minimum)[0][0]
                s = difference_set[ind]
                # DTW computation
                x = np.ravel(TS[int(TS_test_index[test_samp])])
                t_c = np.ravel(TS[int(TS_train_index[s])])
                D_x_s = DTW_Distance_Comp(x,t_c,WS,False,True)
                D.append(D_x_s)
                #update U and E
                U.append(s)
                E.append(s)

                #update nearest member
                if D_x_s<D_x_n:
                    Q=U
                    n=s
                    D_x_n = D_x_s
                else:
                    Q = [s]

                #elimination
                set_p_e = list(set(P)-set(E))
                for i in range(len(Q)):
                    q = Q[i]
                    for j in range(len(set_p_e)):
                        p = set_p_e[j]
                        D_p_q= Training_Set_DM[p,q]
                        D_x_q = D[i]

                        if D_p_q> D_x_q+D_x_n-H or D_p_q< D_x_q-D_x_n+H:
                            E.append(p)

                count = count+1

        end = time.time()
        duration[inc,0]=end-start
        #classification
        assigned_label[inc,0]=Label_train[n]
        test_class = Label_test[test_samp]
        # print('predicted={},true label={}'.format(Label_train[n],test_class))
        if test_class == Label_train[n]:
            true = true+1
        else:
            false = false + 1
        nearest_sample.append(n)
        print('Test sample {} completed--->NumofDistComp:{},ClosestSample:{},predictedLabel:{}'.format(test_samp,count,n,assigned_label[inc,0]))
        number_dtw_comp[inc,0]=count
        average_dtw_comp = sum(number_dtw_comp[:,0])/len(Label_test)
        inc=inc+1

    accuracy= true/(true+false)*100
    output = {}
    output['ave_dist_comp'] = average_dtw_comp
    output['n_dist_comp'] = number_dtw_comp
    output['accuracy'] = accuracy
    output['train_length'] = len(TS_train_index)
    output['test_length'] = len(TS_test_index)

    return output

def plot_AESA_results(output,H_range):
    """

    Parameters
    ----------
    output : list of dicts
        The list that includes the results. Each dictionary includes accuracy, average number of distance computations,
        number of distance computations made for each test sample, the length of training and test sets.
    H_range : np.array
        The range of looseness constant which user wants to try to see how it changes the classification accuracy

    Returns
    -------
    fig : figure
        The left axis represents the accuracy, while right axis is for the average number of distance computations made for each looseness constant value.

    """
    fs=20
    accuracy = []
    average_dtw_computation = []
    for i in range(len(output)):
        average_dtw_computation.append(output[i]['ave_dist_comp'])
        accuracy.append(output[i]['accuracy'])

    # Create some mock data
    fig, ax1 = plt.subplots()

    color = 'tab:red'
    ax1.set_xlabel('Looseness (H)',fontsize=fs-5)
    ax1.set_ylabel('Accuracy', color=color,fontsize=fs-5)
    ax1.plot(H_range, accuracy,color=color,linewidth=2)
    ax1.tick_params(axis='y', labelcolor=color)
    plt.ylim([0,100])
    ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis

    color = 'tab:green'
    ax2.set_ylabel('Average number of DTW Computation', color=color, fontsize=fs-5,rotation=270)  # we already handled the x-label with ax1
    ax2.plot(H_range, average_dtw_computation, color=color,linewidth=2)
    ax2.plot([0,max(H_range)],[output[0]['train_length'],output[0]['train_length']],'k',linewidth=1.5,label ='Training \nSet Length')
    ax2.tick_params(axis='y', labelcolor=color)
    ax2.legend(loc='lower left', ncol=1, prop={'size': fs-7.5})
    # ax1.legend(loc='lower left', ncol=1, prop={'size': fs-7.5})

    # textstr = 'Training set length'
    # # place a text box in upper left in axes coords
    # ax1.text(0.05, 1, textstr, transform=ax1.transAxes, fontsize=14,
    #         verticalalignment='top')

    # for tick in ax1.xaxis.get_major_ticks():
    #     tick.label.set_fontsize(fs)
    # for tick in ax1.yaxis.get_major_ticks():
    #     tick.label.set_fontsize(fs)

    for tick in ax2.yaxis.get_major_ticks():
        tick.label.set_fontsize(fs+5)

    ax2.yaxis.set_label_coords(1.1,0.5)

    fig.tight_layout()  # otherwise the right y-label is slightly clipped
    plt.show()
    return fig

if __name__ == '__main__':
    # generate two time series
    ts1 = np.linspace(0,6.28,num=100)
    ts2 = np.sin(ts1) + np.random.uniform(size=100)/10.0

    # compute the distance between and the plot the warping path
    distance = DTW_Distance_Comp(ts1,ts2,5,True,False)

    # generate synthetic data set

    TS1 = []
    for i in range(15):
        fs, T = 100, 10
        t = np.linspace(-0.2,T,fs*T+1)
        A = 20
        TS1.append(A*np.sin((i+1)*np.pi*t) + A*np.sin(1*t))

    # serial distance computation
    DM1 = DTW_Dist_Mat(TS1,False,False)
    # parallel distance computation
    DM2 = DTW_Dist_Mat(TS1,False,True)

    # Generate the second set of time series so that we can apply transfer learning
    TS2 = []
    for i in range(20):
        fs, T = 100, 10
        t = np.linspace(-0.2,T,fs*T+1)
        A = 20
        TS2.append(A*np.sin((2*i+1)*np.pi*t) + A*np.sin(2*t))

    # serial distance computation
    DM_TF1 = DTW_Dist_Mat(TS1,True,False,TS2)
    # parallel distance computation
    DM_TF2 = DTW_Dist_Mat(TS1,True,True,TS2)

    # perform classification
    labels1 = np.random.choice([0, 1], size=(len(TS1),), p=[1./3, 2./3])
    out = TS_Classification(1,TS1,labels1,DM1,False)

    # perform classification using transfer learning
    labels2 = np.random.choice([0, 1], size=(len(TS2),), p=[1./3, 2./3])
    out = TS_Classification(1,TS1,labels1,DM_TF1,True,TS2,labels2,DM_TF2)

    # AESA ---

    # Generate the second set of time series so that we can apply transfer learning
    TS3 = []
    for i in range(50):
        fs, T = 100, 10
        t = np.linspace(-0.2,T,fs*T+1)
        A = 20
        TS3.append(A*np.sin((2*i+1)*np.pi*t) + A*np.sin(2*t))
    labels3 = np.random.choice([0, 1], size=(len(TS3),), p=[1./3, 2./3])
    # parallel distance computation
    DM3 = DTW_Dist_Mat(TS3,False,True)

    # Check if there is any violiation to triangular inequality
    H = TriangularInequalityLoosenes(DM3)

    # plot the loosenes constants
    plt.figure()
    fig = plot_Looseness_Constants(H)
    plt.show()

    # define a range for the H value
    H_range = np.linspace(0,20000,20)

    # run the AESA for each value in H_range
    output=[]
    for i in H_range:
        output.append(AESA_Classification(TS3,labels3,i,DM3,100))

    #plot the results
    plt.figure()
    plot_AESA_results(output,H_range)
    plt.show()


class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        '''
        HashSet lookup O(1)
        Time O(m+n)
        Space O(m+n)
        '''
        n1 = set(nums1)
        n2 = set(nums2)
        res = set()
        if len(n1) > len(n2):
            n1, n2 = n2, n1
        for i in n1:
            if i in n2:
                res.add(i)
        return res

'''
Follow up, if the arrays are sorted, we can use two-pointers to iter them.
'''
def intersection2(nums1: List[int], nums2: List[int]) -> List[int]:
    nums1.sort()
    nums2.sort()

    res = []

    left, right = 0, 0
    while left < len(nums1) and right < len(nums2):
        left_val = nums1[left]
        right_val = nums2[right]

        if right_val == left_val:
            res.append(nums2[right])
            while right < len(nums2) and nums2[right] == right_val:
                right += 1
            while left < len(nums1) and nums1[left] == left_val:
                left += 1
        if right_val > left_val:
            while left < len(nums1) and left_val == nums1[left]:
                left += 1
        else:
            while right < len(nums2) and right_val == nums2[right]:
                right += 1
    return res