import numpy as np
import tensorflow as tf
from tensorflow_probability import distributions as tfd
import gpflow as gpf
from gpflow.utilities import print_summary, set_trainable, to_default_float, deepcopy, positive
from itertools import groupby
from operator import itemgetter
from gpflow import Parameter
import copy
from sklearn.model_selection import train_test_split
from scipy.stats import multivariate_normal
from .tools.utils import get_data_stats
from .tools.kernels import create_linear, create_period, create_rbf, Interaction, Linear, Periodic
from .DirichletProcess import MarginalGibbsSampler
from .KernelSelection import BIC, MAP

class TrajectoryModel:
    def __init__(self,
            X_list,                     # dictionary indexed by (m, t) of the data matrices
            y_list,                     # dictionary indexed by (m, t) of the prediction targets
            z_init = np.ones(0),              # initial clustering of customers. Array whose length is the total number of customers.
                                        # indexing corresponds to the reservations. For example, if customer (0, 0) is in index
                                        # 0 in restaurant "", then z_init[0] is that customer's table.
            reservations = None,        # dictionary which maps restaurant (string representation of model) to a list
                                        # of customers (reservations[""] = [(0, 0), (0, 1), (1, 0), (1, 1)])
            model_to_string = None,     # function which returns string representation of model structure
            likelihood_func = None,     # function which returns log p(y | X, M, hypers)
            likelihood_params = {},     # parameters of likelihood calculation, contains info on heartsteps and mean function
            hyper_priors = {},          # dictionary mapping from hyperparater element to a TFD distribution. Structure
                                        # depends on the application. For kernels, hyper_priors['lengthscale'] = LogNormal
#            hyper_constructor = None,   # Hyperparameter class constructor. Depends on application.
            base_distribution_constructor = None, # Constructor for distribution over model structure
            base_distribution_args = {}, # Dictionary of args for base distribution
            seed = 0,
            alpha = 1,                  # DP parameter
            heartsteps = False,  # whether or not we are predicting for heartsteps (relevant for kernel)
            adapt_noise_prior = False,  # whether or not to adapt noise prior for children
            parent_kernel_prob = None): # bias the children toward the parents kernel.
        np.random.seed(seed)
        tf.random.set_seed(seed)

        # model parameters
        self.base_distribution_constructor = base_distribution_constructor
        self.base_distribution_args = base_distribution_args
        self.base_distribution_args['hyper_priors'] = hyper_priors
        self.alpha = alpha
        self.to_string = model_to_string
        self.lml = likelihood_func
        self.lml_params = likelihood_params
        # hyperparameters
        self.hyper_priors = hyper_priors # TODO: Is this needed? can we replace by passing list of kernels?
        self.adapt_noise_prior = adapt_noise_prior

        # GLOBAL paramaters (things indexed by restaurant)
        self.restaurants = {}
        # sample random parameters for each table
        base_distribution = base_distribution_constructor(**self.base_distribution_args)
        if adapt_noise_prior:
            base_distribution.hyper_priors['noise'] = self.noise_prior("") # parent has 0 elements
        thetas = [base_distribution.sample() for table in range(np.unique(z_init).shape[0])]
        self.restaurants[''] = MarginalGibbsSampler(alpha, base_distribution, '', z = z_init, thetas = thetas)

        # LOCAL parameters (things indexed by m, t)
        self.M, self.T = get_data_stats(X_list)
        self.num_customers = sum(self.T)

        self.K = {} # track each customers composition (K[(m, t)] = kernel_name)
        for m in range(self.M):
            for t in range(self.T[m]):
                self.K[(m, t)] = "" # TODO: should this be set to the value sampled as the initially sampled thetas?

        self.kernels = {} # track the kernel itself (self.kernels[(m, t)] = kernel)
        self.reservations = reservations # a dictionary of customers at each restaurant (self.reservations[restaurant] = customers). Indices correspond to the z list.

        # Data
        self.X_list = X_list
        self.y_list = y_list

        self.heartsteps = heartsteps
        self.parent_kernel_prob = parent_kernel_prob

    def seat_customers(self):
        '''
        assigns customers to tables
        '''
        for m in range(self.M): # for each task
            #print("Seating customer {}".format(m))
            for t in range(self.T[m] -1, -1, -1): # for each time point, in reverse TODO: check if needs + 1
            #for t in range(self.T[m]): # for each time point TODO: check if needs + 1
                # get data
                X = self.X_list[(m, t)]
                y = self.y_list[(m, t)]
                # get actual restaurant, index of customer, unseat
                for restaurant, customers in self.reservations.items():
                    if (m, t) in customers: # found customer
                        # note location
                        og_restaurant = restaurant
                        i = customers.index((m, t))
                        break
                # unseat customer
                del self.reservations[og_restaurant][i]
                dp = self.restaurants[og_restaurant]
                prev_dish = copy.deepcopy(dp.thetas[dp.z[i]]) # track the model at the table the customer used to sit at
                dp.unseat(i)

                # close restaurant if empty
                if dp.num_customers == 0:
                    del self.restaurants[og_restaurant] # remove
                    del self.reservations[og_restaurant]

                # seat user in updated restaurant
                if t > 0:
                    restaurant = self.K[(m, t - 1)]
                else:
                    restaurant = ""

                if restaurant not in self.restaurants:
                    #print("ADDING")
                    #print(self.parent_kernel_prob, " ", t)
                    H0 = self.base_distribution_constructor(**self.base_distribution_args)
                    # probability towards parent kernel (restaurant)
                    if self.parent_kernel_prob is not None and t > 0:
                        kernel_vec = H0.get_structure(self.kernels[(m, t-1)])
                        H0.p[kernel_vec > 0] = self.parent_kernel_prob

                    # noise prior
                    if self.adapt_noise_prior:
                        H0.hyper_priors['noise'] = self.noise_prior(restaurant) # parent has 0 elements
                    #    print("updated inclusion")
                    self.restaurants[restaurant] = MarginalGibbsSampler(self.alpha, H0, restaurant) # new dp

                dp = self.restaurants[restaurant]

                # assign to a table at restaurant
                dp.assign_table(X, y, self.lml, self.lml_params,  prev_dish = prev_dish)

                # is now the n-th customer at the restaurant, so update the location!
                if restaurant in self.reservations:
                    self.reservations[restaurant].append((m, t))
                else:
                    self.reservations[restaurant] = [(m, t)]

                # updates
                og_plate = self.K[(m, t)]
                #new_plate = self.to_string(dp.thetas[int(dp.z[-1])])
                new_plate = self.to_string(dp.thetas[int(dp.z[-1])]['structure'])
                self.K[(m, t)] = new_plate # update composition
                self.kernels[(m, t)] = dp.thetas[int(dp.z[-1])]

        if np.sum([len(guests) for rest, guests in self.reservations.items()]) != self.num_customers:
            raise ValueError("Did not pass seating check! Number seating != num customers")

    def noise_prior(self, model):
        '''
        determines noise prior based on number of parent's components
        '''
        if model == "" or "White" in model:
            num_components = 0
        else:
            num_components = len(model.split("+"))
        #print(model, "has ", num_components, "components")
        if num_components == 0:
            return {'mean':2, 'var': 0.5}
        elif num_components == 1:
            return {'mean':1, 'var': 1}
        else:
            return {'mean':0, 'var': 2}

    def plate_tables(self, mh_params = {}):
        '''
        updates the composition at each table based on who is sitting there
        MH-sampler
        '''

        # Make sure restaurants and locations sync
        '''
        location_rest = np.array(list(self.reservations.keys()))
        location_rest_counts = np.array([len(val) for val in self.reservations.values()])
        rest_counts = np.array([dp.num_customers for rest, dp in self.restaurants.items()])
        rest = np.array(list(self.restaurants.keys()))
        sort = np.argsort(rest_counts)
        '''
        for restaurant, dp in self.restaurants.items():
            if dp.num_customers > 0: # non leaf node
                # Get ordered list of customers at the restuarant
                customers = self.reservations[restaurant]
                dp.update_tables_mh_full(self.X_list, self.y_list, self.lml, self.lml_params, customers, **mh_params)

                # update K_{m, t} based on what is at table
                for i, customer in enumerate(customers):
                    #self.K[(customer[0], customer[1])] = self.to_string(dp.thetas[int(dp.z[i])])
                    self.K[(customer[0], customer[1])] = self.to_string(dp.thetas[int(dp.z[i])]['structure'])
                    self.kernels[(customer[0], customer[1])] = dp.thetas[int(dp.z[i])]

        # Reconstruct structure
        new_reservations = {}
        new_restaurants = {}
        for m in range(self.M):
            for t in range(self.T[m]):
                model = self.kernels[(m, t)]
                model_string = self.K[(m, t)]
                if t > 0:
                    restaurant = self.K[(m, t - 1)]
                else:
                    restaurant = ""

                if restaurant in new_restaurants: # already started DP
                    dp = new_restaurants[restaurant]
                    dishes = [self.to_string(theta['structure']) for theta in dp.thetas]
                    new_reservations[restaurant].append((m, t))
                    # place in restaurant
                    if model_string in dishes: # dish already exists, place at table
                        index = dishes.index(model_string)
                        dp.z = np.append(dp.z, index)
                        dp.num_customers += 1
                    else:
                        dp.thetas.append(model) # TODO: not sure if by reference...buggy?
                        dp.z = np.append(dp.z, dp.num_tables)
                        dp.num_tables += 1
                        dp.num_customers +=1
                else: # start new restaurant, place customer
                    H0 = self.base_distribution_constructor(**self.base_distribution_args)
                    # probability towards parent kernel (restaurant)
                    if self.parent_kernel_prob is not None and t > 0:
                        kernel_vec = H0.get_structure(self.kernels[(m, t-1)])
                        H0.p[kernel_vec > 0] = self.parent_kernel_prob

                    # noise prior
                    if self.adapt_noise_prior:
                        H0.hyper_priors['noise'] = self.noise_prior(restaurant)

                    new_restaurants[restaurant] = MarginalGibbsSampler(self.alpha, H0, restaurant, thetas = [model], z = np.array([0])) # new dp
                    new_reservations[restaurant] = [(m, t)]
        del self.restaurants
        del self.reservations
        self.restaurants = new_restaurants
        self.reservations = new_reservations

    def posterior_likelihood(self):
        '''
        ll = 0
        dp = self.restaurants[""]
        for m in range(self.M):
            for t in range(self.T[m]):
                new_likelihood = self.lml(self.X_list[(m, t)], self.y_list[(m, t)], self.kernels[(m, t)], **self.lml_params)

        new_prior = tf.squeeze(dp.base_dist.log_prob(self.kernels[(m,t)])).numpy()
        ll += (new_likelihood + new_prior)
        '''
        # User likelihood
        user_lmls = self.total_lml()
        # Model prior
        structure_prior = 0
        for restaurant, dp in self.restaurants.items():
            for table in dp.thetas:
                table_prior = dp.base_dist.log_prob(table)
                structure_prior += table_prior
        print("likelihood: ", user_lmls.numpy(), "prior: ", structure_prior.numpy())
        return float(user_lmls + structure_prior)

    def total_lml(self):
        lml = 0
        for m in range(self.M):
            for t in range(self.T[m]):
                new_lml = self.lml(self.X_list[(m, t)], self.y_list[(m, t)], self.kernels[(m, t)], **self.lml_params)
                lml += new_lml
        return lml

    def print(self):
        for m in range(self.M):
            traj = ""
            for t in range(self.T[m]):
                traj += "--> {}/{:.2f}".format(self.K[(m, t)], self.kernels[(m,t)]['noise'])
            print("Task {}: {}".format(m, traj))

    def iterate(self, n_seating = 5, mh_params = {}):
        '''
        goes through one Gibbs sweep of all steps in the following order: seat, plate, update hypers
        '''
        # seat customers
        print("SEATING CUSTOMERS")
        for i in range(n_seating):
            print("Seating iteration {}".format(i))
            self.seat_customers()
        self.print()

        # plate tables
        print("PLATING TABLES")
        self.plate_tables(mh_params)
        self.print()

    def _form_leaves(self):
        self.leaves = {}
        for m in range(self.M):
            model = self.kernels[(m, self.T[m] - 1)] # Get all the "leaves" (final kernels)
            # Get prior
            if self.T[m] > 1:
                restaurant = self.K[(m, self.T[m] - 2)]
            else:
                restaurant = ""

            base_dist = self.restaurants[restaurant].base_dist
            self.leaves[restaurant + self.to_string(model['structure'])] = (model, base_dist)

    def select_leaf(self, X, y, learn_hypers = False, validation = None):
        lmls = []
        models = []
        for structure, selection in self.leaves.items():
            if learn_hypers:
                if validation is not None:
                    X_train, X_val, y_train, y_val = train_test_split(X, np.array(y), test_size=0.33)
                    opt_model, bic = BIC(X_train, y_train, selection[0], selection[1], **self.lml_params)
                    bic = validation(opt_model, X_train, y_train, X_val, y_val)
                else:
                    opt_model, bic = BIC(X, y, selection[0], selection[1], **self.lml_params)
            else:
                if validation is not None:
                    X_train, X_val, y_train, y_val = train_test_split(X, np.array(y), test_size=0.33)
                    opt_model = selection[0]
                    bic = validation(opt_model, X_train, y_train, X_val, y_val)
                else:
                    opt_model = selection[0]
                    bic = self.lml(X, y, selection[0], **self.lml_params) + tf.squeeze(selection[1].log_prob(selection[0])).numpy()

            lmls.append(bic)
            models.append(opt_model)
        print("leaf options: {}".format([self.to_string(mod['structure']) for mod in models]))
        print("leaf lmls: {}".format([tf.squeeze(lik).numpy() for lik in lmls]))
        print("chose leaf {}".format(self.to_string(models[np.argmax(lmls)]['structure'])))
        return models[np.argmax(lmls)], lmls # Return best leaf

    def form_strata(self):
        T_max = np.max(self.T)
        self.strata = []
        for t in range(T_max):
            # See what other users had here
            options = {}
            for m in range(self.M):
                option = self.kernels[(m, t)]
                if option['structure'] not in options:
                    options[option['structure']] = option
            options = list(options.values())
            print("Options at time {}: {}".format(t, [self.to_string(k) for k in options]))
            self.strata.append(options)

    def predict_trajectory(self, X_train_list, y_train_list, threshold = 1, prioritize_leaves = False, learn_hypers = False, validation = None):
        '''
        traverse tree conditionally
        '''
        curr_model_string = ""
        curr_model = None
        curr_model_initial = None
        T = len(y_train_list)
        lmls = []
        models = []
        at_leaf = False
        for t in range(T):
            print("SHAPE", X_train_list[t].shape)
