from __future__ import annotations

import itertools
from collections.abc import Iterator
from typing import Generator, Iterable, Optional, Sequence

import numpy as np
import tensorflow as tf

from pararealml.constrained_problem import ConstrainedProblem
from pararealml.initial_condition import VectorizedInitialConditionFunction
from pararealml.initial_value_problem import TemporalDomainInterval
from pararealml.operators.ml.physics_informed.collocation_point_sampler import (  # noqa: 501
    CollocationPointSampler,
)

class Dataset:
    """
    A generator and container of all the data necessary to train a
    physics-informed regresion model with variable initial conditions.
    """

    def __init__(
        self,
        cp: ConstrainedProblem,
        t_interval: TemporalDomainInterval,
        y_0_functions: Iterable[VectorizedInitialConditionFunction],
        point_sampler: CollocationPointSampler,
        n_domain_points: int,
        n_boundary_points: int = 0,
        vertex_oriented: bool = False,
    ):
        """
        :param cp: the constrained problem to generate the spatial data about
        :param t_interval: the bounds of the temporal domain to generate data
            from
        :param y_0_functions: the initial condition functions
        :param point_sampler: a sampler instance for sampling the collocation
            points
        :param n_domain_points: the number of domain points to sample
        :param n_boundary_points: the number of boundary points to sample; if
            the constrained problem is an ODE, it should be 0
        :param vertex_oriented: whether the initial condition collocation
            points should be the vertices or the cell centers of the mesh
        """
        x_dimension = cp.differential_equation.x_dimension

        if n_domain_points <= 0:
            raise ValueError(
                f"number of domain points ({n_domain_points}) must be greater "
                f"than 0"
            )
        if n_boundary_points < 0:
            raise ValueError(
                f"number of boundary points ({n_boundary_points}) must be "
                f"non-negative"
            )
        if not x_dimension and n_boundary_points:
            raise ValueError("number of boundary points must be 0 for ODEs")

        self._cp = cp
        self._t_interval = t_interval
        self._y_0_functions = y_0_functions
        self._point_sampler = point_sampler
        self._n_domain_points = n_domain_points
        self._n_boundary_points = n_boundary_points
        self._vertex_oriented = vertex_oriented

        self._initial_value_data = self._create_initial_value_data()
        self._domain_collocation_data = self._create_domain_collocation_data()
        self._initial_collocation_data = (
            self._create_initial_collocation_data()
        )
        self._boundary_collocation_data = (
            self._create_boundary_collocation_data()
        )

    @property
    def constrained_problem(self) -> ConstrainedProblem:
        """
        The constrained problem the dataset is built around.
        """
        return self._cp

    @property
    def initial_value_data(self) -> np.ndarray:
        """
        The initial value data where each row is a different initial condition
        function and each column represents a component of the initial
        condition function evaluated over a point of the constrained problem's
        mesh.
        """
        return self._initial_value_data

    @property
    def domain_collocation_data(self) -> np.ndarray:
        """
        The domain collocation data points where the first column is t and all
        other columns are x.
        """
        return self._domain_collocation_data

    @property
    def initial_collocation_data(self) -> np.ndarray:
        """
        The initial collocation data points where the first column is t and all
        other columns are x.
        """
        return self._initial_collocation_data

    @property
    def boundary_collocation_data(self) -> Optional[np.ndarray]:
        """
        The boundary collocation data points where the columns represent t, x,
        y, the derivative of y with respect to the unit normal vector of the
        boundary, and finally the axis denoting the direction of the normal
        vector.
        """
        return self._boundary_collocation_data

    def get_iterator(
        self, n_batches: int, n_ic_repeats: int = 1, shuffle: bool = True
    ) -> DatasetIterator:
        """
        Returns an iterator over the dataset to enable iterating over the
        Cartesian product of the initial value data and the collocation data
        batch by batch.

        :param n_batches: the number of batches to map the underlying data to
        :param n_ic_repeats: the number of times to repeat the initial
            collocation data samples in an epoch
        :param shuffle: whether to shuffle the data behind the iterator
        :return: the iterator over the dataset
        """
        return DatasetIterator(self, n_batches, n_ic_repeats, shuffle)

    def _create_initial_value_data(self) -> np.ndarray:
        """
        Creates the initial value data by evaluating the initial condition
        functions (over the vertices or the cell centers of the mesh in case
        the constrained problem is a PDE).
        """
        if self._cp.differential_equation.x_dimension:
            x = self._cp.mesh.all_index_coordinates(
                self._vertex_oriented, flatten=True
            )
            initial_value_data = np.vstack(
                [y_0_func(x).flatten() for y_0_func in self._y_0_functions]
            )
        else:
            initial_value_data = np.array(
                [y_0_func(None) for y_0_func in self._y_0_functions]
            )

        initial_value_data.setflags(write=False)
        return initial_value_data

    def _create_domain_collocation_data(self) -> np.ndarray:
        """
        Creates the domain collocation data by sampling collocation points from
        the space-time domain of the constrained problem combined with the time
        interval.
        """
        domain_points = self._point_sampler.sample_domain_points(
            self._n_domain_points, self._t_interval, self._cp.mesh
        )
        domain_collocation_data = (
            np.concatenate((domain_points.t, domain_points.x), axis=1)
            if self._cp.differential_equation.x_dimension
            else domain_points.t
        )

        domain_collocation_data.setflags(write=False)
        return domain_collocation_data

    def _create_initial_collocation_data(self) -> np.ndarray:
        """
        Creates the initial collocation data by combining the coordinates of
        the vertices or the cell centers of the constrained problem's mesh (if
        the constrained problem is a PDE) with an array of zeros representing
        the time points.
        """
        if self._cp.differential_equation.x_dimension:
            x = self._cp.mesh.all_index_coordinates(
                self._vertex_oriented, flatten=True
            )
            t = np.zeros((len(x), 1))
            initial_collocation_data = np.hstack((t, x))
        else:
            initial_collocation_data = np.zeros((1, 1))

        initial_collocation_data.setflags(write=False)
        return initial_collocation_data

    def _create_boundary_collocation_data(self) -> Optional[np.ndarray]:
        """
        Creates the boundary collocation data by sampling collocation points
        from the spatial boundaries of the space-time domain of the constrained
        problem combined with the time interval; if the constrained problem is
        a PDE, it also evaluates the boundary conditions (both Dirichlet and
        Neumann) and includes the constraints in the dataset.
        """
        diff_eq = self._cp.differential_equation
        x_dimension = diff_eq.x_dimension
        y_dimension = diff_eq.y_dimension
        if not x_dimension:
            return None

        all_boundary_points = self._point_sampler.sample_boundary_points(
            self._n_boundary_points, self._t_interval, self._cp.mesh
        )

        t = []
        x = []
        y = []
        d_y_over_d_n = []
        axis = []
        for ax, (bc_pair, boundary_points_pair) in enumerate(
            zip(self._cp.boundary_conditions, all_boundary_points)
        ):
            for bc, boundary_points in zip(bc_pair, boundary_points_pair):
                if boundary_points is None:
                    continue

                for i in range(boundary_points.t.shape[0]):
                    t_i = boundary_points.t[i]
                    x_i = boundary_points.x[i : i + 1]
                    y_i = (
                        bc.y_condition(x_i, t_i)[0]
                        if bc.has_y_condition
                        else [None] * y_dimension
                    )
                    d_y_over_d_n_i = (
                        bc.d_y_condition(x_i, t_i)[0]
                        if bc.has_d_y_condition
                        else [None] * y_dimension
                    )

                    t.append(t_i)
                    x.append(x_i[0])
                    axis.append([ax])
                    y.append(y_i)
                    d_y_over_d_n.append(d_y_over_d_n_i)

        boundary_collocation_data = np.concatenate(
            [
                np.array(t),
                np.array(x),
                np.array(y),
                np.array(d_y_over_d_n),
                np.array(axis),
            ],
            axis=1,
        )
        boundary_collocation_data.setflags(write=False)
        return boundary_collocation_data