#            print("Curr node: {}".format(curr_model_string))
            # data
            X = X_train_list[t]
            y = y_train_list[t]
            if prioritize_leaves:
                leaf, likelihoods = self.select_leaf(X, y, learn_hypers = learn_hypers, validation = validation)
                likelihoods = np.sort(likelihoods)
                traverse = False
                if likelihoods.shape[0] >= 2: # At least two options
                    traverse = np.abs(likelihoods[-1] - likelihoods[-2]) < threshold # ambiguity between two options
            else:
                traverse = True
            if traverse:
                # get current restaurant
                if curr_model_string in self.restaurants:
                    dp = self.restaurants[curr_model_string]

                if dp.num_tables > 0: # not a leaf node
                    # add self loop
                    model_represented = (curr_model_string in [self.to_string(theta['structure']) for theta in dp.thetas])
                    #model_represented = False
                    thetas = list(dp.thetas)
                    if model_represented == False and curr_model is not None:
                    #if curr_model is not None:
                        #thetas.append(curr_model_initial)
                        thetas.append(curr_model)
                    print(thetas)
                    # get table with the highest model likelihood
                    tables = []
                    table_likelihoods = []
                    for theta in thetas:
                        if learn_hypers:
                            if validation is not None:
                                X_train, X_val, y_train, y_val = train_test_split(X, np.array(y), test_size=0.33)
                                table_model, bic = BIC(X_train, y_train, theta, dp.base_dist, **self.lml_params)
                                bic = validation(table_model, X_train, y_train, X_val, y_val)
                            else:
                                table_model, bic = BIC(X, y, theta, dp.base_dist, **self.lml_params)
                        else:
                            table_model = theta
                            if validation is not None:
                                X_train, X_val, y_train, y_val = train_test_split(X, np.array(y), test_size=0.33)
                                bic = validation(theta, X_train, y_train, X_val, y_val)
                            else:
                                bic = self.lml(X, y, theta, **self.lml_params) + tf.squeeze(dp.base_dist.log_prob(theta)).numpy()

                        table_likelihoods.append(bic)
                        tables.append(table_model)

                    # get the new model
                    top_i= np.argsort(table_likelihoods)
                    next_table = top_i[-1]
                    curr_table = tables[next_table]
                    curr_model_initial = thetas[next_table]
                    curr_model = {key:item for key, item in curr_table.items()}
                    curr_model_string = self.to_string(curr_model['structure'])
                    models.append(curr_model)

                    print("options: {}".format([self.to_string(mod['structure']) for mod in tables]))
                    print("lmls: {}".format([tf.squeeze(lik).numpy() for lik in table_likelihoods]))
                    print("chose: {}".format(curr_model_string))

                else: # leaf node, stay here
                    at_leaf = True
                    curr_model = {key:item for key, item in curr_model.items()}
                    curr_model_string = self.to_string(curr_model['structure'])
                    if learn_hypers:
                        curr_model, bic = BIC(X, y, curr_model_initial, dp.base_dist, **self.lml_params)
                    print("leaf node {}".format(curr_model_string))
                    models.append(curr_model)
            else:
                models.append(leaf)

        return models


from subprocess import Popen, PIPE
from tests import PROJECT_DIR, TESTDATA
import json

MYTH = str(PROJECT_DIR / "myth")

def test_parallel():

    test_file = str(TESTDATA / "input_contracts" / "origin.sol")
    program = f"python3 {MYTH} a {test_file} --solv 0.5.0 -o json"
    processes = [Popen(program, stdout=PIPE, shell=True) for i in range(30)]
    for p in processes:
        out, err = p.communicate()
        json_output = json.loads(out.decode("utf-8"))
        assert json_output["success"] == True


# jsb/plugs/count.py
#
#

""" count number of items in result queue. """

## jsb imports

from jsb.lib.commands import cmnds
from jsb.utils.generic import waitforqueue
from jsb.lib.examples import examples

## count command

def handle_count(bot, ievent):
    """ show nr of elements in result list. """
    if not ievent.inqueue:
        ievent.reply("use count in a pipeline")
        return
    result = waitforqueue(ievent.inqueue, 5000)
    ievent.reply(str(len(result)))

cmnds.add('count', handle_count, ['USER', 'GUEST'])
examples.add('count', 'count nr of items', 'list | count')


from odoo.addons.contract.tests.test_contract import TestContractBase

class TestContract(TestContractBase):
    def setUp(self):
        super(TestContract, self).setUp()
        self.brand_id = self.env["res.brand"].create({"name": "brand"})
        self.account_receivable_type = self.env.ref(
            'account.data_account_type_receivable'
        )
        self.account_receivable_brand_default = self.env[
            'account.account'
        ].create(
            {
                'name': 'Receivable Brand Default',
                'code': 'RCV01',
                'user_type_id': self.account_receivable_type.id,
                'reconcile': True,
            }
        )
        self.partner_account_brand = self.env['res.partner.account.brand'].create(
            {
                'partner_id': self.contract.partner_id.id,
                'account_id': self.account_receivable_brand_default.id,
                'brand_id': self.brand_id.id,
                'account_type': 'receivable',
            }
        )

    def test_contract_create_branded_invoice(self):
        """ It should create a branded invoice based on the contract brand
        """
        self.contract.brand_id = self.brand_id
        invoice = self.contract.recurring_create_invoice()
        self.assertEqual(invoice.brand_id, self.brand_id)
        self.assertEqual(invoice.account_id, self.account_receivable_brand_default)

    def test_contract_analytic_account_onchange_brand(self):
        self.brand_id.analytic_account_id = self.env[
            'account.analytic.account'
        ].create({'name': 'analytic account'})
        self.contract.brand_id = self.brand_id
        self.assertFalse(
            self.contract.contract_line_ids.mapped('analytic_account_id')
        )
        self.contract._onchange_brand_id()
        self.assertEqual(
            self.contract.contract_line_ids.mapped('analytic_account_id'),
            self.brand_id.analytic_account_id,
        )


import sys

input = sys.stdin.readline
INF = int(1e9)  # 무한대(도달할 수 없는 지점)

V, E = map(int, input().split())
graph = [[INF] * (V + 1) for _ in range(V + 1)]  # i~j 까지 최단 경로

for _ in range(E):
    a, b, c = map(int, input().split())
    graph[a][b] = c  # 그래프에 최단경로 추가

for k in range(1, V + 1):  # 매개체
    for i in range(1, V + 1):  # 행
        for j in range(1, V + 1):  # 열
            graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j])  # 최솟값 갱신

ans = INF  # 정답을 나타낼 변수
for diagonal in range(1, V):  # 대각선
    for i in range(1, V - diagonal + 1):  # 행
        j = i + diagonal  # 열

        # ex) 1을 시작/목적으로 하는 사이클의 최단 경로는
        # 1~2 최단경로 + 2~1 최단경로 , 1~3 최단경로 + 3~1 최단경로...
        ans = min(ans, graph[i][j] + graph[j][i])  # 최솟값 갱신
print(ans) if ans != INF else print(-1)  # 도달할 수 없으면 -1 아니면 값 출력


#!/usr/bin/python3

"""Write a Python program to count the number of equal numbers from three given integers.
Sample Input:
(1, 1, 1)
(1, 2, 2)
(-1, -2, -3)
(-1, -1, -1)
Sample Output:
3
2
0
3"""

def noOfEquals(n1,n2,n3):
    if len(set([n1,n2,n3])) == 3: # Means no equals were found
        return 0
    else:
        return 4 - len(set([n1,n2,n3]))

if __name__ == "__main__":
    print(noOfEquals(1,1,1))
    print(noOfEquals(1,2,2))
    print(noOfEquals(-1,-2,-3))
    print(noOfEquals(-1,-1,-1))


"""
random.py
---------

Reconstruct a network from a random matrix
not taking the time series into account.

author: Brennan Klein
email: klein.br@husky.neu.edu
Submitted as part of the 2019 NetSI Collabathon.

"""

from .base import BaseReconstructor
import numpy as np
from ..utilities import create_graph, threshold

class RandomReconstructor(BaseReconstructor):
    """Returns a random graph (dummy class)."""

    def fit(self, TS, threshold_type='range', **kwargs):
        """Return a random correlation matrix with a threshold.

        The results dictionary also stores the weight matrix as
        `'weights_matrix'` and the thresholded version of the weight matrix
        as `'thresholded_matrix'`.

        Parameters
        ----------

        TS (np.ndarray)
            array consisting of :math:`L` observations from :math:`N` sensors.

        threshold_type (str)
            Which thresholding function to use on the matrix of
            weights. See `netrd.utilities.threshold.py` for
            documentation. Pass additional arguments to the thresholder
            using ``**kwargs``.

        Returns
        -------
        G (nx.Graph)
            a reconstructed graph with :math:`N` nodes.

        """
        N, L = TS.shape
        W = np.random.rand(N, N)
        A = threshold(W, threshold_type, **kwargs)
        G = create_graph(A)
        self.results['graph'] = G
        self.results['weights_matrix'] = W
        self.results['thresholded_matrix'] = A
        return G


# coding: utf-8

# In[2]:

def tree_search(tree):

    tree_vals = []

    def inorder(tree):
        inorder(tree.getLeftChild())
        tree_vals.append(tree.root_val)
        inorder(tree.getRightChild())

    def sort_trees(arr):
        return sorted(arr) == arr

    inorder(tree)
    sort_trees(tree)

# In[ ]:

#Without recursion

def is_binary_search_tree(root):

    # start at the root, with an arbitrarily low lower bound
    # and an arbitrarily high upper bound
    node_and_bounds_stack = [(root, -float('inf'), float('inf'))]

    # depth-first traversal
    while len(node_and_bounds_stack):
        node, lower_bound, upper_bound = node_and_bounds_stack.pop()

        # if this node is invalid, we return false right away
        if (node.value <= lower_bound) or (node.value >= upper_bound):
            return False

        if node.left:
            # this node must be less than the current node
            node_and_bounds_stack.append((node.left, lower_bound, node.value))
        if node.right:
            # this node must be greater than the current node
            node_and_bounds_stack.append((node.right, node.value, upper_bound))

    # if none of the nodes were invalid, return true
    # (at this point we have checked all nodes)
    return True


import pandas as pd
import plotly.graph_objects as go

df = pd.read_csv("csv/SampleLocations.csv")

fig = go.Figure(go.Bar(x = df['Name'], y = df['Count'],
                  hovertext=df['Timestamp'],
                  name='Devices connected to WIFI'))

fig.update_layout(title='UNCC CAMPUS WIFI DATA',
                   plot_bgcolor='rgb(230, 230,230)',
                   showlegend=True)

fig.write_html("wifichartinfo.html")


from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^upload_pic/$', views.upload_pic, name="upload_pic"),
    url(r'^homepage/$', views.homepage, name="home"),
    url(r'^images/$', views.ImageList.as_view()),
    url(r'^images/(?P<image_type>[\w\-]+)/$', views.ImageList.as_view()),
    url(r'^projects/$', views.ProjectsList.as_view()),
    url(r'^projects/(?P<status>[\w\-]+)/$', views.ProjectsList.as_view()),
]


# -*- coding: utf-8 -*-
"""
Created on Thu Jan 27 15:29:52 2022

@author: BRSch
"""

# =============================================================================
# Imports
# =============================================================================

import pandas as pd
pd.options.mode.chained_assignment = None  # default='warn'
import os
import regex as re
import json
import numpy as np

# =============================================================================
# Living Planet Index
#
# The living planet index data is retreived from two datasets, one for Dutch data,
# one for European data. These two datasets are merged into one. For this, two
# major transformations were required:
#    - European data used reference year 1970, has been transformed to match
#      the reference year used in Dutch data (1990). CI's are removed.
#    - Dutch data was on a scale of 0 to 100, has been set to scale of 0 to 1,
#      matching European data.
# =============================================================================
lpi_data= pd.read_csv("data/IPBES Europe-Central Asia.csv")

# Removed the "IPBES" part of geographical region
lpi_data["Title"]= [f"{title.split()[1]} {title.split()[2]}"
                    for title in lpi_data["Title"]]

# Selected for data from 1990 onwards
lpi_data= lpi_data.query('Year>= 1990')

# Scaled data to use reference year 1990 and set that value to 1
lpi_data["LPI_final"]= [value/lpi_data["LPI_final"].iloc[0]
                        for value in lpi_data["LPI_final"]]

# Removed confidence intervals
lpi_data["CI_low"]= [np.nan]*len(lpi_data)
lpi_data["CI_high"]= [np.nan]*len(lpi_data)

lpi_data_NLD= pd.read_excel("data/c-1569-001g-clo-07-nl.xlsx").drop("Waarneming", axis= 1)

# Added geographical region column
lpi_data_NLD["Title"]= ["Netherlands"]*len(lpi_data_NLD)

# Reordered columns and renamed them to same as European data
lpi_data_NLD= lpi_data_NLD.iloc[:, [1,2,3,4,0]]
lpi_data_NLD.columns= lpi_data.columns

# Set values to scale 0 to 1
for column in ["LPI_final", "CI_low", "CI_high"]:
    lpi_data_NLD[column]= [value/100 for value in lpi_data_NLD[column]]

# Merged datasets
lpi_data_EU= pd.concat([lpi_data, lpi_data_NLD], axis= 0)

# Write to csv in app data folder
lpi_data_EU.to_csv(f"{os.pardir}/data/lpi_data_EU.csv", index= False)
# =============================================================================
# IUCN redlist data
#
#   - The relevant columns were identified as 14, 17 and 21 (country, greater
#     geographical region), and 33 through 62 (RLI values).
#   - The selection of relevant columns was transformed into long format.
#   - Data was filtered to only include countries in Europe.
#   - Mean values of the greater geographical regions were added.
# =============================================================================
rli_data= pd.read_csv("data/Indicator_15.5.1%3A_Red_List_Index.csv")

# Filtering for European data
europe= ["Eastern Europe", "Southern Europe", "Western Europe", "Northern Europe"]
rli_data= rli_data.query(f'parentName in {europe}')

# Selecting relevant columns
relevant_columns= [14,17]+ list(range(33,62))
rli_data= rli_data.iloc[:, relevant_columns]

# Transform dataset from wide to long format
rli_data= pd.melt(rli_data, id_vars= ["geoAreaName", "parentName", "ISO3"],
                  var_name= "year", value_name= "RLI")

# Remove leading "year_" part of year string and change string entry of year into integer
rli_data["year"]= [int(entry.split("_")[1])
                   for entry in rli_data["year"]]

# Create European dataset with mean RLI values across the greater geographical regions
rli_data_EU= rli_data.groupby(by= ["parentName", "year"]).mean().reset_index(drop= False)

# Drop parentName column
rli_data.drop(["parentName"], axis= 1, inplace= True)

# Merge main dataset with European mean values
rli_data_EU= pd.concat([rli_data, rli_data_EU.rename(columns= {"parentName": "geoAreaName"})])

# Write to csv in app data folder
rli_data_EU.to_csv(f"{os.pardir}/data/rli_data_EU.csv", index= False)
# =============================================================================
# Dutch Nitrogen (and Phosphate) emission- and loss data
# =============================================================================
emission_data= pd.read_csv('data/83983NED_UntypedDataSet_24022022_122525.csv',
                           sep= ';', index_col= "ID")