class DatasetIterator(Iterator):
    """
    An iterator over a dataset that computes the Cartesian products of the
    initial value data with the domain, initial, and boundary collocation
    data.
    """

    def __init__(
        self,
        dataset: Dataset,
        n_batches: int,
        n_ic_repeats: int = 1,
        shuffle: bool = True,
    ):
        """
        :param dataset: the dataset to iterate over
        :param n_batches: the number of batches per epoch
        :param n_ic_repeats: the number of times to repeat the initial
            collocation data samples in an epoch
        :param shuffle: whether to shuffle the Cartesian product of the initial
            condition data and collocation data.
        """
        self._dataset = dataset
        self._n_batches = n_batches
        self._n_ic_repeats = n_ic_repeats
        self._shuffle = shuffle

        self._iv_data_size = dataset.initial_value_data.shape[0]
        self._domain_collocation_data_size = (
            dataset.domain_collocation_data.shape[0]
        )
        self._initial_collocation_data_size = (
            dataset.initial_collocation_data.shape[0]
        )
        self._boundary_collocation_data_size = (
            0
            if dataset.boundary_collocation_data is None
            else dataset.boundary_collocation_data.shape[0]
        )

        self._total_domain_data_size = (
            self._iv_data_size * self._domain_collocation_data_size
        )
        self._total_initial_data_size = (
            n_ic_repeats
            * self._iv_data_size
            * self._initial_collocation_data_size
        )
        self._total_boundary_data_size = (
            self._iv_data_size * self._boundary_collocation_data_size
        )

        if (
            self._total_domain_data_size % n_batches != 0
            or self._total_initial_data_size % n_batches != 0
            or self._total_boundary_data_size % n_batches != 0
        ):
            raise ValueError(
                "number of batches must be a common divisor of total domain "
                f"data size ({self._total_domain_data_size}), total initial "
                f"data size ({self._total_initial_data_size}), and total "
                f"boundary data size ({self._total_boundary_data_size})"
            )

        self._domain_batch_size = self._total_domain_data_size // n_batches
        self._initial_batch_size = self._total_initial_data_size // n_batches
        self._boundary_batch_size = self._total_boundary_data_size // n_batches

        self._domain_indices = self._create_cartesian_product_indices(
            self._iv_data_size, self._domain_collocation_data_size
        )
        self._initial_indices = np.tile(
            self._create_cartesian_product_indices(
                self._iv_data_size, self._initial_collocation_data_size
            ),
            (n_ic_repeats, 1),
        )
        self._boundary_indices = (
            self._create_cartesian_product_indices(
                self._iv_data_size, self._boundary_collocation_data_size
            )
            if self._boundary_collocation_data_size
            else None
        )

        self._batch_index = 0

    def __len__(self) -> int:
        return self._n_batches

    def __getitem__(self, index: int) -> Sequence[Sequence[tf.Tensor]]:
        return (
            self._get_domain_batch(index),
            self._get_initial_batch(index),
            self._get_boundary_batch(index),
        )

    def __next__(self) -> Sequence[Sequence[tf.Tensor]]:
        if self._batch_index >= self._n_batches:
            raise StopIteration

        batch = self[self._batch_index]
        self._batch_index += 1
        return batch

    def __iter__(self) -> DatasetIterator:
        self._batch_index = 0
        if self._shuffle:
            np.random.shuffle(self._domain_indices)
            np.random.shuffle(self._initial_indices)
            if self._boundary_collocation_data_size:
                np.random.shuffle(self._boundary_indices)

        return self

    @property
    def dataset(self) -> Dataset:
        """
        The dataset behind the iterator.
        """
        return self._dataset

    @property
    def domain_batch_size(self) -> int:
        """
        The domain data batch size used by the iterator.
        """
        return self._domain_batch_size

    @property
    def initial_batch_size(self) -> int:
        """
        The initial data batch size used by the iterator.
        """
        return self._initial_batch_size

    @property
    def boundary_batch_size(self) -> int:
        """
        The boundary data batch size used by the iterator.
        """
        return self._boundary_batch_size

    def to_infinite_generator(
        self,
    ) -> Generator[Sequence[Sequence[tf.Tensor]], None, None]:
        """
        Returns a generator that cycles over this iterator infinitely.
        """
        return (batch for _ in itertools.count(0) for batch in self)

    def _get_domain_batch(self, index: int) -> Sequence[tf.Tensor]:
        """
        Returns a domain data batch.

        :param index: the domain data batch index
        :return: the indexed domain data batch
        """
        start_index = index * self._domain_batch_size
        domain_indices = self._domain_indices[
            start_index : start_index + self._domain_batch_size, :
        ]
        domain_iv_data_indices = domain_indices[:, 0]
        domain_collocation_data_indices = domain_indices[:, 1]
        domain_iv_data = self._dataset.initial_value_data[
            domain_iv_data_indices
        ]
        domain_collocation_data = self._dataset.domain_collocation_data[
            domain_collocation_data_indices
        ]

        diff_eq = self._dataset.constrained_problem.differential_equation
        return (
            tf.convert_to_tensor(domain_iv_data, tf.float32),
            tf.convert_to_tensor(domain_collocation_data[:, :1], tf.float32),
            tf.convert_to_tensor(domain_collocation_data[:, 1:], tf.float32)
            if diff_eq.x_dimension
            else None,
        )

    def _get_initial_batch(self, index: int) -> Sequence[tf.Tensor]:
        """
        Returns an initial data batch.

        :param index: the initial data batch index
        :return: the indexed initial data batch
        """
        start_index = index * self._initial_batch_size
        initial_indices = self._initial_indices[
            start_index : start_index + self._initial_batch_size, :
        ]
        initial_iv_data_indices = initial_indices[:, 0]
        initial_collocation_data_indices = initial_indices[:, 1]
        initial_iv_data = self._dataset.initial_value_data[
            initial_iv_data_indices
        ]
        initial_collocation_data = self._dataset.initial_collocation_data[
            initial_collocation_data_indices
        ]

        initial_u_tensor = tf.convert_to_tensor(initial_iv_data, tf.float32)
        initial_t_tensor = tf.convert_to_tensor(
            initial_collocation_data[:, :1], tf.float32
        )

        diff_eq = self._dataset.constrained_problem.differential_equation
        if diff_eq.x_dimension:
            initial_x_tensor = tf.convert_to_tensor(
                initial_collocation_data[:, 1:], tf.float32
            )
            initial_y_tensor = tf.convert_to_tensor(
                initial_iv_data.reshape(
                    (self._initial_batch_size, -1, diff_eq.y_dimension)
                )[
                    np.arange(self._initial_batch_size),
                    initial_collocation_data_indices,
                    :,
                ],
                tf.float32,
            )
        else:
            initial_x_tensor = None
            initial_y_tensor = initial_u_tensor

        return (
            initial_u_tensor,
            initial_t_tensor,
            initial_x_tensor,
            initial_y_tensor,
        )

    def _get_boundary_batch(self, index: int) -> Optional[Sequence[tf.Tensor]]:
        """
        Returns a boundary data batch.

        :param index: the boundary data batch index
        :return: the indexed boundary data batch
        """
        if self._boundary_batch_size == 0:
            return None

        start_index = index * self._boundary_batch_size
        boundary_indices = self._boundary_indices[
            start_index : start_index + self._boundary_batch_size, :
        ]
        boundary_iv_data_indices = boundary_indices[:, 0]
        boundary_collocation_data_indices = boundary_indices[:, 1]
        boundary_iv_data = self._dataset.initial_value_data[
            boundary_iv_data_indices
        ]
        boundary_collocation_data = self._dataset.boundary_collocation_data[
            boundary_collocation_data_indices
        ]

        diff_eq = self._dataset.constrained_problem.differential_equation
        x_offset = 1
        y_offset = x_offset + diff_eq.x_dimension
        d_y_over_d_n_offset = y_offset + diff_eq.y_dimension
        axis_offset = d_y_over_d_n_offset + diff_eq.y_dimension

        return (
            tf.convert_to_tensor(boundary_iv_data, tf.float32),
            tf.convert_to_tensor(
                boundary_collocation_data[:, :x_offset], tf.float32
            ),
            tf.convert_to_tensor(
                boundary_collocation_data[:, x_offset:y_offset], tf.float32
            ),
            tf.convert_to_tensor(
                boundary_collocation_data[:, y_offset:d_y_over_d_n_offset],
                tf.float32,
            ),
            tf.convert_to_tensor(
                boundary_collocation_data[:, d_y_over_d_n_offset:axis_offset],
                tf.float32,
            ),
            tf.convert_to_tensor(
                boundary_collocation_data[:, axis_offset], tf.int32
            ),
        )

    @staticmethod
    def _create_cartesian_product_indices(
        first_set_size: int, second_set_size: int
    ) -> np.ndarray:
        """
        Creates a 2D array of indices for the Cartesian product of two sets of
        data rows.

        The first column of the returned array is the first set's row indices
        while the second column is the second set's row indices.

        :param first_set_size: the number of rows in the first set
        :param second_set_size: the number of rows in the second set
        :return: a 2D array with two columns of data row indices
        """
        first_set_indices = np.arange(0, first_set_size)
        second_set_indices = np.arange(0, second_set_size)
        cartesian_product_first_set_indices = np.repeat(
            first_set_indices, second_set_size, axis=0
        )
        cartesian_product_second_set_indices = np.tile(
            second_set_indices, (first_set_size,)
        )
        return np.stack(
            (
                cartesian_product_first_set_indices,
                cartesian_product_second_set_indices,
            ),
            axis=1,
        )


from typing import Optional

import torch
from reagent import types as rlt
from reagent.models.base import ModelBase
from reagent.models.fully_connected_network import FullyConnectedNetwork

class FullyConnectedDQN(ModelBase):
    def __init__(
        self,
        state_dim,
        action_dim,
        sizes,
        activations,
        *,
        num_atoms: Optional[int] = None,
        use_batch_norm=False,
        dropout_ratio=0.0,
        normalized_output=False,
    ):
        super().__init__()
        assert state_dim > 0, "state_dim must be > 0, got {}".format(state_dim)
        assert action_dim > 0, "action_dim must be > 0, got {}".format(action_dim)
        self.state_dim = state_dim
        self.action_dim = action_dim
        assert len(sizes) == len(
            activations
        ), "The numbers of sizes and activations must match; got {} vs {}".format(
            len(sizes), len(activations)
        )
        self.num_atoms = num_atoms
        self.fc = FullyConnectedNetwork(
            [state_dim] + sizes + [action_dim * (num_atoms or 1)],
            activations + ["linear"],
            use_batch_norm=use_batch_norm,
            dropout_ratio=dropout_ratio,
            normalize_output=normalized_output,
        )

    def input_prototype(self):
        return rlt.FeatureData(self.fc.input_prototype())

    def forward(self, state: rlt.FeatureData) -> torch.Tensor:
        float_features = state.float_features
        x = self.fc(float_features)
        if self.num_atoms is not None:
            x = x.view(float_features.shape[0], self.action_dim, self.num_atoms)
        return x


#I'm so happy to be able to do this.
#TRAIN TRACK STORY: long time ago, 2 boys were walking home from school along the train track.
#Actually on the train track. Health and safety those days, was based more on common sense and a bit of luck too.
#Back to our boys. Walking home along the track, they came across a fallen tree on the track. Knowing
#there would be a train passing by very soon, the boys started to panic. Some of their school friends were on the train.
#And other people too. In panic, they started hitting the track rails with stones hoping to alert the train driver.
#First, it was just about hitting the rails to create as much noise as possible, but then one of the boys remembered stories
#his grandad told him about travelling on sea and using Morse code to communicate using light. The SOS signal came to his
#mind and he started to use Morse Code to send the message. Strangely enough the driver of the approaching train overheard
#some strange noises, thinking there was something wrong with the train he started slowing down to a halt. Climbing out of
#machine to see what's wrong the ringing noises carried on coming from the direction the train was heading to. To cut
#the story short, the boys saved the day. They were very happy, their parrents were very proud and the school did a lesson
#or two on Morse code and other alternative ways to convey a message.  THE MORAL OF THE STORY: never walk on a train track. Alone.
#Always bring a friend. Because two people know more than one and are more likely to support each other in tricky situations.

#welcome to this project for Raspberry Pi.
#code bellow will le you connect LEDs to your Raspberry Pi.
#I used 5 different colours in 5 GPIOs: feel free to change these.
#we assume at this stage, the INPUT will be letters and space only.

import RPi.GPIO as GPIO
import time

#here are the 5 LEDs allocations for the Raspberry board:
blue,red,yellow,green,white= 22,23,4,17,27

#in here are all the necessary setups:
GPIO.setmode(GPIO.BCM),GPIO.setwarnings(False)
GPIO.setup(blue, GPIO.OUT), GPIO.setup(red, GPIO.OUT),GPIO.setup(yellow, GPIO.OUT), GPIO.setup(green, GPIO.OUT), GPIO.setup(white, GPIO.OUT)

#here is the function switching the RED led on:
def led(lenght):
    GPIO.output(red, GPIO.HIGH) #<to change colour change the colour name here 1/2
    time.sleep(lenght)
    GPIO.output(red, GPIO.LOW)   #<to change colour change the colour name here 2/2
    time.sleep(0.30)   #<pause after letter

#in here is the dictionary where the length of the beep/light on is in accordance with Morse code:
morse = {'a': (0.15, 0.5), 'b' : (0.5, 0.15, 0.15, 0.15), 'c': (0.5,0.15,0.5,0.15),
         'd':(0.5,0.15,0.15), 'e': (0.15), 'f': (0.15, 0.15,0.5,0.15), 'g':(0.5,0.5,0.15),
         'h':(0.15,0.15,0.15,0.15), 'i':(0.15,0.15), 'j': (0.15, 0.5,0.5,0.5), 'k': (0.5,0.15,0.5),
         'l': (0.15,0.5,0.15,0.15), 'm': (0.5,0.5), 'n': (0.5,0.15), 'o':(0.5,0.5,0.5),
         'p':(0.15,0.5,0.5,0.15), 'r':(0.15,0.5,0.15), 's': (0.15,0.15,0.15), 't': (0.15),
         'u': (0.15,0.15,0.5), 'v':(0.15,0.15,0.15,0.5), 'w': (0.15,0.5,0.5), 'x': (0.5,0.15,0.15,0.5),
         'y': (0.5,0.15,0.5,0.5), 'z': (0.5,0.5,0.15,0.15),}

#here is a sos signal to play with:
a = 'SOS sos'

#and here is the function doing all the magic:
def convertToMorse(stringie):
    stringie = stringie.lower()#<converts upper case to lower:

    for i in stringie:

        if i == ' ':  #<here we work with space in a string
            time.sleep(1.5)

        else:
            for x in morse[i]:   #<and here we do the converting:
                led(x)

#and here we test the code:
convertToMorse(a)

#hope you like the project. Have a lovely day.


from __future__ import division
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from util import *
#from torch.autograd import Variable (deprecated)
import numpy as np

def get_test_input():
    img = cv2.imread("imgs/dog-cycle-car.png")
    img = cv2.resize(img,(416,416))
    #  ::-1 means start:end:step
    #  width and height not change, change the color channel dim
    img_ = img[:,:,::-1].transpose((2,0,1)) #BGR->RGB | H W C -> C H W

    img_ = img_[np.newaxis,:,:,:]/255.0 # add a channel at 0 for batch and normalise
    img_ = torch.from_numpy(img_).float()
    img_ = Variable(img_)
    #BCHW
    return img_

class EmptyLayer(nn.Module):
    def __init__(self):
        super(EmptyLayer, self).__init__()

class DetectionLayer(nn.Module):
    def __init__(self, anchors):
        super(DetectionLayer, self).__init__()
        self.anchors = anchors

def parse_cfg(cfg_file):
    """
    Deal with cfg file
    Returns a list of blocks,each block describes a network to be build.
    block is a dictionary
    """
    file = open(cfg_file, 'r')
    lines = file.read().split('\n')
    lines = [x for x in lines if len(x) > 0]
    lines = [x for x in lines if x[0] != '#']
    lines = [x.rstrip().lstrip() for x in lines]

    block = {}
    blocks = []
    for line in lines:
        if line[0] == "[":
            if len(block) != 0:
                blocks.append(block)
                block = {}
            block["type"] = line[1:-1].rstrip()
        else:
            key, value = line.split("=")
            block[key.rstrip()] = value.lstrip()
    blocks.append(block)
    return blocks
############handles############
def handle_upsample(
                block,
                index,
                net_info,
                output_filters,
                module_list,
                prev_filters
                ):
    module = nn.Sequential()
    stride = int(block["stride"])
    upsample = nn.Upsample(scale_factor=stride, mode="nearest")#this is 2
    module.add_module("upsample_{}".format(index), upsample)
    module_list.append(module)

def handle_convolutional(block,
                index,
                net_info,
                output_filters,
                module_list,
                prev_filters):
    module = nn.Sequential()#each block may has muti layers
    activation = block["activation"]
    try:
        batch_normalize = int(block["batch_normalize"])
        bias = False
    except:
        batch_normalize = 0
        bias = True
    filters = int(block["filters"])
    padding = int(block["pad"])
    kernel_size = int(block["size"])
    stride = int(block["stride"])

    if padding:
        pad = (kernel_size-1)//2
    else:
        pad = 0
    #add conv layer
    prev_filter = prev_filters[0]
    conv = nn.Conv2d(prev_filter, filters, kernel_size, stride, pad, bias = bias)
    module.add_module("conv_{0}".format(index), conv)

    #add the batch norm layer
    if batch_normalize:
        bn = nn.BatchNorm2d(filters)# TODO what is batch norm????
        module.add_module("batch_norm_{0}".format(index), bn)
    #add the activation
    if activation == "leaky":
        activn = nn.LeakyReLU(0.1, inplace=True)
        module.add_module("leaky_{0}".format(index), activn)
    prev_filters[0] = filters
    module_list.append(module)

def handle_route(block,
                index,
                net_info,
                output_filters,
                module_list,
                prev_filters):
    module = nn.Sequential()
    block["layers"] = block["layers"].split(',')
    start = int(block["layers"][0])
    try:
        end = int(block["layers"][1])
    except:
        end = 0
    if start > 0:
        start = start - index
    if end > 0:
        end = end - index
    route = EmptyLayer()
    module.add_module("route_{0}".format(index), route)
    if end < 0:
        prev_filters[0] = output_filters[index + start] + output_filters[index + end]
    else:
        prev_filters[0] = output_filters[index + start]
    module_list.append(module)

def handle_shortcut(block,
                index,
                net_info,
                output_filters,
                module_list,
                prev_filters):
    module = nn.Sequential()
    shortcut = EmptyLayer()
    module.add_module("shortcut_{}".format(index), shortcut)
    module_list.append(module)
def handle_yolo(block,
                index,
                net_info,
                output_filters,
                module_list,
                prev_filters):
    module = nn.Sequential()
    mask = block["mask"].split(",")
    mask = [int(x) for x in mask]
    anchors = block["anchors"].split(",")
    anchors = [int(a) for a in anchors]
    anchors = [(anchors[i], anchors[i+1]) for i in range(0, len(anchors), 2)]
    anchors = [anchors[i] for i in mask]

    detection = DetectionLayer(anchors)
    module.add_module("Detection_{}".format(index), detection)
    module_list.append(module)

block_handlers = {
'convolutional':handle_convolutional,
'upsample':handle_upsample,
'route':handle_route,
'shortcut':handle_shortcut,
'yolo':handle_yolo
}

def create_modules_from_blocks(blocks):
    net_info = blocks[0]
    module_list = nn.ModuleList()
    prev_filters = [3] #前一层的filter的数量
    output_filters = [] #所有层的filter的数量
    for index, block in enumerate(blocks[1:]):
        block_type = block["type"]
        #try:
        if block_type in block_handlers:
            try:
                block_handlers[block_type](
                    block,
                    index,
                    net_info,
                    output_filters,
                    module_list,
                    prev_filters)

            except Exception as err:
                print("call handler_", block_type, " has except:", err)
        else:
            print("has not handler_", block_type)
        output_filters.append(prev_filters[0])
    return (net_info, module_list)