# Rename column
emission_data.rename(columns= {"Perioden": "Jaar"}, inplace= True)

# Strip trailing whitespaces
emission_data["RegioS"]= [region.strip()
                          for region in emission_data["RegioS"]]

# Remove trailing "JJ00" part of year string and change string entry of year into integer
emission_data["Jaar"]= [re.sub('(\d{4})\w*', "\\1" , period)
                        for period in emission_data["Jaar"]]
emission_data["Jaar"]= emission_data.Jaar.astype(int)

# Add column with percentage losses values.
emission_data["PercentageStikstofverliezen"]= [round(losses/total * 100,2) if total> 0
                                               else 0
                                               for total, losses in zip(emission_data["TotaalStikstofuitscheiding_5"],
                                                                        emission_data["TotaalStikstofverliezenN_6"])]

region_meta= pd.read_table("data/83983NED_metadata_regio.txt", sep= " ", header= None)

# Create dataset with English terms for region
region_meta.columns= ["RegioS", "NatuurlijkeTerm_NL"]
region_meta["NatuurlijkeTerm_ENG"]= ["Netherlands", "North-Netherlands",
                                     "East-Netherlands", "West-Netherlands",
                                     "South-Netherlands", "Groningen",
                                     "Friesland", "Drenthe",
                                     "Overijssel", "Flevoland",
                                     "Gelderland", "Utrecht",
                                     "Noord-Holland", "Zuid-Holland",
                                     "Zeeland", "Noord-Brabant",
                                     "Limburg", "Concentration region-East",
                                     "Concentration region-South", "Non concentration region"]

# Change region code to english term
emission_data["RegioS"]= [region_meta.query(f'RegioS== "{code}"')["NatuurlijkeTerm_NL"].item()
                          for code in emission_data["RegioS"]]

# Create dataset with English terms for business type
business_meta= pd.read_table("data/83983NED_metadata_bedrijfstypen.txt", sep= ";", header= None)
business_meta.columns= ["Bedrijfstype", "NatuurlijkeTerm_NL"]
business_meta["NatuurlijkeTerm_ENG"]= ["Total all business types",
                                       "Total grazing animal businesses",
                                       "Dairy businesses",
                                       "Meat calve businesses",
                                       "Other cattle businesses",
                                       "Goat- and other grazer businesses",
                                       "Total cage animal businesses",
                                       "Pig businesses",
                                       "Poultry businesses",
                                       "Other cage animal businesses",
                                       "Total other agricultural businesses",
                                       "Total livestock combinations",
                                       "Crop/livestock combinations",
                                       "Agriculture, horticulture and crop combinations"]

# =============================================================================
# Dutch percentage contribution to nitrogen emission data
# =============================================================================
CBS_NHx= pd.read_csv("data/CBS_NHx.csv")

# Strip trailing whitespaces
CBS_NHx.columns= [column.strip()
                  for column in CBS_NHx.columns]

# Replace "," with "." as decimal point and make percentage float
CBS_NHx["Percentage"]= [float(value.replace(",", "."))
                        for value in CBS_NHx["Percentage"]]

# Change source names to English
CBS_NHx["Source"]= ["Agriculture", "Private housholds",
                    "Services, waste and water", "Road traffic",
                    "Industry", "Energy sector",
                    "Other sources", "Shipping",
                    "Railway traffic", "Air traffic"]

CBS_NOx= pd.read_csv("data/CBS_NOx.csv")

# Strip trailing whitespaces
CBS_NOx.columns= [column.strip()
                  for column in CBS_NOx.columns]

# Replace "," with "." as decimal point and make percentage float
CBS_NOx["Percentage"]= [float(value.replace(",", "."))
                        for value in CBS_NOx["Percentage"]]

# Change source names to English
CBS_NOx["Source"]= ["Road traffic", "Other sources",
                    "Shipping", "Industry",
                    "Energy sector", "Agriculture",
                    "Air traffic"]

# Write to csv in app data folder
business_meta.to_csv(f"{os.pardir}/data/83983NED_metadata_bedrijfstypen.csv", index= False)

region_meta.to_csv(f"{os.pardir}/data/83983NED_metadata_regio.csv", index= False)

emission_data.to_csv(f"{os.pardir}/data/emission_data_NL.csv", index= False)

CBS_NHx.to_csv(f"{os.pardir}/data/CBS_NHx.csv", index= False)

CBS_NOx.to_csv(f"{os.pardir}/data/CBS_NOx.csv", index= False)
# =============================================================================
# GeoJSON data
# =============================================================================
with open("data/netherlands.json") as json_file:
    netherlands_geojson= json.load(json_file)

# Change province name in local language to Dutch name
netherlands_geojson["features"][2]["properties"]["name"]= "Friesland"

try:
    with open(f"{os.pardir}/data/netherlands.json", "x") as new_file:
        new_file.write(json.dumps(netherlands_geojson))
except Exception as err:
    print(err)


'''Creati un program ce are ca scop sortarea a x elemente introduse de
utilizator de la tastatura printr-o bucla while. Elementele vor fi inserate pe rand
intr-o lista prin acest while de catre utilizator prin capturare de text. De
asemenea utilizatorul are datoria sa insereze la inceputul programului cate
elemente doreste sa insereze in lista. Trebuie sa afisam lista la final.'''

lista = []
nr = input("Cate elemente doresti sa inserezi in lista? :")
while len(lista) < int(nr):
    lista.append(input())
print("Lista ta este :", lista)


# -*- coding: utf-8 / GBK -*-
'''
重连WiFi
'''
import subprocess
import time
import os
from time import strftime, localtime

ssid = "UCAS"
# 可设置为自己需要连接的WiFi名称

def reconnect():
    '''
    重连
    '''
    print("%s 正在重连WiFi" % strftime("%Y-%m-%d %H:%M:%S", localtime()))
    os.system("netsh wlan disconnect")
    os.system("netsh wlan connect ssid=%s name=%s" % (ssid, ssid))

def check_wifi():
    subp = subprocess.Popen("ping baidu.com", stdout=subprocess.PIPE)
    print("%s " % strftime("%Y-%m-%d %H:%M:%S", localtime()))
    while subp.poll() is None:
        text = str(subp.stdout.readline(), encoding='GBK')
        print(" %s" % text)
        if match(text):
            reconnect()
            break

def match(text):
    '''
    匹配
    '''
    # 如果匹配到"请求超时"或者"找不到"就认为是没网了 可根据自己电脑系统语言更改匹配规则
    if text:
        if text.find('请求超时') >= 0 or text.find('找不到') >= 0:
            return True
        else:
            return False
    else:
        return False

if __name__ == '__main__':
    while True:
        check_wifi()
        time.sleep(20)
        #此处设置检测周期为20s, 可根据个人记场景需要进行配置


import argparse

import torch
from torch import nn, optim
from torch.autograd.variable import Variable

from torchvision import transforms, datasets
from torch.utils.data import DataLoader

from models import Discriminator, Generator

parser = argparse.ArgumentParser()
parser.add_argument('--n_epochs', type=int, default=200, help='number of epochs of training')
parser.add_argument('--batch_size', type=int, default=64, help='size of the batches')
parser.add_argument('--alpha', type=float, default=0.0001, help='adam: learning rate')
parser.add_argument('--b1', type=float, default=0.5, help='adam: beta 1')
parser.add_argument('--b2', type=float, default=0.9, help='adam: beta 2')
parser.add_argument('--n_critic', type=int, default=5, help='number of critic iterations per generator iteration')
parser.add_argument('--lambda_1', type=int, default=10, help='gradient penalty coefficient')
parser.add_argument('--img_size', type=int, default=32, help='size of each image dimension')
parser.add_argument('--channels', type=int, default=3, help='is image rgb (3) or grayscale (1) ?')
parser.add_argument('--display_port', type=int, default=8097, help='where to run the visdom for visualization? useful if running multiple visdom tabs')
parser.add_argument('--display_server', type=str, default="http://localhost", help='visdom server of the web display')
parser.add_argument('--sample_interval', type=int, default=256, help='interval betwen image samples')
opt = parser.parse_args()

try:
    import visdom
    vis = visdom.Visdom(server=opt.display_server, port=opt.display_port, raise_exceptions=True) # Create vis env.
except ImportError:
    vis = None
else:
    vis.close(None) # Clear all figures.

img_dims = (opt.channels, opt.img_size, opt.img_size)
n_features = opt.channels * opt.img_size * opt.img_size

# TODO: Use some initialization in the future.
def init_weights(m):
    if type(m) == nn.ConvTranspose2d:
        torch.nn.init.kaiming_normal(m.weight, mode='fan_out', nonlinearity='relu')
    elif type(m) == nn.Conv2d:
        torch.nn.init.kaiming_uniform_(m.weight, mode='fan_in', nonlinearity='leaky_relu')

def load_cifar10(img_size):
    compose = transforms.Compose(
        [transforms.Resize(img_size),
         transforms.ToTensor(),
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
         ])
    output_dir = './data/cifar10'
    cifar = datasets.CIFAR10(root=output_dir, download=True, train=True,
                             transform=compose)
    return cifar

cifar = load_cifar10(opt.img_size)
batch_iterator = DataLoader(cifar, shuffle=True, batch_size=opt.batch_size) # List, NCHW format.

cuda = torch.cuda.is_available()
Tensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor
gan_loss = nn.BCELoss()

generator = Generator()
discriminator = Discriminator()

optimizer_D = optim.Adam(discriminator.parameters(), lr=opt.alpha, betas=(opt.b1, opt.b2))
optimizer_G = optim.Adam(generator.parameters(), lr=opt.alpha, betas=(opt.b1, opt.b2))

# Loss record.
g_losses = []
d_losses = []
epochs = []
loss_legend = ['Discriminator', 'Generator']

if cuda:
    generator = generator.cuda()
    discriminator = discriminator.cuda()

noise_fixed = Variable(Tensor(25, 128, 1, 1).normal_(0, 1), requires_grad=False) # To track the progress of the GAN.

for epoch in range(opt.n_epochs):
    print('Epoch {}'.format(epoch))
    for i, (batch, _) in enumerate(batch_iterator):
        # == Discriminator update == #
        for iter in range(opt.n_critic):
            # Sample real and fake images, using notation in paper.
            x = Variable(batch.type(Tensor))
            noise = Variable(Tensor(batch.size(0), 128, 1, 1).normal_(0, 1))
            x_tilde = Variable(generator(noise), requires_grad=True)

            epsilon = Variable(Tensor(batch.size(0), 1, 1, 1).uniform_(0, 1))

            x_hat = epsilon*x + (1 - epsilon)*x_tilde
            x_hat = torch.autograd.Variable(x_hat, requires_grad=True)

            # Put the interpolated data through critic.
            dw_x = discriminator(x_hat)
            # A great exercise on learning how the autograd.grad works!
            grad_x = torch.autograd.grad(outputs=dw_x, inputs=x_hat,
                                         grad_outputs=Variable(Tensor(batch.size(0), 1, 1, 1).fill_(1.0), requires_grad=False),
                                         create_graph=True, retain_graph=True, only_inputs=True)
            grad_x = grad_x[0].view(batch.size(0), -1)
            grad_x = grad_x.norm(p=2, dim=1) # My naming is inaccurate, this is the 2-norm of grad(D_w(x_hat))

            # Update discriminator (or critic, since we don't output probabilities anymore).
            optimizer_D.zero_grad()

            # WGAN-GP loss, defined properly as a loss unlike the WGAN paper.
            d_loss = torch.mean(discriminator(x_tilde)) - torch.mean(discriminator(x)) + opt.lambda_1*torch.mean((grad_x - 1)**2)
            # d_loss = torch.mean(d_loss) # there's a reason for why this shouldn't be done this way :)

            d_loss.backward()
            optimizer_D.step()

        # == Generator update == #
        noise = Variable(Tensor(batch.size(0), 128, 1, 1).normal_(0, 1))
        imgs_fake = generator(noise)

        optimizer_G.zero_grad()

        g_loss = -torch.mean(discriminator(imgs_fake))

        g_loss.backward()
        optimizer_G.step()

        if vis:
            batches_done = epoch * len(batch_iterator) + i
            if batches_done % opt.sample_interval == 0:

                # Keep a record of losses for plotting.
                epochs.append(epoch + i/len(batch_iterator))
                g_losses.append(g_loss.item())
                d_losses.append(d_loss.item())

                # Generate images for a given set of fixed noise
                # so we can track how the GAN learns.
                imgs_fake_fixed = generator(noise_fixed).detach().data
                imgs_fake_fixed = imgs_fake_fixed.add_(1).div_(2)

                # Display results on visdom page.
                vis.line(
                    X=torch.stack([Tensor(epochs)] * len(loss_legend), dim=1),
                    Y=torch.stack((Tensor(d_losses), Tensor(g_losses)), dim=1),
                    opts={
                        'title': 'loss over time',
                        'legend': loss_legend,
                        'xlabel': 'epoch',
                        'ylabel': 'loss',
                        'width': 512,
                        'height': 512
                },
                    win=1)
                vis.images(
                    imgs_fake_fixed[:25],
                    nrow=5, win=2,
                    opts={
                        'title': 'GAN output [Epoch {}]'.format(epoch),
                        'width': 512,
                        'height': 512,
                    }
                )


import copy

# Main
if __name__ == "__main__":
    input_file = open("Day-5-Input.txt", "r")
    stack_list = []
    for i in range(9):
        stack_list.append([])
    line = input_file.readline()
    while line != "":
        if line.find("[") == -1:
            break
        for i in range(9):
            char = line[4 * i + 1]
            if char != " ":
                stack_list[i].append(char)
        line = input_file.readline()
    for i in range(9):
        stack_list[i].reverse()
    copy_list = copy.deepcopy(stack_list)
    line = input_file.readline()
    line = input_file.readline()
    while line != "":
        move = int(line[5:line.index(" from")])
        from_stack = int(line[line.index(" to")-1:line.index(" to")])-1
        to_stack = int(line[-2:])-1
        line = input_file.readline()
        for i in range(move):
            stack_list[to_stack].append(stack_list[from_stack].pop())

        pop_index = len(copy_list[from_stack]) - move
        # print("index: " + str(pop_index) + " length: " + str(len(copy_list[from_stack])))

        for i in range(move):
            copy_list[to_stack].append(copy_list[from_stack].pop(pop_index))
    stack_tops = ""
    copy_tops = ""
    for i in range(9):
        stack_tops += str(stack_list[i][-1])
        copy_tops += str(copy_list[i][-1])
    print("Part 1: " + str(stack_tops))
    print("Part 2: " + str(copy_tops))


import json
from pathlib import Path

recordList=[]
taskList = []

class Record(object):
    def __init__(self, date, task, duration):
        self.date = date
        self.task = task
        self.duration = duration

def jsonDefault(object):
    return object.__dict__

def getRecords(num):
    readRecords()
    printRec(num)

def readRecords():
    global recordList
    global taskList
    recordList=[]
    taskList=[]

    file = open("records.txt", "r")
    for line in file:
        try:
            a = json.loads(line)
            recordList.append(a)
        except ValueError:
            print("Fix records file")
    file.close()
    taskHeaders(recordList, taskList)

def taskHeaders(recList, taList):

     for p in recList:
        if(p["task"] not in taList):
            taList.append(p["task"])

def getTasks():
    for p in taskList: print (p)

def printRec(num):
    global recordList
    length=len(recordList)

    try:
        num= int(num)
        if(num >=length or num==0):
            for p in recordList: print (p["date"] +  "     "+ p["task"] +"     "+ p["duration"])
        else:
            for i in range(length-num, length):
                p=recordList[i]
                print (p["date"] +  "     "+ p["task"] +"     "+ p["duration"])
    except ValueError:
        printRec(0)

def sumTask(arg):
    sum=0
    global recordList
    readRecords()

    for a in recordList:
        if arg==a["task"]:
            sum += float(a["duration"])

    if sum==0:
        return False
    else:
        return sum

def writeToRecords(val):
    record=Record(val.date, val.taskname, val.duration)

    file = Path("records.txt")
    if file.exists():
        file = open("records.txt", "a")
        file.write(json.dumps(record, default=jsonDefault) + "\n")
        file.close()
    else:
        file = open("records.txt", "w")
        file.write(json.dumps(record, default=jsonDefault) + "\n")
        file.close()

def recordsTaskname(name):
    global taskList
    global recordList
    for p in recordList:
        if(name==p["task"]):
            print (p["date"] +  "     "+ p["task"] +"     "+ p["duration"])

def recordsDateSort(dateStart, dateEnd):
    global recordList

    for p in recordList:
        date=p["date"].split(" ")
        if(dateStart==date[0]):
            if(dateEnd != date[0]):
                print (p["date"] +  "     "+ p["task"] +"     "+ p["duration"])
            else:
                break


import sys

InputCases = int( sys.stdin.readline() )

for K in range( InputCases ):
    InputLine = sys.stdin.readline()
    InputDice = [ int( S ) for S in InputLine.split() ]
    InputDice.sort()
    Valid = True
    Size = len( InputDice ) - 1
    for D in range( Size ):
        Difference = InputDice[ D + 1 ] - InputDice[ D ]
        if Difference != 1:
            Valid = False
            break
    if Valid == True:
        print( 'Y' )
    else:
        print( 'N' )


from tkinter import *

ventana = Tk()
ventana.geometry("600x500")
ventana.title("Aplicacion")

Boton1 = Button(ventana, text="Inicio", bg="blue", fg="white")
Boton1.grid(row=8, column=1)
Boton2 = Button(ventana, text="Archivos")
Boton2.grid(row=8, column=4)
ventana.mainloop()


from flask import Flask, jsonify, request, json
from flask_restful import Resource, Api
from getKeyword import *
from getMatches import *
from luceneSearch import *
from luceneFunctionalities import *

app = Flask(__name__)

@app.route("/", methods=['GET'])
def func1():
    return jsonify ({"Hello": "World!"})

@app.route("/post", methods=['POST'])
def processRequest():
    requestFromServer = request.get_json()
    keyWord = findKeyword(requestFromServer['request'])
    finalKeyWord = removeArticle(keyWord).strip()
    ##Keyword found
    #Search corpus for keyword
    results = searchLucene(finalKeyWord)
    json_string = json.dumps([ob.__dict__ for ob in results])
    return json_string

if __name__ == '__main__':
    app.run(port=8080)


import smbus2
import paho.mqtt.client as mqtt
import numpy as np
import time
bus = smbus2.SMBus(1)
address = 0x08
message = ""

def on_connect(client, userdata, flags, rc):
	print("Connection returned result:"+str(rc))
	client.subscribe("BrewinBrewer/000000000/Touchscreen", qos = 1)
def on_disconnect(client, userdata, rc):
	if rc!=0:
		print("Unexpected Disconnect")
	else:
		print("Expected Disconnect")
def on_message(client, userdata, message):
	print("Received message: " + str(message.payload.decode()) + " on topic " + message.topic + " with QoS " + str(message.qos))
	message = str(message.payload.decode())
	split = message.split()
	for i in range(3):
		bus.write_byte(address, int(split[i]))
		print("Master has sent", int(split[i]))
		read = bus.read_byte(address)
		print("Slave has received", read)
	time.sleep(3)
	client.publish("BrewinBrewer/000000000/DispenseSystem", "done", qos=1)
	print("Notified System")

client = mqtt.Client()
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message

client.connect_async('test.mosquitto.org')
client.loop_start()
while True:
	pass


from typing import Any, Dict, List, Union
from loguru import logger
import json

from backend.app import app
from backend.utils.running_time_storage import get_running_time_storage
from backend.utils.user_conversation_storage import get_user_conversation_storage
from real_agents.adapters.memory import BaseChatMemory

HUMAN_MESSAGE_KEY = "human_message"
AI_MESSAGE_KEY = "ai_message"

LOCAL = "local"
DATABASE = "database"