class Darknet(nn.Module):
    def __init__(self, cfg_file):
        super(Darknet, self).__init__()
        self.blocks = parse_cfg(cfg_file)
        self.net_info, self.module_list = create_modules_from_blocks(self.blocks)
        assert(len(self.blocks) == len(self.module_list)+1)
        self.output_sizes = {}
    def load_weights(self, weightfile):
        #Open the weights file
        fp = open(weightfile, "rb")

        #The first 5 values are header information
        # 1. Major version number
        # 2. Minor Version Number
        # 3. Subversion number
        # 4,5. Images seen by the network (during training)
        header = np.fromfile(fp, dtype = np.int32, count = 5)
        self.header = torch.from_numpy(header)
        self.seen = self.header[3]

        weights = np.fromfile(fp, dtype = np.float32)

        ptr = 0
        for i in range(len(self.module_list)):
            module_type = self.blocks[i + 1]["type"]

            #If module_type is convolutional load weights
            #Otherwise ignore.

            if module_type == "convolutional":
                model = self.module_list[i]
                try:
                    batch_normalize = int(self.blocks[i+1]["batch_normalize"])
                except:
                    batch_normalize = 0

                conv = model[0]

                if (batch_normalize):
                    bn = model[1]

                    #Get the number of weights of Batch Norm Layer
                    num_bn_biases = bn.bias.numel()

                    #Load the weights
                    bn_biases = torch.from_numpy(weights[ptr:ptr + num_bn_biases])
                    ptr += num_bn_biases

                    bn_weights = torch.from_numpy(weights[ptr: ptr + num_bn_biases])
                    ptr  += num_bn_biases

                    bn_running_mean = torch.from_numpy(weights[ptr: ptr + num_bn_biases])
                    ptr  += num_bn_biases

                    bn_running_var = torch.from_numpy(weights[ptr: ptr + num_bn_biases])
                    ptr  += num_bn_biases

                    #Cast the loaded weights into dims of model weights.
                    bn_biases = bn_biases.view_as(bn.bias.data)
                    bn_weights = bn_weights.view_as(bn.weight.data)
                    bn_running_mean = bn_running_mean.view_as(bn.running_mean)
                    bn_running_var = bn_running_var.view_as(bn.running_var)

                    #Copy the data to model
                    bn.bias.data.copy_(bn_biases)
                    bn.weight.data.copy_(bn_weights)
                    bn.running_mean.copy_(bn_running_mean)
                    bn.running_var.copy_(bn_running_var)

                else:
                    #Number of biases
                    num_biases = conv.bias.numel()

                    #Load the weights
                    conv_biases = torch.from_numpy(weights[ptr: ptr + num_biases])
                    ptr = ptr + num_biases

                    #reshape the loaded weights according to the dims of the model weights
                    conv_biases = conv_biases.view_as(conv.bias.data)

                    #Finally copy the data
                    conv.bias.data.copy_(conv_biases)

                #Let us load the weights for the Convolutional layers
                num_weights = conv.weight.numel()

                #Do the same as above for weights
                conv_weights = torch.from_numpy(weights[ptr:ptr+num_weights])
                ptr = ptr + num_weights

                conv_weights = conv_weights.view_as(conv.weight.data)
                conv.weight.data.copy_(conv_weights)
    def load_weights_old(self, weightfile):
        fp = open(weightfile, "rb")

        # header information
        # 1.major version number
        # 2.minor version number
        # 3.subversion number
        # 4,5 images seen by the network

        header = np.fromfile(fp, dtype = np.int32, count = 5)
        self.header = torch.from_numpy(header)
        self.seen = self.header[3]
        weights = np.fromfile(fp, dtype = np.float32)
        ptr = 0
        for i in range(len(self.module_list)):
            module_type = self.blocks[i + 1]["type"]
            if module_type == "convolutional":
                model = self.module_list[i]
                try:
                    batch_normalize = int(self.blocks[i+1]["batch_normalize"])
                except:
                    batch_normalize = 0
                conv = model[0]

                if (batch_normalize):
                    bn = model[1]
                    print("bn:",bn)
                    num_bn_biases = bn.bias.numel()
                    bn_biases = torch.from_numpy(weights[ptr:ptr+num_bn_biases])
                    ptr += num_bn_biases
                    bn_weights = torch.from_numpy(weights[ptr:ptr+num_bn_biases])
                    ptr += num_bn_biases

                    bn_running_mean = torch.from_numpy(weights[ptr:ptr + num_bn_biases])
                    ptr += num_bn_biases

                    bn_running_var = torch.from_numpy(weights[ptr:ptr+num_bn_biases])
                    ptr += num_bn_biases
                    #cast the loaded weights into dims of model weights
                    bn_biases = bn_biases.view_as(bn.bias.data)
                    bn_weights = bn_weights.view_as(bn.weight.data)
                    bn_running_mean = bn_running_mean.view_as(bn.running_mean)
                    bn_running_var = bn_running_var.view_as(bn.running_var)

                    #copy the data to model
                    bn.bias.data.copy_(bn_biases)
                    bn.weight.data.copy_(bn_weights)
                    bn.running_mean.copy_(bn_running_mean)
                    #bn_running_var.copy_(bn_running_var)
                    # fixed bud !!!!!!!上面这里手滑写错,导致权重load出错，bn.running_var没有被设置
                    # 查看下面的这些内容的一致性是通过输出这些信息到终端，重定向到文件，然后对比md5sum
                    # 1.查看网络输出是否一致
                    # 2.查看输入是否一致
                    # 3.查看网络结构是否一致
                    # 4.查看网络的参数是否一致，发现加载的参数不一样
                    # 5.发现load_weights函数的bug
                    bn.running_var.copy_(bn_running_var)
                else:
                    num_biases = conv.bias.numel()
                    conv_biases = torch.from_numpy(weights[ptr:ptr+num_biases])
                    ptr = ptr + num_biases
                    conv_biases = conv_biases.view_as(conv.bias.data)
                    conv.bias.data.copy_(conv_biases)
                num_weights = conv.weight.numel()
                conv_weights = torch.from_numpy(weights[ptr:ptr+num_weights])
                ptr = ptr + num_weights

                conv_weights = conv_weights.view_as(conv.weight.data)
                conv.weight.data.copy_(conv_weights)

    def forward(self, x, CUDA):
        #x is BCHW format
        batch, channels, height, width = x.size()
        assert(channels == int(self.net_info["channels"]))
        assert(height == int(self.net_info["height"]))
        assert(width == int(self.net_info["width"]))
        #print("input batch is ", batch)
        modules = self.blocks[1:]
        outputs = {} #cache the outputs for the router layer

        write = 0 #TODO
        for i, module in enumerate(modules):
            module_type = (module["type"])
            if module_type =="convolutional" or module_type == "upsample":
                x = self.module_list[i](x)
            elif module_type == "route":
                layers = module["layers"]
                layers = [int(a) for a in layers]
                if layers[0] > 0:
                    layers[0] = layers[0] - i
                if len(layers) == 1:
                    x = outputs[i + layers[0]]
                else:
                    if (layers[1]) > 0:
                        layers[1] = layers[1] - i
                    map1 = outputs[i + layers[0]]
                    map2 = outputs[i + layers[1]]
                    assert(map1.size()[2] == map2.size()[2])
                    assert(map1.size()[3] == map2.size()[3])
                    x = torch.cat((map1, map2), 1)
                    assert(map1.size()[1] + map2.size(1) == x.size()[1])
            elif module_type == "shortcut":
                from_ = int(module["from"])
                assert(outputs[i-1].size() == outputs[i + from_].size())
                x = outputs[i - 1] + outputs[i + from_]
            elif module_type == "yolo":
                #[1, 255, 13, 13]==>[1, 507, 85]
                #[1, 255, 26, 26]==>[1, 2028, 85]
                #[1, 255, 52, 52]==>[1, 8112, 85]
                anchors = self.module_list[i][0].anchors
                #Get the input dim
                input_dim = int(self.net_info["height"])

                num_classes = int(module["classes"])
                #transform
                x = x.data
                #print("row yolo output:,", x.size())#last lay x.size is torch.Size([1, 255, 52, 52])
                #print("predict_transform: input_dim=", input_dim, " anchors=", anchors, " num_classes=", num_classes)
                x = predict_transform(x, input_dim,anchors, num_classes, CUDA)
                if not write:
                    detections = x
                    write = 1
                else:
                    detections = torch.cat((detections,x), 1)

            outputs[i] = x
            self.output_sizes[i] = x.size()
        return detections

###############test################

#blocks = parse_cfg("./cfg/yolov3.cfg")
#net_info , module_list = create_modules_from_blocks(blocks)
if __name__ == '__main__':
    model = Darknet("/home/wyy/pytorch/my/detector/yolov3/cfg/yolov3.cfg")

    model.load_weights_old("/home/wyy/pytorch/my/detector/yolov3/weights/yolov3.weights")
    print("------begin")
    #print(model.state_dict())
    print("------end")
    inp = get_test_input()
    CUDA = torch.cuda.is_available()
    if CUDA:
        model.cuda()
        print("use CUDA model")
    model.eval()

    print("inp size:", inp.size())
    pred = model(inp.cuda(), CUDA)
    output = write_results(pred, 0.6, 80)
    print("output size:",output.size())


import re
from copy import copy
from tqdm import tqdm

with open('input.txt', 'r') as f:
    data = f.read()

test = """Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
Valve BB has flow rate=13; tunnels lead to valves CC, AA
Valve CC has flow rate=2; tunnels lead to valves DD, BB
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
Valve EE has flow rate=3; tunnels lead to valves FF, DD
Valve FF has flow rate=0; tunnels lead to valves EE, GG
Valve GG has flow rate=0; tunnels lead to valves FF, HH
Valve HH has flow rate=22; tunnel leads to valve GG
Valve II has flow rate=0; tunnels lead to valves AA, JJ
Valve JJ has flow rate=21; tunnel leads to valve II"""

class Node:
    def __init__(self, name, flow_rate):
        self.name = name
        self.flow_rate = flow_rate
        self.tunnels = []
        self.distances = None

    def add_tunnel(self, tunnel):
        self.tunnels.append(tunnel)

    def __repr__(self):
        return f'{self.name}'

cache = set()

def get_part_one(data):
    lines = data.split('\n')

    nodes = {}
    for line in lines:
        aa = re.findall(
            r"Valve (\w\w) has flow rate=(\d+); tunnel[s]? lead[s]? to valve[s]? (.*)", line)
        nodes[aa[0][0]] = {'flow_rate': int(
            aa[0][1]), 'tunnels': aa[0][2].split(', ')}

    nodes_objs = {}

    for node in nodes:
        nodes_objs[node] = Node(node, nodes[node]['flow_rate'])

    for node in nodes:
        for tunnel in nodes[node]['tunnels']:
            nodes_objs[node].add_tunnel(tunnel)

    for node in nodes:
        distances = get_distance(nodes_objs[node], nodes_objs)
        nodes_objs[node].distances = distances

    current_node = nodes_objs['AA']

    visit_mask = {k: False for k in nodes_objs}

    return search(current_node, 30, nodes_objs, 0, visit_mask)

def search(current_node, time, nodes, score, visit_mask):

    if (current_node, time, tuple(visit_mask.values())) in cache:
        return score

    visit_mask = copy(visit_mask)

    if time <= 0:
        return score

    scores = []

    score += current_node.flow_rate*time
    visit_mask[current_node.name] = True
    scores.append(score)

    for k in current_node.distances:
        if visit_mask[k] == False:
            scores.append(
                search(nodes[k], time-(current_node.distances[k]+1), nodes, score, visit_mask))

    cache.add((current_node, time, tuple(visit_mask.values())))
    return max(scores)

def get_distance(current_node, nodes):
    distance = 1
    distances = {}

    nn = [current_node.name]
    while len(distances) < len(nodes):
        tmp = []
        for n in nn:
            tmp = tmp + nodes[n].tunnels

        nn = list(set(tmp))
        for n in nn:
            if n not in distances:
                distances[n] = distance
        distance += 1
    distances = {k: v for k, v in distances.items(
    ) if nodes[k].flow_rate != 0 and k != current_node.name}
    return distances

assert get_part_one(test) == 1651
print(f'Part 1: {get_part_one(data)}')

# part 2

def int_to_visit_mask(n, nodes, bit_wise_not=False):
    mask = {}
    for i, node in enumerate(nodes):
        a = bool(n & (1 << i))
        if bit_wise_not:
            a = not a
        mask[node] = a
    return mask

def get_part_two(data):
    lines = data.split('\n')

    nodes = {}
    for line in lines:
        aa = re.findall(
            r"Valve (\w\w) has flow rate=(\d+); tunnel[s]? lead[s]? to valve[s]? (.*)", line)
        nodes[aa[0][0]] = {'flow_rate': int(
            aa[0][1]), 'tunnels': aa[0][2].split(', ')}

    nodes_objs = {}

    for node in nodes:
        nodes_objs[node] = Node(node, nodes[node]['flow_rate'])

    for node in nodes:
        for tunnel in nodes[node]['tunnels']:
            nodes_objs[node].add_tunnel(tunnel)

    for node in nodes:
        distances = get_distance(nodes_objs[node], nodes_objs)
        nodes_objs[node].distances = distances

    current_node = nodes_objs['AA']

    tbd = [k for k in nodes_objs if nodes_objs[k].flow_rate != 0 or k == 'AA']

    max_ = 0

    for i in tqdm(range(2**(len(tbd)))):
        mask = int_to_visit_mask(i, tbd)
        not_mask = int_to_visit_mask(i, tbd, bit_wise_not=True)
        l = search(current_node, 26, nodes_objs, 0, mask)
        r = search(current_node, 26, nodes_objs, 0, not_mask)
        max_ = max(max_, l + r)

    return max_

assert get_part_two(test) == 1707
print(f'Part 2: {get_part_two(data)}')


#!/usr/bin/python3
from subprocess import call
from sync import sync

dirs = ("busters",
		"nietzsche",
		"poetica",
		"sagis_solum",
		"prog"
		)

for i in dirs:
	sync(	f"/home/daxi/{i}",
			"/mnt/daxi/",
			0,
			""
		)


import json

import rclpy
import rclpy.node

# from ament_index_python import get_package_share_directory
from expandroid_msgs.msg import ExpandroidCommand, JoyAndApp, ExpandroidState
from expandroid_commander.get_speed_command import (
    get_speed_command,
    modify_speed_command,
)

from ament_index_python import get_package_share_directory

class ExpandroidParameterSetup(rclpy.node.Node):
    def __init__(self):
        super().__init__("expandroid_parameter_setup")

        self._path_to_field_config = self.declare_parameter(
            "path_to_field_config",
            value=get_package_share_directory("expandroid_bringup")
            + "/config/field.json",
        ).value

        # subscribe joystick
        self.create_subscription(JoyAndApp, "joy_and_app", self.joy_callback, 10)
        self.create_subscription(
            ExpandroidState, "expandroid_state", self.state_callback, 10
        )
        # publish command
        self._speed_command = ExpandroidCommand()
        self.speed_command_publisher = self.create_publisher(
            ExpandroidCommand, "expandroid_speed_command", 10
        )
        # timer
        self.timer = self.create_timer(0.1, self.commander_callback)

    def joy_callback(self, msg: JoyAndApp):
        joy_msg = msg.joy

        if msg.type.data == "pos" and hasattr(self, "_current_state"):
            self._field_config = json.load(open(self._path_to_field_config, "r"))

            self.get_logger().info("color: {}".format(msg.color.data))
            self.get_logger().info("button_num: {}".format(msg.value))
            self.get_logger().info("state: {}".format(self._current_state))

            self._field_config[msg.color.data][str(msg.value)]["pos"].append(
                [
                    round(self._current_state.hand_angle, 3),
                    round(self._current_state.x_angle, 3),
                    round(self._current_state.y_angle, 3),
                    # round(self._current_state.z_angle, 3),
                    0.0,
                ]
            )
            json.dump(
                self._field_config,
                open(self._path_to_field_config, "w"),
                indent=2,
            )

        self._speed_command = get_speed_command(joy_msg, self._speed_command)
        if hasattr(self, "_current_state"):
            self._speed_command = modify_speed_command(
                self._current_state, self._speed_command
            )

    def commander_callback(self):
        self.speed_command_publisher.publish(self._speed_command)

    def state_callback(self, msg: ExpandroidState):
        self._current_state = msg

def main():
    rclpy.init()
    node = ExpandroidParameterSetup()
    rclpy.spin(node)
    rclpy.shutdown()

if __name__ == "__main__":
    main()


import sys, traceback
sys.path.append("..") # Adds parent directory to python3 modules path
import os , re , time
import socket
import socketserver
import pickle
from exam_util_v1_2 import Payload, Con_header, Resp_header, Repolist, Exam_Helper