class UserMemoryManager:
    """A class to manage the global memory including messages, grounding_sources,
    etc. on user level"""

    # api_key_pool:
    # {
    #   "user_id": [{
    #       "tool_id": the id of the tool,
    #       "tool_name": the name of the tool,
    #       "api_key": the api_key of the tool,
    # }]
    # }

    def __init__(self, name: str = None, backend: str = LOCAL, memory_pool: Dict = None):
        self.backend = backend
        self.name = name
        if self.backend == LOCAL:
            if memory_pool is None:
                memory_pool = {}
            self.memory_pool = memory_pool
        elif self.backend == DATABASE:
            with app.app_context():
                self.redis_client = get_running_time_storage()
                self.db_client = get_user_conversation_storage()
        else:
            raise ValueError("Unknown backend option: {}".format(self.backend))

    def get_pool_info_with_id(
        self,
        user_id: str,
        default_value: Union[List, Dict],
    ) -> Any:
        """Gets the information with user_id and chat_id from the pool."""
        if self.backend == LOCAL:
            pool = self.memory_pool
            if user_id in pool:
                return pool[user_id]
            else:
                return default_value
        elif self.backend == DATABASE:
            memory_pool_name = f"{self.name}:{user_id}"
            if self.redis_client.exists(memory_pool_name):
                # In cache
                info = json.loads(self.redis_client.get(memory_pool_name))
            else:
                # Cache miss
                try:
                    # api_keys are not stored in database
                    if self.name == "api_key_pool":
                        info = default_value
                    else:
                        raise NotImplementedError(f"Currently only support message pool in database, not {self.name}")
                except Exception as e:
                    # Not in database
                    logger.bind(user_id=user_id, msg_head="Cache miss but not in database").warning(
                        "Failed to get pool info from database: {}".format(e)
                    )
                    info = default_value
            return info

    def set_pool_info_with_id(self, user_id: str, info: Any) -> None:
        """Sets the information with user_id and chat_id to the pool."""
        if self.backend == LOCAL:
            pool = self.memory_pool
            if user_id not in pool:
                pool[user_id] = info
        elif self.backend == DATABASE:
            # As db has its own updating logic, we only need to update the cache here (write-through).
            memory_pool_name = f"{self.name}:{user_id}"
            self.redis_client.set(memory_pool_name, json.dumps(info))

    def __iter__(self):
        """Iterates over the memory pool."""
        if self.backend == LOCAL:
            for user_id, info in self.memory_pool.items():
                yield user_id, info
        elif self.backend == DATABASE:
            raise NotImplementedError("Currently not support UserMemoryManager iteration in database mode.")

class ChatMemoryManager:
    """A class to manage the global memory including messages, grounding_sources, etc. on chat level"""

    # memory_pool:
    # {user_id: {chat_id: [
    #                           {"message_id": the id of this pair of messages,
    #                            "parent_message_id": the id of the parent message,
    #                            "message_type": type of the message, possible values: human_message / ai_message
    #                            "message_content": content of the message
    #                           }
    #                     ]
    #           }
    # }
    # grounding_source_pool:
    # {user_id: {chat_id: {"filenames": List of filenames,
    #                      "activated_filenames": List of user-selected activated names}}

    def __init__(self, name: str = None, backend: str = LOCAL, memory_pool: Dict = None):
        """
        This ChatMemoryManager can not be applied to grounding_source_pool in database mode.
        """
        self.backend = backend
        self.name = name
        if self.backend == LOCAL:
            if memory_pool is None:
                memory_pool = {}
            self.memory_pool = memory_pool
        elif self.backend == DATABASE:
            with app.app_context():
                self.redis_client = get_running_time_storage()
                self.db_client = get_user_conversation_storage()
        else:
            raise ValueError("Unknown backend option: {}".format(self.backend))

    def get_pool_info_with_id(
        self,
        user_id: str,
        chat_id: str,
        default_value: Union[List, Dict],
    ) -> Any:
        """Gets the information with user_id and chat_id from the pool."""
        if self.backend == LOCAL:
            pool = self.memory_pool
            if user_id in pool and chat_id in pool[user_id]:
                return pool[user_id][chat_id]
            else:
                return default_value
        elif self.backend == DATABASE:
            memory_pool_name = f"{self.name}:{user_id}:{chat_id}"
            if self.redis_client.exists(memory_pool_name):
                # In cache
                info = json.loads(self.redis_client.get(memory_pool_name))
            else:
                # Cache miss
                try:
                    # Found in database
                    if self.name == "message_pool":
                        info = []
                        response = self.db_client.message.find({"conversation_id": chat_id})
                        if response is None:
                            # Not in database (new chat)
                            info = default_value
                        else:
                            # In database
                            for message in response:
                                if message["role"] == "user":
                                    message_type = HUMAN_MESSAGE_KEY
                                elif message["role"] == "assistant":
                                    message_type = AI_MESSAGE_KEY
                                else:
                                    raise ValueError("Unknown role: {}".format(message["role"]))
                                info.append(
                                    {
                                        "message_id": message["message_id"],
                                        "parent_message_id": message["parent_message_id"],
                                        "message_type": message_type,
                                        "message_content": message["data_for_llm"],
                                    }
                                )
                            self.redis_client.set(memory_pool_name, json.dumps(info))
                    elif self.name == "jupyter_kernel_pool":
                        info = default_value
                    else:
                        raise NotImplementedError(f"Currently only support message pool in database, not {self.name}")
                except Exception as e:
                    # Not in database
                    logger.bind(user_id=user_id, chat_id=chat_id, msg_head="Cache miss but not in database").warning(
                        "Failed to get pool info from database: {}".format(e)
                    )
                    info = default_value
            return info

    def set_pool_info_with_id(self, user_id: str, chat_id: str, info: Any) -> None:
        """Sets the information with user_id and chat_id to the pool."""
        if self.backend == LOCAL:
            pool = self.memory_pool
            if user_id not in pool:
                pool[user_id] = {}
            pool[user_id][chat_id] = info
        elif self.backend == DATABASE:
            # As db has its own updating logic, we only need to update the cache here (write-through).
            memory_pool_name = f"{self.name}:{user_id}:{chat_id}"
            self.redis_client.set(memory_pool_name, json.dumps(info))

    def __iter__(self):
        """Iterates over the memory pool."""
        if self.backend == LOCAL:
            for user_id, chat_id_info in self.memory_pool.items():
                for chat_id, info in chat_id_info.items():
                    yield user_id, chat_id, info
        elif self.backend == DATABASE:
            if self.name == "jupyter_kernel_pool":
                iterator = self.redis_client.scan_iter("jupyter_kernel_pool:*")
                for key in iterator:
                    user_id, chat_id = key.split(":")[1:]
                    yield user_id, chat_id, self.get_pool_info_with_id(user_id, chat_id, {})
            else:
                raise NotImplementedError("Currently only support jupyter kernel pool iteration in database mode.")

    def drop_item_with_id(self, user_id: str, chat_id: str):
        if self.backend == LOCAL:
            # drop item under one user
            if user_id in self.memory_pool:
                self.memory_pool[user_id].pop([chat_id], None)
        elif self.backend == DATABASE:
            if self.name == "jupyter_kernel_pool":
                self.redis_client.delete(f"{self.name}:{user_id}:{chat_id}")
            else:
                raise NotImplementedError("Currently only support jupyter kernel pool delete in database mode.")

class MessageMemoryManager(ChatMemoryManager):
    """A class to manage the memory of messages."""

    @staticmethod
    def load_agent_memory_from_list(agent_memory: BaseChatMemory, message_list: List[Dict[str, str]]) -> None:
        """Load agent's memory from a list."""
        agent_memory.clear()
        for message in message_list:
            if message.get("message_type", None) == HUMAN_MESSAGE_KEY:
                agent_memory.chat_memory.add_user_message(message["message_content"])
            elif message.get("message_type", None) == AI_MESSAGE_KEY:
                agent_memory.chat_memory.add_ai_message(message["message_content"])
        try:
            agent_memory.fit_max_token_limit()
        except Exception as e:
            import traceback

            traceback.print_exc()
            pass

    @staticmethod
    def save_agent_memory_to_list(agent_memory: BaseChatMemory) -> List[Dict[str, str]]:
        """Saves agent's memory to a list"""
        messages = agent_memory.chat_memory.messages
        message_list = []
        for message in messages:
            if message.type == "human":
                message_list.append(
                    {
                        "message_type": "human_message",
                        "message_content": message.content,
                    }
                )
            elif message.type == "ai":
                message_list.append(
                    {
                        "message_type": "ai_message",
                        "message_content": message.content,
                    }
                )
        return message_list

    def get_activated_message_list(
        self,
        user_id: str,
        chat_id: str,
        default_value: Union[List, Dict],
        parent_message_id: Union[int, str],
    ) -> List:
        """Gets the activated message list from leaf to root."""
        # ONLY work for messages
        message_list = self.get_pool_info_with_id(user_id, chat_id, default_value)
        activated_message_list = []
        end_point = parent_message_id
        while len(message_list) > 0 and end_point != -1:
            flag = False
            for msg in message_list:
                if msg["message_id"] == end_point:
                    if end_point == msg["parent_message_id"]:
                        flag = False
                        break
                    activated_message_list = [msg] + activated_message_list
                    end_point = msg["parent_message_id"]
                    flag = True
                    break
            if not flag:
                break
        logger.bind(msg_head=f"get_activated_message_list").debug(activated_message_list)
        return activated_message_list


import os
from hedra.core.graphs.stages import (
    Submit
)

from hedra.reporting.types import (
    S3Config
)

class SubmitS3ResultsStage(Submit):
    config=S3Config(
        aws_access_key_id=os.getenv('AWS_ACCESS_KEY_ID', ''),
        aws_secret_access_key=os.getenv('AWS_SECRET_ACCESS_KEY', ''),
        region_name=os.getenv('AWS_REGION_NAME', ''),
        buckets_namespace='results',
        events_bucket='events',
        metrics_bucket='metrics'
    )


from CircuitCalculator.Network.network import Network, Branch
from CircuitCalculator.Network.elements import resistor, voltage_source
from CircuitCalculator.Network.NodalAnalysis import open_circuit_voltage
from numpy.testing import assert_almost_equal

def test_open_circuit_voltage_of_equal_nodes_is_zero() -> None:
    V = 1
    R1, R2, R3 = 10, 20, 30
    network = Network([
        Branch('1', '0', voltage_source('V', V)),
        Branch('1', '2', resistor('R1', R1)),
        Branch('1', '2', resistor('R2', R2)),
        Branch('2', '0', resistor('R3', R3)),
        ])
    V0 = open_circuit_voltage(network, '1', '1')

    assert_almost_equal(V0, 0)

def test_open_circuit_voltage() -> None:
    V = 1
    R1, R2, R3 = 10, 20, 30
    network = Network([
        Branch('1', '0', voltage_source('V', V)),
        Branch('1', '2', resistor('R1', R1)),
        Branch('1', '2', resistor('R2', R2)),
        Branch('2', '0', resistor('R3', R3)),
        ])
    V0 = open_circuit_voltage(network, '2', '0')

    assert_almost_equal(V0, V*R3/(R3+R1*R2/(R1+R2)))


import os
from functools import partial

import numpy as np
import torch
from torch.nn.utils import clip_grad_norm_

import models.metrics as metrics_module
from data.dataset_loading import PADDED_Y_VALUE
from models.model_utils import get_num_params, log_num_params
from training.early_stop import EarlyStop
from utils.ltr_logging import get_logger
from utils.tensorboard_utils import TensorboardSummaryWriter

logger = get_logger()

def loss_batch(model, loss_func, xb, yb, indices, gradient_clipping_norm, pass_indices_n_qid, qid=None, num_pos=None, num_item=None, ideal_dcg=None, opt=None):
    mask = (yb == PADDED_Y_VALUE)

    if pass_indices_n_qid:
        loss = loss_func(model(xb, mask, indices), yb, qid, indices, num_pos, num_item, ideal_dcg)
    else:
        loss = loss_func(model(xb, mask, indices), yb)

    if opt is not None:
        loss.backward()
        if gradient_clipping_norm:
            clip_grad_norm_(model.parameters(), gradient_clipping_norm)
        opt.step()
        opt.zero_grad()

    return loss.item(), len(xb)

def metric_on_batch(metric, model, xb, yb, indices):
    mask = (yb == PADDED_Y_VALUE)
    return metric(model.score(xb, mask, indices), yb)

def metric_on_epoch(metric, model, dl, dev):
    metric_values = torch.mean(
        torch.cat(
            [metric_on_batch(metric, model, xb.to(device=dev), yb.to(device=dev), indices.to(device=dev))
             for xb, yb, indices, _, _, _, _ in dl]
        ), dim=0
    ).cpu().numpy()
    return metric_values

def compute_metrics(metrics, model, dl, dev):
    metric_values_dict = {}
    for metric_name, ats in metrics.items():
        metric_func = getattr(metrics_module, metric_name)
        metric_func_with_ats = partial(metric_func, ats=ats)
        metrics_values = metric_on_epoch(metric_func_with_ats, model, dl, dev)
        metrics_names = ["{metric_name}_{at}".format(metric_name=metric_name, at=at) for at in ats]
        metric_values_dict.update(dict(zip(metrics_names, metrics_values)))

    return metric_values_dict

def epoch_summary(epoch, train_loss, train_metrics, val_metrics):
    summary = "Epoch : {:0>3d} Train loss: {:.6f} \n".format(epoch, train_loss)
    for metric_name, metric_value in train_metrics.items():
        summary += " Train {} {:.6f}".format(metric_name, metric_value)
    summary += "\n"
    for metric_name, metric_value in val_metrics.items():
        summary += " Val {} {:.6f}".format(metric_name, metric_value)

    return summary

def val_metrics_summary(val_metrics):
    summary = "Evaluate on val set \n"
    for metric_name, metric_value in val_metrics.items():
        summary += " Val {} {:.6f}".format(metric_name, metric_value)

    return summary

def get_current_lr(optimizer):
    for param_group in optimizer.param_groups:
        return param_group["lr"]

def fit(epochs, model, loss_func, optimizer, scheduler, train_dl, valid_dl, config, gradient_clipping_norm,
        early_stopping_patience, device, output_dir, tensorboard_output_path, pass_indices_n_qid, pretrained_model_path):
    tensorboard_summary_writer = TensorboardSummaryWriter(tensorboard_output_path)

    num_params = get_num_params(model)
    log_num_params(num_params)

    early_stop = EarlyStop(early_stopping_patience)

    if len(pretrained_model_path) > 0:
        logger.info("load pretrained model model.pkl from {}".format(pretrained_model_path))
        model.load_state_dict(torch.load(pretrained_model_path))
        model.eval()
        with torch.no_grad():
            val_metrics = compute_metrics(config.metrics, model, valid_dl, device)
        logger.info(val_metrics_summary(val_metrics))
        logger.info("Reset the parameters in the last layer.")
        model.reset_last_layer()

    for epoch in range(epochs):
        logger.info("Current learning rate: {}".format(get_current_lr(optimizer)))

        model.train()
        # xb dim: [batch_size, slate_length, embedding_dim]
        # yb dim: [batch_size, slate_length]

        train_losses, train_nums = zip(
            *[loss_batch(model, loss_func, xb.to(device=device), yb.to(device=device), indices.to(device=device),
                         gradient_clipping_norm, pass_indices_n_qid, qid.to(device=device), num_pos.to(device=device), num_item.to(device=device), ideal_dcg.to(device=device), optimizer) for
              xb, yb, indices, qid, num_pos, num_item, ideal_dcg in train_dl])
        train_loss = np.sum(np.multiply(train_losses, train_nums)) / np.sum(train_nums)
        train_metrics = compute_metrics(config.metrics, model, train_dl, device)

        model.eval()
        with torch.no_grad():
            val_metrics = compute_metrics(config.metrics, model, valid_dl, device)

        tensorboard_metrics_dict = {("train", "loss"): train_loss}

        train_metrics_to_tb = {("train", name): value for name, value in train_metrics.items()}
        tensorboard_metrics_dict.update(train_metrics_to_tb)
        val_metrics_to_tb = {("val", name): value for name, value in val_metrics.items()}
        tensorboard_metrics_dict.update(val_metrics_to_tb)
        tensorboard_metrics_dict.update({("train", "lr"): get_current_lr(optimizer)})

        tensorboard_summary_writer.save_to_tensorboard(tensorboard_metrics_dict, epoch)

        logger.info(epoch_summary(epoch, train_loss, train_metrics, val_metrics))

        current_val_metric_value = val_metrics.get(config.val_metric)
        if scheduler:
            if type(scheduler) == torch.optim.lr_scheduler.ReduceLROnPlateau:
                args = [val_metrics[config.val_metric]]
                scheduler.step(*args)
            else:
                scheduler.step()

        early_stop.step(current_val_metric_value, epoch)
        if early_stop.stop_training(epoch):
            logger.info(
                "early stopping at epoch {} since {} didn't improve from epoch no {}. Best value {}, current value {}".format(
                    epoch, config.val_metric, early_stop.best_epoch, early_stop.best_value, current_val_metric_value
                ))
            break

    torch.save(model.state_dict(), os.path.join(output_dir, "model.pkl"))
    tensorboard_summary_writer.close_all_writers()

    return {
        "epochs": epoch,
        "train_metrics": train_metrics,
        "val_metrics": val_metrics,
        "num_params": num_params
    }


from z3 import *

with open("input/24.txt") as handle:
    instructions = [line.rstrip().split(" ") for line in handle.readlines()]

optimize = Optimize()

inputs = []
for i in range(14):
    digit = BitVec(f"digit{i}", 64)
    inputs.append(digit)
    optimize.add(digit > 0, digit < 10)

next_input = len(inputs) - 1
zero, one = BitVecVal(0, 64), BitVecVal(1, 64)
registers = {
    "x": zero,
    "y": zero,
    "z": zero,
    "w": zero,
}

for i, op in enumerate(instructions):
    if op[0] == "inp":
        registers[op[1]] = inputs[next_input]
        next_input -= 1
    else:
        a = registers[op[1]]
        registers[op[1]] = BitVec(f"step{i}", 64)
        b = registers[op[2]] if op[2] in "xyzw" else int(op[2])

        if op[0] == "add":
            optimize.add(registers[op[1]] == a + b)
        elif op[0] == "mul":
            optimize.add(registers[op[1]] == a * b)
        elif op[0] == "div":
            optimize.add(registers[op[1]] == a / b)
        elif op[0] == "mod":
            optimize.add(registers[op[1]] == a % b)
        elif op[0] == "eql":
            optimize.add(registers[op[1]] == If(a == b, one, zero))

optimize.add(registers["z"] == 0)
digit_sum = sum(d * (10 ** i) for i, d in enumerate(inputs))

optimize.push()

result = optimize.maximize(digit_sum)
optimize.check()
print(result.value())

optimize.pop()

result = optimize.minimize(digit_sum)
optimize.check()
print(result.value())


from __future__ import print_function
import os
import sys
import csv
import time
sys.path.append('../')
import argparse
import numpy as np
import torch
import torch.nn.functional as F
import torch.optim as optim
from data_loader import define_dataloader,load_embedding
from utils import str2bool,check_model_name,timeSince,get_performance_batchiter,print_performance,write_blackbox_output_batchiter
import data_io_tf
from pathlib import Path

PRINT_EVERY_EPOCH = 1

def train(args, model, device, train_loader, optimizer, epoch):

    model.train()

    for batch in train_loader:

        X_pep, X_tcr, y = batch.X_pep.to(device), batch.X_tcr.to(device), batch.y.to(device)
        optimizer.zero_grad()
        yhat = model(X_pep, X_tcr)
        loss = F.cross_entropy(yhat, y)
        loss.backward()
        optimizer.step()

    if epoch % PRINT_EVERY_EPOCH == 1:
        print('[TRAIN] Epoch {} Loss {:.4f}'.format(epoch, loss.item()))