class MyTCPHandler(socketserver.BaseRequestHandler):

    """
    The request handler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def setup(self):
        # this will be invoked once at the beginnig of the instantiation.
        #print("setup is invoked")
        self.buffer_size=Exam_Helper.block_size
        self.meta = Security_Check_Point()

    def get_payload(self,req_header):
        print(f"entering get_payload of {req_header.mod_code}, uploaded by : {req_header.uploader_id}")
        scp=self.meta
        files = [f for f in os.listdir('.') if os.path.isfile(f) and \
                 f.endswith(req_header.uploader_id+'.dat') and f.startswith(req_header.mod_code)]
        #print(files)
        if len(files) != 1 :
            return None
        ########################
        try:
            with open(files[0],"rb") as f1:
                payload_bytes = f1.read() # read in the entire file and store it in payload_bytes
                f1.close()
            return payload_bytes
        except:
            print(f"Serious FILE I/O error. Cannot open/read from {files[0]}")
            return None

    def send_payload(self,pload_bytes):
        try:
            # now waiting for ready to receive signal from the client
            ack = str(self.request.recv(self.buffer_size), "utf-8")
            if ack != "ack":
                print("client abort")
                return
            print("Got the ack. Send the payload now")
            Exam_Helper.block_send(self.request,pload_bytes,self.buffer_size)
        except socket.timeout as tmerr:
            print("handler timout and exits")

    def get_pload_list(self,staff_id):
        #print(f"in get_pload_list staff_id is {staff_id}")
        def get_Playload_Info(fname,staff_id):
            # get_Playload_Info is a sub function of get_pload_list()
            # Playload Info includes the module code, the examiner id and the upload date/time
            scp=self.meta
            output=""
            id=re.search(r"\.([^\.]*)",fname) # search for staff_id from the filename.
            if id and id.lastindex == 1:
                if staff_id == scp.p_admin_id or staff_id in scp.others or staff_id == id.group(1):
                    # retrieve all the files for admin or user own files.
                    mod_code=re.search(r"^[^\.]*",fname)
                    if mod_code:
                        t=os.stat(fname).st_mtime
                        output=f"{mod_code.group(0):20} {id.group(0)[1:]:10} {time.ctime(t):30}\n"
            return output

        result=""
        files = [f for f in os.listdir('.') if os.path.isfile(f) and f.endswith('.dat')]
        #print(files) # all the matched files.
        for f in files:
            result=result+get_Playload_Info(f,staff_id)
        repo=Repolist() # create a default (and empty) Repolist object.
        if len(result) > 0:
            repo.status="ok"
            repo.content=f"{'Module_Code':20} {'Upload_By':10} {'Last_Modified':30}\n"+result
        return pickle.dumps(repo)

    def handle_upload(self,req_header):
        try:
            p_len = req_header.payload_size
            # print(f"payload size: {p_len}") # for debugging.
            # send a positive ack to the client
            scp=self.meta       # Retrieve the server owner, exam admid ids.
            resp_header= Resp_header()
            resp_header.resp_type='ok'
            # The following responses may provide the info for the client to encrypt the
            # payload in such a way that, all the exam admins can decrypt the payload at their ends.
            resp_header.p_admin_id=scp.p_admin_id
            resp_header.others = scp.others
            # send the resp_header now.
            Exam_Helper.block_send(self.request,pickle.dumps(resp_header),self.buffer_size)
            # now is waiting for the payload from the client.
            pload_bytes = Exam_Helper.block_recv(self.request,p_len,self.buffer_size)
            pload = pickle.loads(pload_bytes)
            if type(pload) is Payload:
                print("Payload has just arrived")
                print(f"staff id : {pload.staff_id}")
                print(f"module code : {pload.mod_code}")
                print(f"Exam paper file name: {pload.exam_fn}")
                print(f"Exam solution file name : {pload.sol_fn}")
                # now write payload bytes to a binary file.
                with open(pload.mod_code+'.'+pload.staff_id+".dat","wb") as outf:
                    outf.write(pload_bytes)
                # send back an acknowledgement message to the client
                self.request.sendall(b"upload operation has been completed successfully")
            else:
                #print(f"pload object type => {type(pload)}")
                # send back an error message to the client
                self.request.sendall(b"upload operation has been failed!!!")
        except socket.timeout as tmerr:
            print("handler timout and exits")
            pass
        except:
            print(f"handler exists due to unexpected error : {sys.exc_info()[0]}")
            traceback.print_exc(file=sys.stdout)

    def handle_retrieval(self,req_header):
        print(f"{req_header.requester_id} is requesting to retrieve the payload of {req_header.mod_code}")
        scp=self.meta
        resp_header= Resp_header()
        if req_header.requester_id == scp.p_admin_id or req_header.requester_id in scp.others:
            payload_bytes=self.get_payload(req_header)
            if payload_bytes != None:
                resp_header.resp_type='ok'
                resp_header.payload_size=len(payload_bytes)
                resp_bytes=pickle.dumps(resp_header)
                print("sending resp_header to client")
                self.request.sendall(resp_bytes)
                self.send_payload(payload_bytes)
                return
        resp_header.resp_type='rejected'
        resp_bytes=pickle.dumps(resp_header)
        self.request.sendall(resp_bytes)

    def handle_get_payload_listing(self,staff_id):
        try:
            rpo_bytes=self.get_pload_list(staff_id) # repo_bytes is from a Repolist object.
            #it contains a status , and a content field
            #print("rpo_bytes is ready. Send it now")
            Exam_Helper.block_send(self.request,rpo_bytes,self.buffer_size)
        except socket.timeout as tmerr:
            print("handler timout and exits")
        except:
            print(f"handler exists due to unexpected error : {sys.exc_info()[0]}")

    def handle(self):
        # self.request is the TCP socket connected to the client
        # Set a timeout value on this socket connection, to avoid
        # this server to be held up by a malfunction client.
        self.request.settimeout(Exam_Helper.timeout_in_seconds)
        try:
            print(f"Connection from {self.client_address[0]}:{self.client_address[1]}")
            self.data = self.request.recv(self.buffer_size).strip()
            if self.data == None:
                return()
            # self.data should contain a valid Con_header object
            req_header = pickle.loads(self.data)
            if type(req_header) is Con_header and req_header.request_type in ['u','r','L']:
                if req_header.request_type=='u':
                    self.handle_upload(req_header)
                elif req_header.request_type =='r':
                    self.handle_retrieval(req_header)
                else: # must be 'L'
                    self.handle_get_payload_listing(req_header.requester_id)
            else:
                #invalid request
                print(f"Handler exits due to invalid request: {req}")
                return()

        except socket.timeout as tmerr:
            print("handler timout and exits")
        #except:
        #    print(f"handler exists due to unexpected error : {sys.exc_info()[0]}")

    def finish(self):
        print("reaching finish() of the handler")
        return socketserver.BaseRequestHandler.finish(self)


from pathlib import Path

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

DB_URL= "sqlite:///"+str(Path(__file__).parent / 'guitar_listings.db')

column_name_translation = dict(
    modell="model",
    bauweise="shape",
    farbe="color",
    griffbrett="wood_fretboard",
    inkl_gigbag="gigbag_included",
    koffer="case_included",
    tonabnehmer="has_pickup",
    verkaufsrang="sales_rank",
    hersteller_id="manufacturer_id",
    erhaeltlich_seit="available_since",
    buende="frets",
    holz_decke="wood_top",
    holz_boden_zargen="wood_back_sides",
    artikelnummer="item_number"
)

# Create engine singleton and associated sessionmaker
engine = create_engine(DB_URL)
Session = sessionmaker()
Session.configure(bind=engine)


""" Displays a knight rider animation on the hat"""

# -- setup

import time
import unicornhat as unicorn

unicorn.set_layout(unicorn.AUTO)
unicorn.rotation(180)
unicorn.brightness(0.5)
WIDTH, HEIGHT = unicorn.get_shape()

# -- globals

# define a list of reds to use to light up the pixels
# this can be tinkered with to produce something that looks better
color_range = [(110,0,0),
               (150,0,0),
               (220,0,0),
               (255,0,0),
               (255,0,0),
               (220,0,0),
               (150,0,0),
               (110,0,0)]

# -- functions

def light_up_row(palette, start_value):
    """ lights up all the rows on the hat:

        loops over the columns on the hat, if this is in the
        allowed range (0 -> 7) light up those pixels using the palette
        provided.

        The inner loop just applies the coloring to all rows of the hat
    """
    # set starting position of the palette
    pal_pos = 0
    print(f"range to light up is from {start_value} to {start_value + 7}")
    # loop from start value to end value (8 positions)
    for col in range(start_value, start_value + 8, 1):
        # if the value is not outside the hat range, light up this pixel
        if col >= 0 and col <= 7:
            print(f"lighting up column {col} with {palette[pal_pos]}")
            # color all pixels
            for row in range(2,6):
                unicorn.set_pixel(col, row, palette[pal_pos])
        # for each loop iteration, update display
        unicorn.show()
        pal_pos = pal_pos + 1
    time.sleep(0.02)
    unicorn.off()
    print("-----------------------------------------------")

def offset_looper():
    """ constructs ranges and feeds it to light_up_row """
    for i in range(-9, 9, 1):
        print("moving right -->")
        print(f"position is {i}")
        light_up_row(palette = color_range, start_value = i)
    print("---- changing direction ----")
    for p in range(9, -9, -1):
        print("moving left <--")
        print(f"position is {p}")
        light_up_row(palette = color_range, start_value = p)

def knight_rider(seconds):
    """ runs the entire process for xx seconds """
    t_end = time.time() + seconds
    while time.time() < t_end:
        offset_looper()
    unicorn.off()

# -- run

knight_rider(8)


import torch
import torch.nn as nn
import torch.nn.functional as F
from transformers import RobertaModel
from Layers.gcn import GraphConvolution
import pickle

class Label2Context(nn.Module):  # label attention in the encoder
    def __init__(self, label_embedding_size, attn_hidden_size):
        super(Label2Context,self).__init__()
        self.proj_label_top = nn.Linear(label_embedding_size, attn_hidden_size, bias=False)
        self.proj_label_sec = nn.Linear(label_embedding_size, attn_hidden_size, bias=False)
        self.proj_label_conn = nn.Linear(label_embedding_size, attn_hidden_size, bias=False)

    def forward(self, input_data, label_repr, use_label_num):
        seq_len = input_data.shape[1]
        lb_num = use_label_num[1] - use_label_num[0]
        embedding_label = label_repr[use_label_num[0]:use_label_num[1]]
        if lb_num == 4:
            embedding_label = self.proj_label_top(embedding_label)
        if lb_num == 11:
            embedding_label = self.proj_label_sec(embedding_label)
        if lb_num == 102:
            embedding_label = self.proj_label_conn(embedding_label)
        embedding_label = embedding_label.transpose(0, 1)
        input_data = F.normalize(input_data, dim=-1, p=2)
        embedding_label = F.normalize(embedding_label, dim=0, p=2)
        G = torch.matmul(input_data.reshape(-1, input_data.shape[-1]), embedding_label)
        G = G.reshape(-1, seq_len, G.shape[-1])
        max_G = G.max(-1, keepdim=True)[0]  # [batch_size, seq_length, 1]
        soft_max_G = torch.softmax(max_G, dim=1)
        output = torch.sum(input_data * soft_max_G, axis=1)
        return output

class Decoder(nn.Module):
    def __init__(self, label_embedding_size, hidden_size, enc_hidden_size, dec_hidden_size):
        super().__init__()
        self.hidden_size = hidden_size
        self.rnn = nn.GRU(enc_hidden_size+100, dec_hidden_size)
        self.proj_out = nn.Linear(dec_hidden_size*2+100, dec_hidden_size)

    def forward(self, input, hidden, encoder_outputs):
        attention_outputs = encoder_outputs
        rnn_input = torch.cat([attention_outputs, input], dim=-1)
        output, hidden = self.rnn(rnn_input.unsqueeze(0), hidden.unsqueeze(0))

        assert (output == hidden).all()
        output = output.squeeze(0)
        hidden = hidden.squeeze(0)
        pred = self.proj_out(torch.cat([attention_outputs, output, input], dim=1))
        return pred, hidden

class Model(nn.Module):
    def __init__(self, config):
        super(Model, self).__init__()
        with open('label_graph.g', 'rb') as f:
            label_graph = pickle.load(f)
        self.config = config
        self.label_graph = torch.from_numpy(label_graph).float().to(config.device)
        self.label_embedding = nn.Parameter(torch.randn(config.label_num, config.label_embedding_size, dtype=torch.float32))
        nn.init.xavier_normal_(self.label_embedding.data)

        self.bert = RobertaModel.from_pretrained(config.bert_path)
        for param in self.bert.parameters():
            param.requires_grad = config.finetune_bert

        self.gcn_layers = nn.ModuleList()
        for i in range(config.num_gcn_layer):
            self.gcn_layers.append(GraphConvolution(config.label_embedding_size, config.label_embedding_size))

        # top-down manner Decoder
        self.decoder = Decoder(config.label_embedding_size, config.attn_hidden_size, config.enc_hidden_size, config.dec_hidden_size)
        # bottom-up manner auxilary Decoder
        self.decoder_reverse = Decoder(config.label_embedding_size, config.attn_hidden_size, config.enc_hidden_size,config.dec_hidden_size)
        self.label2context = Label2Context(config.label_embedding_size, config.attn_hidden_size)
        self.fc1_top = nn.Linear(config.dec_hidden_size, config.n_top)
        self.fc1_sec = nn.Linear(config.dec_hidden_size, config.n_sec)
        self.fc1_conn = nn.Linear(config.dec_hidden_size, config.n_conn)
        self.fc2_top = nn.Linear(config.dec_hidden_size, config.n_top)
        self.fc2_sec = nn.Linear(config.dec_hidden_size, config.n_sec)
        self.fc2_conn = nn.Linear(config.dec_hidden_size, config.n_conn)
        self.softmax = nn.Softmax(dim=1)
        self.dropout = nn.Dropout(0.2)

    def forward(self, x, argmask):
        context = x[0]  #
        mask = x[2]
        bert_out = self.bert(context, attention_mask=mask)
        hidden_last, pooled, hidden_all = bert_out.last_hidden_state, bert_out.pooler_output, bert_out.hidden_states
        hidden_cls, encode_out = hidden_last[:, 0, :], hidden_last[:, 1:, :]
        encode_out = self.dropout(encode_out)
        for gcn_layer in self.gcn_layers:
            label_repr = F.relu(gcn_layer(self.label_embedding, self.label_graph))
        bs = hidden_last.shape[0]
        hidden_g = hidden_cls
        hidden = hidden_cls
        # input = torch.FloatTensor(torch.zeros(bs, self.label_embedding.shape[1])).to(self.config.device)
        # input_reverse = torch.FloatTensor(torch.zeros(bs, self.label_embedding.shape[1])).to(self.config.device)
        input = label_repr[0: 4].sum(dim=0, keepdim=True).repeat(bs, 1)
        input_reverse = label_repr[15: 117].sum(dim=0, keepdim=True).repeat(bs, 1)
        hidden_reverse = hidden_cls
        out_top, out_sec, out_conn = 0, 0, 0
        for i in range(3):
            if i == 0:  # top-level prediction
                label2context_out = self.label2context(encode_out, label_repr, [0, 4])
                pred, output = self.decoder(input, hidden.contiguous(), label2context_out)
                hidden = output
                out_top = self.fc1_top(pred)
                t = self.softmax(out_top).unsqueeze(-1).expand(out_top.shape[0], out_top.shape[1], label_repr.shape[1])
                input = (t * label_repr[0:4]).sum(dim=1, keepdim=False)

            if i == 1:  # second-level prediction
                hidden = hidden + hidden_g
                label2context_out = self.label2context(encode_out, label_repr, [4, 15])
                pred, output = self.decoder(input, hidden.contiguous(), label2context_out)
                hidden = output
                out_sec = self.fc1_sec(pred)
                t = self.softmax(out_sec).unsqueeze(-1).expand(out_sec.shape[0], out_sec.shape[1], label_repr.shape[1])
                input = (t * label_repr[4:15]).sum(dim=1, keepdim=False)

            if i == 2:  # conn-level prediction
                hidden = hidden + hidden_g
                label2context_out = self.label2context(encode_out, label_repr, [15, 117])
                pred, output = self.decoder(input, hidden.contiguous(), label2context_out)
                out_conn = self.fc1_conn(pred)
                t = self.softmax(out_conn).unsqueeze(-1).expand(out_conn.shape[0], out_conn.shape[1],
                                                               label_repr.shape[1])
                input = (t * label_repr[15:117]).sum(dim=1, keepdim=False)
        # the bottom-up manner auxilary decoder
        for i in range(3):
            if i == 0:
                hidden_reverse = hidden_reverse.contiguous()
                label2context_out = self.label2context(encode_out, label_repr, [15, 117])
                pred_reverse, output_reverse = self.decoder_reverse(input_reverse, hidden_reverse,label2context_out)
                hidden_reverse = output_reverse
                out_conn_reverse = self.fc2_conn(pred_reverse)
                t = self.softmax(out_conn_reverse).unsqueeze(-1).expand(out_conn_reverse.shape[0], out_conn_reverse.shape[1], label_repr.shape[1])
                input_reverse = (t * label_repr[15:117]).sum(dim=1, keepdim=False)

            if i == 1:
                hidden_reverse = hidden_reverse + hidden_g
                hidden_reverse = hidden_reverse.contiguous()
                label2context_out = self.label2context(encode_out, label_repr, [4, 15])
                pred_reverse, output_reverse = self.decoder_reverse(input_reverse, hidden_reverse, label2context_out)
                hidden_reverse = output_reverse
                out_sec_reverse = self.fc2_sec(pred_reverse)
                t = self.softmax(out_sec_reverse).unsqueeze(-1).expand(out_sec_reverse.shape[0],
                                                                       out_sec_reverse.shape[1], label_repr.shape[1])
                input_reverse = (t * label_repr[4:15]).sum(dim=1, keepdim=False)

            if i == 2:
                hidden_reverse = hidden_reverse + hidden_g
                hidden_reverse = hidden_reverse.contiguous()
                label2context_out = self.label2context(encode_out, label_repr, [0, 4])
                pred_reverse, output_reverse = self.decoder_reverse(input_reverse, hidden_reverse, label2context_out)
                out_top_reverse = self.fc2_top(pred_reverse)
        return out_top, out_sec, out_conn, out_top_reverse, out_sec_reverse, out_conn_reverse


#!/usr/bin/env python
"""This module is executed by the user to start the program."""

import Queue
import logging
import logging.config
import optparse
import json

import sys
sys.dont_write_bytecode = True

import logic
import network
import gui

from utils import handle_except

@handle_except('other')
def main():
    """The main function of the server."""
    # parsing command line argumants
    parser = optparse.OptionParser()
    parser.add_option('-c', '--config', dest='config_file',
                      default='logging.json',
                      help='change the logging configuration file')
    parser.add_option('-p', '--port', dest='port', default='2048', type='int',
                      help='set custom connection port')

    options, args = parser.parse_args()

    # configurate the loggers of the threads
    with open(options.config_file, 'rb') as f:
        config = json.loads(f.read())
        logging.config.dictConfig(config)

    logger = logging.getLogger('other')
    logger.info('main thread started')

    logic_queue = Queue.Queue()
    gui_queue = Queue.Queue()
    network_queue = Queue.Queue()

    network_receiver_thread = network.NetworkReceiverThread(
        network_queue=network_queue,
        logic_queue=logic_queue,
        port=options.port
    )

    network_sender_thread = network.NetworkSenderThread(
        network_queue=network_queue,
        logic_queue=logic_queue,
        port=options.port)

    logic_thread = logic.LogicThread(
        logic_queue=logic_queue,
        gui_queue=gui_queue,
        network_queue=network_queue)

    gui_thread = gui.Gui(
        gui_queue=gui_queue,
        logic_queue=logic_queue)

    network_receiver_thread.start()
    network_sender_thread.start()
    logic_thread.start()
    gui_thread.main()

    logger.info('main thread ended')

if __name__ == '__main__':
    main()


import numpy as np
import pandas as pd

pop = pd.read_csv('../../data/state-population.csv')
areas = pd.read_csv('../../data/state-areas.csv')
abbrevs = pd.read_csv('../../data/state-abbrevs.csv')

pop.head()
areas.head()
abbrevs.head()

merged = pd.merge(pop, abbrevs, how='outer', left_on='state/region', right_on='abbreviation')
merged.drop('abbreviation', 1)
merged.head()


"""
    Faça um programa que tenha uma função chamada ficha(), que receba dois parâmetros opcionais: o nome de um jogador e quantos gols ele marcou.

    O programa deverá ser capaz de mostrar a ficha do jogador, mesmo que algum dado não tenha sido informado corretamente.