def main():

    parser = argparse.ArgumentParser(description='Prediction of TCR binding to peptide-MHC complexes')

    parser.add_argument('--infile', type=str,
                        help='input file for training')
    parser.add_argument('--indepfile', type=str, default=None,
                        help='independent test file')
    parser.add_argument('--blosum', type=str, default='data/BLOSUM50',
                        help='file with BLOSUM matrix')
    parser.add_argument('--batch_size', type=int, default=50, metavar='N',
                        help='batch size')
    parser.add_argument('--model_name', type=str, default='original.ckpt',
                        help = 'if train is True, model name to be saved, otherwise model name to be loaded')
    parser.add_argument('--epoch', type = int, default=200, metavar='N',
                        help='number of epoch to train')
    parser.add_argument('--lr', type=float, default=0.001, metavar='LR',
                        help='learning rate')
    parser.add_argument('--cuda', type = str2bool, default=True,
                        help = 'enable cuda')
    parser.add_argument('--seed', type=int, default=7405,
                        help='random seed')
    parser.add_argument('--mode', default = 'train', type=str,
                        help = 'train or test')
    parser.add_argument('--model', type=str, default='cnn',
                        help='cnn, resnet')

    args = parser.parse_args()

    if args.mode is 'test':
        assert args.indepfile is not None, '--indepfile is missing!'

    ## cuda
    if torch.cuda.is_available() and not args.cuda:
        print("WARNING: You have a CUDA device, so you should probably run with --cuda")
    args.cuda = (args.cuda and torch.cuda.is_available())
    device = torch.device('cuda' if args.cuda else 'cpu')

    ## set random seed
    seed = args.seed
    torch.manual_seed(seed)
    if args.cuda:
        torch.cuda.manual_seed(seed) if args.cuda else None

    # embedding matrix
    embedding = load_embedding(args.blosum)

    ## read data
    X_pep, X_tcr, y = data_io_tf.read_pTCR(args.infile)
    y = np.array(y)

    n_total = len(y)
    n_train = int(round(n_total * 0.8))
    n_valid = int(round(n_total * 0.1))
    n_test = n_total - n_train - n_valid
    idx_shuffled = np.arange(n_total); np.random.shuffle(idx_shuffled)
    idx_train, idx_valid, idx_test = idx_shuffled[:n_train], \
                                     idx_shuffled[n_train:(n_train+n_valid)], \
                                     idx_shuffled[(n_train+n_valid):]

    ## define dataloader
    train_loader = define_dataloader(X_pep[idx_train], X_tcr[idx_train], y[idx_train], None,
                                     None, None,
                                     batch_size=args.batch_size, device=device)
    valid_loader = define_dataloader(X_pep[idx_valid], X_tcr[idx_valid], y[idx_valid], None,
                                     maxlen_pep=train_loader['pep_length'],
                                     maxlen_tcr=train_loader['tcr_length'],
                                     batch_size=args.batch_size, device=device)
    test_loader = define_dataloader(X_pep[idx_test], X_tcr[idx_test], y[idx_test], None,
                                    maxlen_pep=train_loader['pep_length'],
                                    maxlen_tcr=train_loader['tcr_length'],
                                    batch_size=args.batch_size, device=device)

    ## read indep data
    if args.indepfile is not None:
        X_indep_pep, X_indep_tcr, y_indep = data_io_tf.read_pTCR(args.indepfile)
        y_indep = np.array(y_indep)
        indep_loader = define_dataloader(X_indep_pep, X_indep_tcr, y_indep, None,
                                         maxlen_pep=train_loader['pep_length'],
                                         maxlen_tcr=train_loader['tcr_length'],
                                         batch_size=args.batch_size, device=device)

    if args.model == 'cnn':

        from cnn import Net

    #if args.model == 'resnet':
    #
    #    from resnet import Net
    #    Net = models.resnet18

    else:
        raise ValueError('unknown model name')

    ## define model
    model = Net(embedding, train_loader['pep_length'], train_loader['tcr_length']).to(device)
    optimizer = optim.Adam(model.parameters(), lr=args.lr)

    if 'models' not in os.listdir('.'):
        os.mkdir('models')
    if 'result' not in os.listdir('.'):
        os.mkdir('result')

    ## fit model
    if args.mode == 'train' :

        model_name = check_model_name(args.model_name)
        model_name = check_model_name(model_name, './models')
        model_name = args.model_name

        wf_open = open('result/'+os.path.splitext(os.path.basename(args.infile))[0]+'_'+os.path.splitext(os.path.basename(args.model_name))[0]+'_valid.csv', 'w')
        wf_colnames = ['loss', 'accuracy',
                       'precision1', 'precision0',
                       'recall1', 'recall0',
                       'f1macro','f1micro', 'auc']
        wf = csv.DictWriter(wf_open, wf_colnames, delimiter='\t')

        t0 = time.time()
        for epoch in range(1, args.epoch + 1):

            train(args, model, device, train_loader['loader'], optimizer, epoch)

            ## evaluate performance
            perf_train = get_performance_batchiter(train_loader['loader'], model, device)
            perf_valid = get_performance_batchiter(valid_loader['loader'], model, device)

            ## print performance
            print('Epoch {} TimeSince {}\n'.format(epoch, timeSince(t0)))
            print('[TRAIN] {} ----------------'.format(epoch))
            print_performance(perf_train)
            print('[VALID] {} ----------------'.format(epoch))
            print_performance(perf_valid, writeif=True, wf=wf)

        ## evaluate and print test-set performance
        print('[TEST ] {} ----------------'.format(epoch))
        perf_test = get_performance_batchiter(test_loader['loader'], model, device)
        print_performance(perf_test)

        model_name = './models/' + model_name
        torch.save(model.state_dict(), model_name)

    elif args.mode == 'test' :

        model_name = args.model_name

        assert model_name in os.listdir('./models')

        model_name = './models/' + model_name
        model.load_state_dict(torch.load(model_name))

        ## evaluate and print independent-test-set performance
        print('[INDEP] {} ----------------')
        perf_indep = get_performance_batchiter(indep_loader['loader'], model, device)
        print_performance(perf_indep)

        ## write blackbox output
        wf_bb_open = open('data/testblackboxpred_' + os.path.basename(args.indepfile), 'w')
        wf_bb = csv.writer(wf_bb_open, delimiter='\t')
        write_blackbox_output_batchiter(indep_loader, model, wf_bb, device)

        wf_bb_open1 = open('data/testblackboxpredscore_' + os.path.basename(args.indepfile), 'w')
        wf_bb1 = csv.writer(wf_bb_open1, delimiter='\t')
        write_blackbox_output_batchiter(indep_loader, model, wf_bb1, device, ifscore=True)

    else :

        print('\nError: "--mode train" or "--mode test" expected')

if __name__ == '__main__':
    main()


#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor as DTR #此处为回归决策树
from sklearn.metrics import confusion_matrix
from sklearn.metrics import mean_absolute_error,mean_squared_error,\
    median_absolute_error,explained_variance_score,r2_score

import data_read
import torch
def data_process():
    data = data_read.data_read()
    loads_df = pd.DataFrame(data, columns=['id', 'date', 'energy_use'])
    # 查询数据中的空缺值
    loads_df = loads_df.replace('', np.nan)
    loads_df.isnull().sum()
    # 删除空缺值
    loads_df = loads_df.dropna()
    loads_df.shape
    loads_df.time = loads_df.date.apply(lambda x: x.split()[1])
    time = loads_df.time.drop_duplicates().sort_values()
    loads_df.loc[:, 'energy_use'] = loads_df.energy_use.astype(float)
    loads_df.loc[:, 'id'] = loads_df['id'].astype(int)
    loads_df.loc[:, 'date'] = pd.to_datetime(loads_df.date)
    loads_df = loads_df.sort_values(['id', 'date'], ascending=[True, True])
    loads_df = loads_df.reset_index(drop=True)
    return loads_df

def tree_train(X, Y):
    x_tr, x_te, y_tr, y_te = train_test_split(X, Y, test_size=0.33, random_state=42)
    # 构建决策树模型 回归树
    dtc = DTR()
    # 训练模型 ,需要将type转换为int，否则报错
    dtc.fit(x_tr, y_tr.astype('int'))
    dtc.fit(x_tr, y_tr)
    # 预测数据
    # dtc = dtc = torch.load('decision_tree.pkl')
    pre = dtc.predict(X)
    return pre

def evaluate(y_te,pre):
    r2 = r2_score(y_te, pre)
    y_var_te = y_te[1:] - y_te[:len(y_te) - 1]
    y_var_pre = pre[1:] - pre[:len(pre) - 1]
    txt = np.zeros(len(y_var_te))
    for i in range(len(y_var_te - 1)):
        txt[i] = np.sign(y_var_te[i]) == np.sign(y_var_pre[i])
    result = sum(txt) / len(txt)

    return float(r2), int(result * 100)


import pathlib
import os
import sys
from confluent_kafka import Producer

FILE_PATH = pathlib.Path(__file__).absolute()
ROOT_PATH = FILE_PATH.parent.parent
sys.path.insert(0, ROOT_PATH.as_posix())
DATA_DIR =os.path.join(ROOT_PATH, "src/main/resources/data/nested.json")

p = Producer({'bootstrap.servers': 'localhost:9092'})

def delivery_report(err, msg):
    """ Called once for each message produced to indicate delivery result.
        Triggered by poll() or flush(). """
    if err is not None:
        print('Message delivery failed: {}'.format(err))
    else:
        print('Message delivered to {} [{}]'.format(msg.topic(), msg.partition()))

with open(DATA_DIR) as f:
    data = f.read()
    p.poll(0)
    p.produce('topic1', data.encode('utf-8'), callback=delivery_report)

p.flush()


class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 0:
            return 0
        if n == 1:
            return 1
        if n == 2:
            return 2
        pre = 1
        post = 2
        for i in range(3, n + 1):
            result = pre + post
            pre = post
            post = result
        return result
if __name__ == '__main__':
    solu = Solution()
    print(solu.climbStairs(3))