"""

def ficha(nome='', gols=''):
    if (nome.strip() == ''):
        nome = '<desconhecido>'
    if (gols.isnumeric()):
        gols = int(gols)
    else:
        gols = 0
    return print(f'O jogador {nome} marcou {gols} gols no Campeonato.')

# Programa Principal
nome = input('Nome do Jogador: ')
gols = input('Número de Gols: ')
ficha(nome, gols)


from workerA import add_nums, get_predictions, get_accuracy

from flask import (
   Flask,
   request,
   jsonify,
   Markup,
   render_template
)

#app = Flask(__name__, template_folder='./templates',static_folder='./static')
app = Flask(__name__)

@app.route("/")
def index():
    return '
Welcome to a Stargazer prediction service - brought to you by group 8
'

@app.route("/accuracy", methods=['POST', 'GET'])
def accuracy():
    if request.method == 'POST':
        r = get_accuracy.delay()
        a = r.get()
        return '
The accuracy is {}
'.format(a)

    return '''<form method="POST">
    <input type="submit">
    </form>'''

@app.route("/predictions", methods=['POST', 'GET'])
def predictions():
    if request.method == 'POST':
        results = get_predictions.delay()
        predictions = results.get()

        results = get_accuracy.delay()
        accuracy = results.get()

        final_results = list(zip(predictions['y'], predictions['predicted']))

        return render_template('result.html', accuracy=accuracy, final_results=final_results)

    return '''<form method="POST">
    <input type="submit">
    </form>'''
if __name__ == '__main__':
    app.run(host = '0.0.0.0',port=5100,debug=True)


from Radnik import meniradnik
from Kupac import menikupac

korisnici=[]

def main():

    unos=input('Da li zelite da se registraciju(moguce samo kao kupac) ili login?')
    if unos=='login':
        titula=-1
        imekorisnika=''

        while titula==-1:
            korisnickoime=input('Korisnicko ime: ')
            lozinka=input('Lozinka: ')

            with open('podaci\Korisnici.txt') as fajl:
                podaci=fajl.readlines()

                for red in podaci:
                    korisnik=red.strip().split('|')
                    korisnici.append(korisnik)

                for red in korisnici:
                    if korisnickoime==red[5] and lozinka==red[6]:
                        titula=red[1]
                        imekorisnika=red[2]

            if titula==-1:
                print('Uneli ste pogresno korisnicno ime ili lozinku.')
                print('Pokusajte ponovo:')
            else:
                print('Login uspesan! Dobro dosao/la ' + imekorisnika)

        if titula=='0':
            meniradnik()
        elif titula=='1':
            menikupac()
        else:
            print('Doslo je do greske. Nepoznata titula.')
    elif unos=='registracija':
        kime=input('Unesite korisnicko ime: ')
        loz=input('unesite loziku:')

if __name__=='__main__':
    main()


import tensorflow.compat.v1 as tf
import numpy as np

tf.compat.v1.disable_v2_behavior()

x = tf.placeholder("float64", [None, 3])
y = tf.placeholder("float64", [None, 1])
W = tf.Variable(np.array([[0.1],[0.2],[0.3]]))
b = tf.Variable(np.array([0.8]))

y_ = tf.matmul(x,W) + b
cost = tf.reduce_mean(tf.reduce_mean((y-y_)*(y-y_), reduction_indices=1))

learning_rate = 1e-2
optim = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

init = tf.initialize_all_variables()

data = np.array([
  [1.0,2.0,3.0],
  [4.0,5.0,6.0],
  [6.0,7.0,8.0]
])

label = []
for i in range(3):
  label.append([0.42*data[i][0] + 0.35*data[i][1] + 0.53*data[i][2] + 5.0])

label = np.array(label)
print(label)

with tf.Session() as sess:
  sess.run(init)
  for i in range(4):
    _, loss = sess.run([optim, cost], feed_dict={x: data, y: label})
    print(loss)


import os

from utils.files_utils import FilesUtils
from utils.images_utils import ImagesUtils

class TestDataset:
    def __init__(self, data_path):
        self._download_url = 'Dummy url, real one requires authentication token.'
        self.dataset_dir = os.path.join(data_path, 'dogs_vs_cats')
        self._train_dir = os.path.join(self.dataset_dir, 'train')
        self._test_dir = os.path.join(self.dataset_dir, 'test1')

    def initialize(self, force_init=False):
        os.makedirs(self.dataset_dir, exist_ok=True)

        downloaded_target_path = os.path.join(self.dataset_dir, 'dogs-vs-cats.zip')
        if not os.path.exists(downloaded_target_path) or force_init:
            FilesUtils.download(self._download_url, downloaded_target_path)

        if not os.path.exists(self.dataset_dir) or force_init:
            FilesUtils.extract(downloaded_target_path)

        if not os.path.exists(self._train_dir):
            FilesUtils.extract(os.path.join(self.dataset_dir, 'train.zip'))

        if not os.path.exists(self._test_dir):
            FilesUtils.extract(os.path.join(self.dataset_dir, 'test1.zip'))

    def get_image(self, image_id):
        image_path = os.path.join(self._train_dir, image_id)
        img = ImagesUtils.convert_to_numpy(image_path)
        return img, 'dog' in image_id

    def get_image_ids(self):
        return os.listdir(self._train_dir)

    def get_full_path(self, image_id):
        return os.path.join(self._train_dir, image_id)


import sys
sys.path.append('../../')

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import xgboost as xgb
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import accuracy_score, f1_score
from sklearn.model_selection import cross_val_score
from sklearn.metrics import make_scorer, classification_report

from utility import general_utility as gu
from utility import featureExtractor as f_extr
from utility import dataProcess as dp
import model_config as mc
import scoreFunc as scoreF
import model_zoo as mz

def load_best_config(configPath):

    f = open(configPath, 'rb')
    config = pickle.load(f)

    return config

def get_stack_model(configPath_dict, stock, days):

    config = {
                'xgb': load_best_config(configPath_dict['xgb'])[stock][days]['model_config'],
                'rf': load_best_config(configPath_dict['rf'])[stock][days]['model_config'],
                'svc': load_best_config(configPath_dict['svc'])[stock][days]['model_config'],

             }

    return mz.stacking_avg_model(config)

configPath = {
                'svc':'../config/20180525/best_config_svc_speicalDate.pkl',
                'xgb':'../config/20180525/best_config_xgb_speicalDate.pkl',
                'rf':'../config/20180525/best_config_rf_speicalDate.pkl'
            }

stock_list =  [
                '0050', '0051',  '0052', '0053',
                '0054', '0055', '0056', '0057',
                '0058', '0059', '006201', '006203',
                '006204', '006208','00690', '00692',
                '00701', '00713'
              ]

stock_list = ['0050']
date_range_normal = [
                        ['20130101','20150601'],
                        ['20150101','20170101'],
                        ['20160101','20180101'],
                        None
                    ]

date_range_special = [['20130101','20180401']]

predict_days  = list(range(5))  #The dow wish model to predict
consider_lagdays = list(range(1,6)) #Contain # lagday information for a training input
feature_list_comb = [
                        ['velocity'],
                        ['ma'],
                        ['ratio'],
                        ['rsi'],
                        ['kdj'],
                        ['macd'],
                        ['ud']
                    ]

config  = mc.model_config('xgb').get
best_config = {}

srcPath = '/home/ubuntu/dataset/etf_prediction/all_feature_data_Nm_1_MinMax_94.pkl'
metaPath = '/home/ubuntu/dataset/etf_prediction/all_meta_data_Nm_1_MinMax_94.pkl'
#srcPath = '../../Data/all_feature_data_Nm_1_MinMax_94.pkl'
#metaPath = '../../Data/all_meta_data_Nm_1_MinMax_94.pkl'
*_,meta = gu.read_metafile(metaPath)

tv_gen = dp.train_validation_generaotr()
f = tv_gen._load_data(srcPath)

for s in stock_list:
    best_config[s] = {}
    for predict_day in predict_days:

        best_config[s][predict_day] = {}
        best_accuracy = 0
        best_test_accuracy = 0

        if s in ['00690', '00692','00701', '00713']:
            date_range = date_range_special
        else:
            date_range = date_range_normal

        for period in date_range:
            for consider_lagday in consider_lagdays:
                for feature_list in feature_list_comb:

                    #***************Get train data******************
                    single_stock = tv_gen._selectData2array(f, [s], period)
                    single_stock, meta_v = f_extr.create_velocity(single_stock, meta)
                    features, label = dp.get_data_from_dow(f , single_stock, meta_v, predict_day, feature_list)

                    feature_concat = []
                    dow = {0:'mon', 1:'tue', 2:'wed', 3:'thu', 4:'fri'}

                    for i in range(consider_lagday):
                        for k in  features[dow[i]]:
                            feature_concat.append( features[dow[i]][k])
                    data_feature = np.concatenate(feature_concat, axis=1)

                    train_val_set_days = {'train': data_feature,
                                          'train_label': label}

                    train_data = train_val_set_days['train']
                    train_label = train_val_set_days['train_label']

                    #***************Get test data******************
                    single_stock_test = tv_gen._selectData2array(f, [s], ['20180401','20180601'])
                    single_stock_test, meta_v = f_extr.create_velocity(single_stock_test, meta)
                    features_test, label_test = dp.get_data_from_dow(f, single_stock_test, meta_v, predict_day, feature_list)

                    feature_concat_test = []
                    for i in range(consider_lagday):
                        for k in  features_test[dow[i]]:
                            feature_concat_test.append(features_test[dow[i]][k])

                    data_feature_test = np.concatenate(feature_concat_test, axis=1)
                    test_val_set_days = {'test': data_feature_test,
                                          'test_label': label_test}

                    test_data = test_val_set_days['test']
                    test_label = test_val_set_days['test_label']

                    #*************************************************

                    model = get_stack_model(configPath, s, predict_day)

                    sample_weight = gu.get_sample_weight(train_label)
                    if config['fit_param']:
                        sample_weight = {'sample_weight':sample_weight}

                    else:
                        sample_weight = {}

                    score = np.mean(cross_val_score(model, train_data, train_label, cv=3,
                                                    n_jobs = 5,
                                                    scoring = scoreF.time_discriminator_score,
                                                    fit_params = sample_weight
                                                    ))

                    normal_score = np.mean(cross_val_score(model, train_data, train_label, cv=3,
                                                    n_jobs = 5,
                                                    fit_params = sample_weight
                                                    ))

                    model.fit(train_data, train_label)
                    y_xgb_train = model.predict(train_data)
                    y_xgb_test = model.predict(test_data)
                    print("Train Accuracy of day {} [DOW]: {}".format(predict_day, accuracy_score(train_label, y_xgb_train)))
                    print("Validation Accuracy  {} [DOW]: {} ".format(predict_day, accuracy_score(test_label, y_xgb_test)))

                    score = accuracy_score(y_xgb_test, test_label)

                    if score > best_accuracy:
                         gsearch2b = GridSearchCV(model, config['param'], n_jobs=5, cv=3,
                                                  scoring= scoreF.time_discriminator_score,
                                                  fit_params = sample_weight)
                         gsearch2b.fit(train_data, train_label)
                         fintue_predict = gsearch2b.predict(test_data)
                         best_config[s][predict_day] = {'train acc': accuracy_score(train_label, y_xgb_train),
                                                        'test_acc': accuracy_score(test_label, y_xgb_test),
                                                        'days': consider_lagday,
                                                        'cross_score':normal_score,
                                                        'features': feature_list,
                                                        'period':period,
                                                        'model_config':gsearch2b.best_params_,
                                                        'fintune_score': gsearch2b.best_score_,
                                                        'fintune_testscore': accuracy_score(test_label, fintue_predict)}
                         best_accuracy = score

#                    if  accuracy_score(y_xgb_test, test_label) > best_test_accuracy:
#
#                         best_config[s]['test_'+str(predict_day)] = {'train acc': accuracy_score(y_xgb_train, train_label),
#                                                        'test_acc': accuracy_score(y_xgb_test, test_label),
#                                                        'days': consider_lagday,
#                                                        'cross_score':normal_score,
#                                                        'features': feature_list,
#                                                        'period':period,
#                                                        'model_config':model.get_params(),
#                                                        'fintune_score': gsearch2b.best_score_}
#                         best_test_accuracy = accuracy_score(y_xgb_test, test_label)

import pickle
with open('../config/best_config_stack_dow.pkl', 'wb') as handle:
    pickle.dump(best_config, handle, protocol=pickle.HIGHEST_PROTOCOL)


from flask import jsonify
from lexi import BACKEND_VERSION

def make_response(status, message, **kwargs):
    response = dict()
    response["backend_version"] = BACKEND_VERSION
    response["status"] = status
    response["message"] = message
    for k, v in kwargs.items():
        response[str(k)] = v
    return jsonify(response)


import pytest
from src.dos_veintisiete import * #2.27

#2.27
@pytest.mark.parametrize(
    "input_x,input_y,expected",
    [
      (4.54,3,13.62)
    ]
)

def test_calculoCoste(input_x,input_y,expected):
  assert calculoCoste(input_x,input_y) == expected

@pytest.mark.parametrize(
    "input_x,input_y,input_z,input_s,expected",
    [
      ("pan",4.54,3,13.62,"pan - 00004.54 - 003 - 00013.62")
    ]
)

def test_cadenaFinal(input_x,input_y,input_z,input_s,expected):
  assert cadenaFinal(input_x,input_y,input_z,input_s) == expected

@pytest.mark.parametrize(
    "input_x,expected",
    [
      ("pan - 00004.54 - 003 - 00013.62","Resultado final: pan - 00004.54 - 003 - 00013.62")
    ]
)

def test_mensajeSalida27(input_x,expected):
     assert mensajeSalida27(input_x) == expected