from abc import ABC
import torch
from pytorch_lightning import LightningModule
from torch import nn
from numerai.model.positional_encoder import PositionalEncoder

class TransformerMLP(LightningModule, ABC):

    def __init__(self, params):
        super().__init__()
        if params.initial_bn:
            self.initial_bn = nn.BatchNorm1d(params.num_features)
        else:
            self.initial_bn = None
        self.pos_encoder = PositionalEncoder(params.num_features)
        encoder_layer = nn.TransformerEncoderLayer(d_model=1, nhead=1,
                                                   dropout=params.dropout)
        self.transformer_encoder = nn.TransformerEncoder(encoder_layer, params.num_enc_layers)
        decoder_layer = nn.TransformerDecoderLayer(d_model=1, nhead=1,
                                                   dropout=params.dropout)
        self.transformer_decoder = nn.TransformerDecoder(decoder_layer, params.num_dec_layers)
        dimensions = params.dimensions
        ae_layers = [nn.Linear(params.num_features, dimensions[0]), nn.BatchNorm1d(dimensions[0]),
                     nn.SiLU(inplace=True)]
        if params.dropout > 0:
            ae_layers.append(nn.Dropout(p=params.dropout))
        ae_layers.append(nn.Linear(dimensions[0], 1 + len(params.aux_target_cols)))
        ae_layers.append(nn.Sigmoid())
        self.ae = nn.Sequential(*ae_layers)
        mlp_layers = [nn.Linear(params.num_features + params.num_features, dimensions[1]),
                      nn.BatchNorm1d(dimensions[1]),
                      nn.SiLU(inplace=True)]
        if params.dropout > 0:
            mlp_layers.append(nn.Dropout(p=params.dropout))
        for i in range(1, len(dimensions) - 1):
            mlp_layers.append(nn.Linear(dimensions[i], dimensions[i + 1]))
            mlp_layers.append(nn.BatchNorm1d(dimensions[i + 1]))
            mlp_layers.append(nn.SiLU(inplace=True))
            if params.dropout > 0:
                mlp_layers.append(nn.Dropout(p=params.dropout))
        mlp_layers.append(nn.Linear(dimensions[-1], 1 + len(params.aux_target_cols)))
        mlp_layers.append(nn.Sigmoid())
        self.mlp = nn.Sequential(*mlp_layers)

    def forward(self, x):
        if self.initial_bn is not None:
            x = self.initial_bn(x)
        src = x.unsqueeze(2)
        src_pos = self.pos_encoder(src)
        tgt_pos = src_pos
        encoded = self.transformer_encoder(src_pos)
        decoded = self.transformer_decoder(tgt_pos, src_pos)
        decoded = decoded.squeeze()
        ae_out = self.ae(decoded)
        src_pos = src_pos.squeeze()
        encoded = encoded.squeeze()
        mlp_out = self.mlp(torch.cat((src_pos, encoded), dim=1).to(self.device))
        return decoded, ae_out, mlp_out


#https://www.acmicpc.net/problem/6118
from collections import deque, defaultdict

def bfs(v):
  q = deque()
  # 노드 번호와 거리 큐에 삽입
  q.append((v,0))
  # 1번 노드 방문 기록 표시
  visited[v] = 1

  while q:
    x, index = q.popleft()

    for u in maps[x]:
        # 방문하지 않았다면
      if visited[u] == 0:
        # 거리 하나 증가
        visited[u] = index+1
        # 큐에 삽입
        q.append((u, index+1))

# 1번 노드로부터 모든 노드까지 최단 거리 구하기
n, m = map(int,input().split())

maps = defaultdict(list)

for _ in range(m):
  a,b = map(int,input().split())

  maps[a].append(b)
  maps[b].append(a)

visited = [0] * (n+1)
bfs(1)

# 가장 멀리 있는 노드까지의 거리
answer = max(visited)

# 가장 멀리 있는 노드 중 가장 작은 노드
for i in range(2,n+1):
  if visited[i] == answer:
    print(i,end =" ")
    break

# 그 헛간까지의 거리
print(answer, end = " ")

# 그 헛간과 같은 거리를 갖는 헛간의 개수
print(visited[2:].count(answer))


import allure
import jsonschema
from allure_commons._allure import step
from allure_commons.types import Severity

from tests.conftest import post_new_user_params, reqres_api
from utils import load_schema

@allure.title('POST user: Status code is 201')
@allure.label('owner', 'AngPawl')
@allure.tag('smoke tests')
@allure.severity(Severity.CRITICAL)
def test_status_code_is_ok():
    response = reqres_api(url='/users', method='post', json=post_new_user_params)

    with step('Status code is 201'):
        assert (
            response.status_code == 201
        ), f"Status code {response.status_code} is incorrect"

@allure.title('POST user: Response schema is valid')
@allure.label('owner', 'AngPawl')
@allure.tag('smoke tests')
@allure.severity(Severity.CRITICAL)
def test_schema_is_valid():
    schema = load_schema('reqres', 'post_user.json')

    response = reqres_api(url='/users', method='post', json=post_new_user_params)

    with step('Response schema is valid'):
        jsonschema.validate(response.json(), schema)

@allure.title('POST user: Response data contains correct values')
@allure.label('owner', 'AngPawl')
@allure.tag('smoke tests')
@allure.severity(Severity.CRITICAL)
def test_response_data_is_valid():
    response = reqres_api(url='/users', method='post', json=post_new_user_params)

    with step('Response data contains correct values'):
        assert (
            response.json()['name'] == post_new_user_params['name']
        ), f"Response data contains incorrect value: {response.json()['name']}"
        assert (
            response.json()['job'] == post_new_user_params['job']
        ), f"Response data contains incorrect value: {response.json()['job']}"


import os
import json
import math
import random
import numpy as np
import matplotlib.pyplot as plt
from collections import namedtuple, deque
from itertools import count

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.distributions.normal import Normal

import gym
from gym import spaces
import pygame

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

"""
Used Sources:
https://www.gymlibrary.dev/content/environment_creation/
https://github.com/Farama-Foundation/gym-examples/blob/main/gym_examples/envs/grid_world.py
#https://github.com/philtabor/Youtube-Code-Repository/tree/master/ReinforcementLearning/PolicyGradient/SAC
"""

class GridWorldEnv(gym.Env):
    metadata = {"render_modes": ["human", "rgb_array"], "render_fps": 4}

    def __init__(self, render_mode=None, size=5, reward_parameters=None, num_obstacles=5):
        self.size = size  # The size of the square grid
        self.window_size = 512  # The size of the PyGame window
        self.reward_parameters = reward_parameters
        self.num_obstacles = num_obstacles

        self._agent_location = None
        self._target_location = None
        self._obstacle_locations = None
        # Observations are dictionaries with the agent's and the target's location.
        # Each location is encoded as an element of {0, ..., `size`}^2, i.e. MultiDiscrete([size, size]).
        elements = {"agent": spaces.Box(0, size - 1, shape=(2,), dtype=int),
                    "target": spaces.Box(0, size - 1, shape=(2,), dtype=int)}
        for idx_obstacle in range(self.num_obstacles):
            elements.update({"obstacle_{0}".format(idx_obstacle): spaces.Box(0, size - 1, shape=(2,), dtype=int)})
        self.observation_space = spaces.Dict(elements)

        # TODO action space should be continuous and bounded in [-3, 3]
        self.action_space = spaces.Discrete(4) # Continuous 3 see gym examlpes
        #Box(low=np.array([-1.0, -2.0]), high=np.array([2.0, 4.0]), dtype=np.float32) - Box(3,) x,y velocity
        #no polar coord as its already encoded

        """
        The following dictionary maps abstract actions from `self.action_space` to
        the direction we will walk in if that action is taken.
        I.e. 0 corresponds to "right", 1 to "up" etc.
        """
        self._action_to_direction = {
            # TODO: a normalized direction vector and a scalar amount of velocity [-1,1]
            # if time, dynamics
            0: np.array([1, 0]),
            1: np.array([0, 1]),
            2: np.array([-1, 0]),
            3: np.array([0, -1]),
        }

        assert render_mode is None or render_mode in self.metadata["render_modes"]
        self.render_mode = render_mode

        """
        If human-rendering is used, `self.window` will be a reference
        to the window that we draw to. `self.clock` will be a clock that is used
        to ensure that the environment is rendered at the correct framerate in
        human-mode. They will remain `None` until human-mode is used for the
        first time.
        """
        self.window = None
        self.clock = None

    def _get_obs(self):
        elements = {"agent": self._agent_location, "target": self._target_location}
        for idx_obstacle in range(self.num_obstacles):
            elements.update({"obstacle_{0}".format(idx_obstacle): self._obstacle_locations[str(idx_obstacle)]})
        return elements

    def _get_info(self):
        distances = {"distance_to_target":
                         np.linalg.norm(self._agent_location - self._target_location, ord=1)}
        # ord=1: max(sum(abs(x), axis=0))
        for idx_obstacle in range(self.num_obstacles):
            distances.update({"distance_to_obstacle_{0}".format(idx_obstacle):
                                  np.linalg.norm(self._agent_location - self._obstacle_locations[str(idx_obstacle)],
                                                 ord=1)})
        return distances

    def reset(self, seed=None, options=None):
        # We need the following line to seed self.np_random
        super().reset(seed=seed)

        # Choose the agent's location uniformly at random
        self._agent_location = self.np_random.integers(0, self.size, size=2, dtype=int)

        # We will sample the target's location randomly until it does not coincide with the agent's location
        self._target_location = self._agent_location
        while np.array_equal(self._target_location, self._agent_location):
            self._target_location = self.np_random.integers(
                0, self.size, size=2, dtype=int
            )

        # We will sample the obstacle's location randomly until it does not coincide with the agent's/target's location
        self._obstacle_locations = {}
        for idx_obstacle in range(self.num_obstacles):
            self._obstacle_locations.update({"{0}".format(idx_obstacle): self._agent_location})
            if idx_obstacle == 0:
                while np.array_equal(self._obstacle_locations[str(idx_obstacle)], self._agent_location) \
                        or np.array_equal(self._obstacle_locations[str(idx_obstacle)], self._target_location):
                    self._obstacle_locations[str(idx_obstacle)] = self.np_random.integers(
                        0, self.size, size=2, dtype=int
                    )
                continue
            while np.array_equal(self._obstacle_locations[str(idx_obstacle)], self._agent_location) \
                    or np.array_equal(self._obstacle_locations[str(idx_obstacle)], self._target_location) \
                    or np.array_equal(self._obstacle_locations[str(idx_obstacle)],
                                      self._obstacle_locations[str(idx_obstacle - 1)]):
                self._obstacle_locations[str(idx_obstacle)] = self.np_random.integers(
                    0, self.size, size=2, dtype=int
                )
            # TODO: check all obstacles pairwise for every additional obstacle
        observation = self._get_obs()
        info = self._get_info()

        if self.render_mode == "human":
            self._render_frame()

        return observation, info

    def step(self, action_step):
        global penalty_distance_collision
        action_step = np.round(
            self.reward_parameters[
                "action_step_scaling"] * action_step)  # scale action to e.g. [-2, 2] -> reach is 5x5 grid
        previous_position = self._agent_location
        self._agent_location = self._agent_location + action_step
        self._max_distance = math.sqrt(2) * self.size

        ### COLLISION SPARSE REWARD ###
        # Check for obstacle collision
        terminated = False
        for idx_obstacle in range(self.num_obstacles):
            terminated = np.array_equal(self._agent_location, self._obstacle_locations[str(idx_obstacle)])
            if terminated:
                break
        # Check if the agent is out of bounds
        if self._agent_location[0] < 0 or self._agent_location[1] < 0 or \
                self._agent_location[0] > self.size - 1 or self._agent_location[1] > self.size - 1 or \
                terminated:
            terminated = True  # agent is out of bounds but did not collide with obstacle

            reward = self.reward_parameters['collision_value']  # collision with wall or obstacles

            observation = self._get_obs()
            info = self._get_info()
            return observation, reward, terminated, False, info

        ### TARGET SPARSE REWARD ###
        # An episode is done iff the agent has reached the target
        terminated = np.array_equal(self._agent_location, self._target_location)  # target reached
        if terminated:
            reward = self.reward_parameters['target_value']  # sparse target reward

        ### OTHER REWARDS ###
        else:
            ### Distances
            # Distance to target

            previous_distance_to_target = math.sqrt((previous_position[0] - self._target_location[0]) ** 2
                                                    + (previous_position[1] - self._target_location[1]) ** 2)

            distance_to_target = math.sqrt((self._agent_location[0] - self._target_location[0]) ** 2
                                           + (self._agent_location[1] - self._target_location[1]) ** 2)

            # Distances to obstacles
            previous_distances_to_obstacles = np.array([])
            distances_to_obstacles = np.array([])
            for idx_obstacle in self._obstacle_locations:
                previous_distance_to_obstacle = math.sqrt(
                    (previous_position[0] - self._obstacle_locations[str(idx_obstacle)][0]) ** 2
                    + (previous_position[1] - self._obstacle_locations[str(idx_obstacle)][1]) ** 2)
                distance_to_obstacle = math.sqrt(
                    (self._agent_location[0] - self._obstacle_locations[str(idx_obstacle)][0]) ** 2
                    + (self._agent_location[1] - self._obstacle_locations[str(idx_obstacle)][1]) ** 2)
                np.append(previous_distances_to_obstacles, previous_distance_to_obstacle)
                np.append(distances_to_obstacles, distance_to_obstacle)

            # Distance to the closest wall
            previous_distance_to_wall = np.amin(np.vstack((previous_position + 1, self.size - previous_position)))
            # get the distance to the closest wall in the previous step
            distance_to_wall = np.amin(np.vstack((self._agent_location + 1, self.size - self._agent_location)))
            # get the distance to the closest wall in the current step # TODO: check if this is correct (@Mo)

            ### Distance differences
            # Difference to target
            diff_distance_to_target = np.abs(previous_distance_to_target - distance_to_target)

            # Difference to obstacles TODO: make this a parameter, is this a good idea?
            distances_to_obstacles[distances_to_obstacles > 0.3 * self.size] = 0  # set distances to obstacles > 5 to 0
            previous_distances_to_obstacles[distances_to_obstacles == 0] = 0
            # set previous distances to obstacles 0 with the same indices as distances to obstacles
            diff_obstacle_distances = np.abs(
                previous_distances_to_obstacles - distances_to_obstacles)  # TODO: make use of this

            # Difference to wall
            diff_distance_to_wall = np.abs(distance_to_wall - previous_distance_to_wall)  # TODO: make use of this

            reward = 0

            ### DENSE REWARDS ###
            # Reward for avoiding obstacles
            if self.reward_parameters['obstacle_avoidance']:
                min_collision_distance = np.min(np.append(distances_to_obstacles, [distance_to_wall]))
                penalty_distance_collision = np.max(np.array([1.0 - min_collision_distance / self._max_distance, 0.0]))
                reward += self.reward_parameters['obstacle_distance_weight'] * penalty_distance_collision

            if self.reward_parameters['target_seeking']:
                reward += self.reward_parameters['target_distance_weight'] * distance_to_target / self._max_distance

            ### SUB-SPARSE REWARDS ###
            # Distance checkpoint rewards
            if self.reward_parameters['checkpoints']:
                checkpoint_reward_given = [False] * (reward_parameters['checkpoint_number'] + 1)
                for i in np.invert(range(1, reward_parameters['checkpoint_number'] + 1)):
                    if (distance_to_target < i * reward_parameters['checkpoint_distance_proportion'] * self.size) \
                            and not checkpoint_reward_given[i]:
                        checkpoint_reward_given[i] = True
                        reward += self.reward_parameters['checkpoint_value']  # checkpoint reward

            # Time penalty
            if self.reward_parameters['time']:
                reward += self.reward_parameters['time_penalty']  # time penalty

            # last_x_positions = self._agent_location_history[-self.reward_parameters['history_size']:]
            # # Waiting reward # TODO: add step history to check if the agent is waiting
            # if self.reward_parameters['waiting']:
            #     if last_x_positions.count(last_x_positions[0]) == len(last_x_positions):  # Checks if all positions are equal
            #         reward += self.reward_parameters['waiting_value']
            #
            # # Consistency reward # TODO: add step history to check if the agent is waiting
            # if self.reward_parameters['consistency']:
            #     last_x_steps = []
            #     for i in np.invert((range(1, self.reward_parameters['consistency_step_number'] + 1))):  # csn,...,1
            #         last_x_steps.append(last_x_positions[i] - last_x_positions[i - 1])
            #         if last_x_steps.count(last_x_steps[0]) == len(last_x_steps):  # Checks if all directions are equal
            #             reward += self.reward_parameters['consistency_value']

        observation = self._get_obs()
        info = self._get_info()

        if self.render_mode == "human":
            self._render_frame()

        return observation, reward, terminated, False, info

    def render(self):
        if self.render_mode == "rgb_array":
            return self._render_frame()

    def _render_frame(self):
        if self.window is None and self.render_mode == "human":
            pygame.init()
            pygame.display.init()
            self.window = pygame.display.set_mode((self.window_size, self.window_size))
        if self.clock is None and self.render_mode == "human":
            self.clock = pygame.time.Clock()

        canvas = pygame.Surface((self.window_size, self.window_size))
        canvas.fill((255, 255, 255))
        pix_square_size = (
                self.window_size / self.size
        )  # The size of a single grid square in pixels

        # First we draw the target
        pygame.draw.rect(
            canvas,
            (255, 0, 0),
            pygame.Rect(
                pix_square_size * self._target_location,
                (pix_square_size, pix_square_size),
            ),
        )
        # Now we draw the agent
        pygame.draw.circle(
            canvas,
            (0, 0, 255),
            (self._agent_location + 0.5) * pix_square_size,
            pix_square_size / 3,
        )
        # Now we draw the obstacles
        for idx_obstacle in range(self.num_obstacles):
            pygame.draw.rect(
                canvas,
                (0, 0, 0),
                pygame.Rect(
                    pix_square_size * self._obstacle_locations[str(idx_obstacle)],
                    (pix_square_size, pix_square_size),
                ),
            )

        # Finally, add some gridlines
        for x in range(self.size + 1):
            pygame.draw.line(
                canvas,
                0,
                (0, pix_square_size * x),
                (self.window_size, pix_square_size * x),
                width=3,
            )
            pygame.draw.line(
                canvas,
                0,
                (pix_square_size * x, 0),
                (pix_square_size * x, self.window_size),
                width=3,
            )

        if self.render_mode == "human":
            # The following line copies our drawings from `canvas` to the visible window
            self.window.blit(canvas, canvas.get_rect())
            pygame.event.pump()
            pygame.display.update()

            # We need to ensure that human-rendering occurs at the predefined framerate.
            # The following line will automatically add a delay to keep the framerate stable.
            self.clock.tick(self.metadata["render_fps"])
        else:  # rgb_array
            return np.transpose(
                np.array(pygame.surfarray.pixels3d(canvas)), axes=(1, 0, 2)
            )

    def close(self):
        if self.window is not None:
            pygame.display.quit()
            pygame.quit()

Transition = namedtuple('Transition', ('state', 'action', 'next_state', 'reward'))

class ReplayMemory(object):  # a memory buffer to store transitions

    def __init__(self, capacity):
        self.memory = deque([], maxlen=capacity)

    def push(self, *args):
        """Save a transition"""
        self.memory.append(Transition(*args))

    def sample(self, batch_size):
        return random.sample(self.memory, batch_size)

    def sample_sequence(self, batch_size):
        return random.sample(self.memory, batch_size)

    def __len__(self):
        return len(self.memory)

class CriticNetwork(nn.Module):
    def __init__(self, beta, input_dims, n_actions, fc1_dims=128, fc2_dims=64,
                 name='critic', chkpt_dir='tmp/sac'):
        super(CriticNetwork, self).__init__()
        self.input_dims = input_dims
        self.fc1_dims = fc1_dims
        self.fc2_dims = fc2_dims
        self.n_actions = n_actions
        self.name = name
        self.checkpoint_dir = chkpt_dir
        self.checkpoint_file = os.path.join(self.checkpoint_dir, name + '_sac')

        self.fc1 = nn.Linear(self.input_dims + n_actions, self.fc1_dims)
        self.fc2 = nn.Linear(self.fc1_dims, self.fc2_dims)
        self.q = nn.Linear(self.fc2_dims, 1)

        self.optimizer = optim.Adam(self.parameters(), lr=beta)
        self.device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

        self.to(self.device)

    def forward(self, state, action):
        action_value = self.fc1(torch.cat([state, action], dim=1))
        action_value = F.relu(action_value)
        action_value = self.fc2(action_value)
        action_value = F.relu(action_value)

        q = self.q(action_value)

        return q

    def save_checkpoint(self):
        torch.save(self.state_dict(), self.checkpoint_file)

    def load_checkpoint(self):
        self.load_state_dict(torch.load(self.checkpoint_file))

class ValueNetwork(nn.Module):
    def __init__(self, beta, input_dims, fc1_dims=128, fc2_dims=64,
                 name='value', chkpt_dir='tmp/sac'):
        super(ValueNetwork, self).__init__()
        self.input_dims = input_dims
        self.fc1_dims = fc1_dims
        self.fc2_dims = fc2_dims
        self.name = name
        self.checkpoint_dir = chkpt_dir
        self.checkpoint_file = os.path.join(self.checkpoint_dir, name + '_sac')

        self.fc1 = nn.Linear(self.input_dims, self.fc1_dims)
        self.fc2 = nn.Linear(self.fc1_dims, fc2_dims)
        self.v = nn.Linear(self.fc2_dims, 1)

        self.optimizer = optim.Adam(self.parameters(), lr=beta)
        self.device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

        self.to(self.device)

    def forward(self, state):
        state_value = self.fc1(state)
        state_value = F.relu(state_value)
        state_value = self.fc2(state_value)
        state_value = F.relu(state_value)

        v = self.v(state_value)

        return v

    def save_checkpoint(self):
        torch.save(self.state_dict(), self.checkpoint_file)

    def load_checkpoint(self):
        self.load_state_dict(torch.load(self.checkpoint_file))

class ActorNetwork(nn.Module):
    def __init__(self, alpha, input_dims, max_action, fc1_dims=128,
                 fc2_dims=64, n_actions=2, name='actor', chkpt_dir='tmp/sac'):
        super(ActorNetwork, self).__init__()
        self.input_dims = input_dims
        self.fc1_dims = fc1_dims
        self.fc2_dims = fc2_dims
        self.n_actions = n_actions
        self.name = name
        self.checkpoint_dir = chkpt_dir
        self.checkpoint_file = os.path.join(self.checkpoint_dir, name + '_sac')
        self.max_action = max_action
        self.reparam_noise = 1e-6

        self.fc1 = nn.Linear(self.input_dims, self.fc1_dims)
        self.fc2 = nn.Linear(self.fc1_dims, self.fc2_dims)
        self.mu = nn.Linear(self.fc2_dims, self.n_actions)
        self.sigma = nn.Linear(self.fc2_dims, self.n_actions)

        self.optimizer = optim.Adam(self.parameters(), lr=alpha)
        self.device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

        self.to(self.device)

    def forward(self, state):
        prob = self.fc1(state)
        prob = F.relu(prob)
        prob = self.fc2(prob)
        prob = F.relu(prob)

        mu = self.mu(prob)
        sigma = self.sigma(prob)  # log_std

        sigma = torch.clamp(sigma, min=self.reparam_noise, max=0.5)  # TODO: decaying sigma

        return mu, sigma

    def sample_normal(self, state, reparametrize=True):
        mu, sigma = self.forward(state)
        probabilities = Normal(mu, sigma)

        if reparametrize:
            actions = probabilities.rsample()
        else:
            actions = probabilities.sample()

        action_sample = torch.tanh(actions) * torch.tensor(self.max_action).to(self.device)
        log_probs = probabilities.log_prob(actions)
        log_probs -= torch.log(1 - action_sample.pow(2) + self.reparam_noise)  # lower bound for probabilities
        log_probs = log_probs.sum(1, keepdim=True)

        return action_sample, log_probs

    def save_checkpoint(self):
        torch.save(self.state_dict(), self.checkpoint_file)

    def load_checkpoint(self):
        self.load_state_dict(torch.load(self.checkpoint_file))

alpha_entropy = 0.5

def optimize_model():
    if len(memory) < hyper_parameters["batch_size"]:  # if memory is not full enough to start training, return
        return
    transitions = memory.sample(hyper_parameters["batch_size"])  # sample a batch of transitions from memory
    # Transpose the batch (see https://stackoverflow.com/a/19343/3343043 for
    # detailed explanation). This converts batch-array of Transitions
    # to Transition of batch-arrays.
    batch = Transition(*zip(*transitions))

    # Compute a mask of non-final states and concatenate the batch elements
    # (a final state would've been the one after which simulation ended)
    non_final_mask = torch.tensor(tuple(map(lambda s: s is not None,
                                            batch.next_state)), device=device, dtype=torch.bool)
    non_final_next_states = torch.cat([s for s in batch.next_state
                                       if s is not None])
    state_batch = torch.cat(batch.state)
    action_batch = torch.cat(batch.action)
    reward_batch = torch.cat(batch.reward)

    value = valueNet(state_batch).view(-1)  # infer size of batch
    value_ = torch.zeros(hyper_parameters["batch_size"], device=device)
    value_[non_final_mask] = target_valueNet(non_final_next_states).view(-1)

    actions, log_probs = actorNet.sample_normal(state_batch, reparametrize=False)
    log_probs = log_probs.view(-1)
    q1_new_policy = criticNet_1.forward(state_batch, actions)
    q2_new_policy = criticNet_2.forward(state_batch, actions)
    critic_value = torch.min(q1_new_policy, q2_new_policy)
    critic_value = critic_value.view(-1)

    valueNet.optimizer.zero_grad()
    value_target = critic_value - alpha_entropy * log_probs
    value_loss = 0.5 * F.mse_loss(value, value_target)
    value_loss.backward(retain_graph=True)
    valueNet.optimizer.step()

    actions, log_probs = actorNet.sample_normal(state_batch, reparametrize=True)
    log_probs = log_probs.view(-1)
    q1_new_policy = criticNet_1.forward(state_batch, actions)
    q2_new_policy = criticNet_2.forward(state_batch, actions)
    critic_value = torch.min(q1_new_policy, q2_new_policy)
    critic_value = critic_value.view(-1)

    actor_loss = alpha_entropy * log_probs - critic_value
    actor_loss = torch.mean(actor_loss)
    print(actor_loss)
    actorNet.optimizer.zero_grad()
    actor_loss.backward(retain_graph=True)
    actorNet.optimizer.step()

    criticNet_1.optimizer.zero_grad()
    criticNet_2.optimizer.zero_grad()
    q_hat = reward_batch + hyper_parameters["gamma"] * value_
    q1_old_policy = criticNet_1.forward(state_batch, action_batch).view(-1)
    q2_old_policy = criticNet_2.forward(state_batch, action_batch).view(-1)
    critic_1_loss = 0.5 * F.mse_loss(q1_old_policy, q_hat)  # line 13 in s.u. pseudocode
    critic_2_loss = 0.5 * F.mse_loss(q2_old_policy, q_hat)

    critic_loss = critic_1_loss + critic_2_loss
    critic_loss.backward()
    criticNet_1.optimizer.step()  # line 13 in s.u. pseudocode
    criticNet_2.optimizer.step()

# initialize hyperparameters

input_dims = 6  # original position of actor, obstacle and target position
BATCH_SIZE = 512
GAMMA = 0.999  # discount factor
TARGET_UPDATE = 10  # update target network every 10 episodes
alpha = 0.0003  # learning rate for actor
beta = 0.0003  # learning rate for critic
tau = 0.005  # target network soft update parameter (parameters = tau*parameters + (1-tau)*new_parameters)

reward_paramaters = {'action_step_scaling': 1,

                     'target_value': 10,
                     'collision_value': 50,
                     'time_value': 0.0,

                     'distance_weight': 0.0,
                     'obstacle_distance_weight': 0.0}
# TODO: reward function method (in the step def in env)

env = GridWorldEnv(render_mode=None, size=10, reward_parameters=reward_paramaters)

# initialize NN
n_actions = 2  # velocity in 2 directions
actorNet = ActorNetwork(alpha, input_dims, n_actions=n_actions,
                        name='actor', max_action=[1, 1])  # TODO max_action value and min_action value
criticNet_1 = CriticNetwork(beta, input_dims, n_actions=n_actions,
                            name='critic_1')
criticNet_2 = CriticNetwork(beta, input_dims, n_actions=n_actions,
                            name='critic_2')
valueNet = ValueNetwork(beta, input_dims, name='value')
target_valueNet = ValueNetwork(beta, input_dims, name='target_value')

memory = ReplayMemory(10000)  # replay buffer size

steps_done = 0

def select_action(state):
    # state = torch.Tensor([state]).to(actorNet.device)
    actions, _ = actorNet.sample_normal(state, reparametrize=False)

    return actions.cpu().detach().numpy()[0]

import A_star.algorithm

def select_action_A_star(state):
    size = env.size
    grid = np.zeros((size, size))
    grid[state[2], state[3]] = 1
    # Start position
    StartNode = (state[0], state[1])
    # Goal position
    EndNode = (state[4], state[5])
    path = A_star.algorithm.algorithm(grid, StartNode, EndNode)
    if path == None:
        print("error: doesn't find a path")
        return None
    path = np.array(path)
    actions = np.zeros(((len(path) - 1), 2))
    for i in range(len(path) - 1):
        actions[i, :] = path[i + 1] - path[i]
    return actions

episode_durations = []

def plot_durations():
    plt.figure(1)
    plt.clf()
    durations_t = torch.tensor(episode_durations, dtype=torch.float)
    plt.title('Training...')
    plt.xlabel('Episode')
    plt.ylabel('Duration')
    plt.plot(durations_t.numpy())
    # Take X episode averages and plot them too
    avg_every_X_episodes = 25
    if len(durations_t) >= avg_every_X_episodes:
        means = durations_t.unfold(0, avg_every_X_episodes, 1).mean(1).view(-1)
        means = torch.cat((torch.zeros(avg_every_X_episodes - 1), means))
        plt.plot(means.numpy())

    plt.pause(0.001)  # pause a bit so that plots are updated

num_episodes = 500
for i_episode in range(num_episodes):
    # Initialize the environment and state
    env.reset()
    obs = env._get_obs()
    state_np = np.array([obs["agent"], obs["obstacle"], obs["target"]])
    state_np = state_np.reshape(-1)
    state = torch.tensor(state_np, dtype=torch.float, device=device)
    state = state.view(1, -1)
    actions = select_action_A_star(state_np)
    if actions.all() == None:
        print("error: doesn't find a path")
        continue
    t = 0
    for action in actions:
        t += 1
        action = action / reward_paramaters['action_step_scaling']
        _, reward, done, _, _ = env.step(action)
        reward = torch.tensor([reward], dtype=torch.float, device=device)
        obs = env._get_obs()
        if not done:
            next_state_ = np.array([obs["agent"], obs["obstacle"], obs["target"]])
            next_state_ = next_state_.reshape(-1)
            next_state = torch.tensor(np.array([obs["agent"], obs["obstacle"], obs["target"]]), dtype=torch.float,
                                      device=device)
            next_state = next_state.view(1, -1)
        else:
            next_state_ = None
            next_state = None

        # Store the transition in memory
        action_torch = torch.tensor(np.array([action]), dtype=torch.float).to(actorNet.device)
        memory.push(state, action_torch, next_state, reward)

        # Move to the next state
        state_np = next_state_
        state = next_state

        # Perform one step of the optimization (on the policy network)
        optimize_model()
        if done:
            episode_durations.append(t + 1)
            plot_durations()
            break
    # Update the target network, using tau
    if t != len(actions):
        print("error: actual step is not equal to precalculated steps")
    target_value_params = target_valueNet.named_parameters()
    value_params = valueNet.named_parameters()

    target_value_state_dict = dict(target_value_params)
    value_state_dict = dict(value_params)

    for name in value_state_dict:
        value_state_dict[name] = tau * value_state_dict[name].clone() + \
                                 (1 - tau) * target_value_state_dict[name].clone()
    target_valueNet.load_state_dict(value_state_dict)

print('Pretrain complete')

num_episodes = 250
for i_episode in range(num_episodes):

    # Initialize the environment and state
    env.reset()
    obs = env._get_obs()

    obs_values = [obs["agent"], obs["target"]]
    for idx_obstacle in range(num_obstacles):
        obs_values.append(obs["obstacle_{0}".format(idx_obstacle)])
    state = torch.tensor(np.array(obs_values), dtype=torch.float, device=device)

    state = state.view(1, -1)
    for t in count():
        # Select and perform an action
        action = select_action(state)
        _, reward, done, _, _ = env.step(action)
        reward = torch.tensor([reward], dtype=torch.float, device=device)

        # Observe new state
        obs = env._get_obs()
        if not done:
            obs_values = [obs["agent"], obs["target"]]
            for idx_obstacle in range(num_obstacles):
                obs_values.append(obs["obstacle_{0}".format(idx_obstacle)])
            next_state = torch.tensor(np.array(obs_values), dtype=torch.float, device=device)

            next_state = next_state.view(1, -1)
        else:
            next_state = None

        # Store the transition in memory
        action = np.array([action])
        action = torch.tensor(action, dtype=torch.float).to(actorNet.device)
        memory.push(state, action, next_state, reward)

        # Move to the next state
        state = next_state

        # Perform one step of the optimization (on the policy network)
        optimize_model()
        if done:
            episode_durations.append(t + 1)
            plot_durations()
            break
    # Update the target network, using tau
    target_value_params = target_valueNet.named_parameters()
    value_params = valueNet.named_parameters()

    target_value_state_dict = dict(target_value_params)
    value_state_dict = dict(value_params)

    for name in value_state_dict:
        value_state_dict[name] = hyper_parameters["tau"] * value_state_dict[name].clone() + \
                                 (1 - hyper_parameters["tau"]) * target_value_state_dict[name].clone()
    target_valueNet.load_state_dict(value_state_dict)

print('Complete')

env.render_mode = "human"

# env=GridWorldEnv(render_mode="human")
i = 0
while True:  # run plot for 3 episodes to see what it learned
    i += 1
    env.reset()
    obs = env._get_obs()

    obs_values = [obs["agent"], obs["target"]]
    for idx_obstacle in range(num_obstacles):
        obs_values.append(obs["obstacle_{0}".format(idx_obstacle)])
    state = torch.tensor(np.array(obs_values), dtype=torch.float, device=device)

    state = state.view(1, -1)
    for t in count():
        # Select and perform an action
        action = select_action(state)
        _, reward, done, _, _ = env.step(action)

        action_ = torch.tensor(action, dtype=torch.float, device=device)
        action_ = action_.view(1, 2)
        mu, sigma = actorNet(state)
        print(actorNet(state))
        print(criticNet_1(state, action_))
        print(criticNet_2(state, action_))
        print(target_valueNet(state))

        reward = torch.tensor([reward], device=device)
        env._render_frame()
        # Observe new state
        obs = env._get_obs()
        if not done:
            obs_values = [obs["agent"], obs["target"]]
            for idx_obstacle in range(num_obstacles):
                obs_values.append(obs["obstacle_{0}".format(idx_obstacle)])
            next_state = torch.tensor(np.array(obs_values), dtype=torch.float, device=device)

            next_state = next_state.view(1, -1)
        else:
            next_state = None

        # Store the transition in memory
        memory.push(state, action, next_state, reward)

        # Move to the next state
        state = next_state
        if done:
            break

# torch.save(actorNet.state_dict(), "model/actor.pt")
# torch.save(criticNet_1.state_dict(), "model/criticNet_1.pt")
# torch.save(criticNet_2.state_dict(), "model/criticNet_2.pt")
# torch.save(target_valueNet.state_dict(), "model/target_valueNet.pt")


# Kasim Terzic (kt54) Feb 2018

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from Lecture04.l04_utils import *

# Load the data from the space-separated txt file.
# This will create a 2D numpy array
# data = np.loadtxt('l04-data.txt')
data = np.loadtxt('/Users/cheetah/Sites/CS5014-Example/Lecture04/l01-data.txt')
factor = np.max(data)

# Extract column 2 (X) and 3 (Y). Add a vector of ones as X_0
x = data[:, 1] / factor
y = data[:, 2] / factor
x = np.c_[np.ones_like(x), x]

# Pick some parameters for our model
theta_start = np.array([0, 0])

theta_new, loss = gradientDescent(x, y, 0.1, theta_start, 1e-8)
print(theta_new, loss)

print(meanSquaredErrorLoss(y, f(x, theta_start)))
plotModel(x, y, f(x, theta_start), title='Random parameters')

print(meanSquaredErrorLoss(y, f(x, theta_new)))
plotModel(x, y, f(x, theta_new), title='After gradient descent')

plotLossFunction(x, y, title='Loss function')
plt.savefig('l04-plot.png')
plt.show()


"""Build Difference Tree Module."""

from collections import OrderedDict

ADDED, DELETED, NESTED = 'added', 'deleted', 'nested'
UNMODIFIED, CHANGED = 'unmodified', 'changed'

def get_ordered_joint_keys(dict1, dict2):
    """Function compares 2 dictionaries and returns joint keys (keys list may
    be sorted or unsorted)

    Args:
        dict1 ([dict]): first dictionary
        dict2 ([dict]): second dictionary

    Returns:
        [list]: if both comparable dictionaries are not empty and not equal,
                function returns list of joint keys sorted alphabetically.
                In case when one of the dictionary is empty or both of them
                are equal, function returns list list of keys "as is"
                (in original order).
    """

    # Initializing output list
    output_list = []

    # Adding sorted keys from dict1 & dict2 into output list
    for key in OrderedDict(dict1):
        output_list.append(key)

    for key in OrderedDict(dict2):
        if key not in output_list:
            output_list.append(key)

    # If one of the dict1 or dict2 is empty, or both dicts are equal
    # return output unsorted
    if (not dict1 or not dict2) or (dict1 == dict2):
        return output_list
    # otherwise return sorted list
    else:
        return sorted(output_list)

def build_diff(input, output):
    """Generate Difference Function.

    Function accepts two dicts (input and output), and discovers
    the difference between keys and values in those dicts.

    Args:
        input ([dict]): input dict (contains original data)
        output ([dict]): output dict (contains modified data)

    Returns:
        difference ([dict]): output dict containing difference
                             between input & output dicts
    """

    # Getting list of joint keys from input & output files
    joint = get_ordered_joint_keys(input, output)

    # Comparing input and output dict's to find differences between keys
    intersected = input.keys() & output.keys()
    deleted = input.keys() - output.keys()
    added = output.keys() - input.keys()

    # Initializing variable containing function output
    difference = {}

    # Traversing each element of the tree
    for key in joint:
        if key in intersected:
            input_val, output_val = input[key], output[key]

            if isinstance(input_val, dict) and isinstance(output_val, dict):
                difference[key] = {'type': NESTED,
                                   'values': build_diff(input_val,
                                                        output_val)
                                   }
            elif input_val == output_val:
                difference[key] = {'type': UNMODIFIED,
                                   'values': input_val}
            else:
                difference[key] = {'type': CHANGED,
                                   'values': (input_val,
                                              output_val
                                              )
                                   }

        if key in added:
            values = output[key]
            if type(values) == dict:
                difference[key] = {'type': ADDED,
                                   'values': build_diff(values,
                                                        values)
                                   }
            else:
                difference[key] = {'type': ADDED,
                                   'values': values}

        if key in deleted:
            values = input[key]
            if type(values) == dict:
                difference[key] = {'type': DELETED,
                                   'values': build_diff(values,
                                                        values)
                                   }
            else:
                difference[key] = {'type': DELETED,
                                   'values': values}

    # Returning function output
    return difference


import mimetypes
import os
from email import encoders as email_encoders
from email.mime.base import MIMEBase

from envelopes import Envelope

class AdvancedEnvelope(Envelope):
    def add_src_image(self, file_path, mimetype=None, src_name=None):
        """Attaches a file located at *file_path* to the envelope. If
               *mimetype* is not specified an attempt to guess it is made. If nothing
               is guessed then `application/octet-stream` is used."""
        if not mimetype:
            mimetype, _ = mimetypes.guess_type(file_path)

        if mimetype is None:
            mimetype = 'application/octet-stream'

        type_maj, type_min = mimetype.split('/')
        with open(file_path, 'rb') as fh:
            part_data = fh.read()

            part = MIMEBase(type_maj, type_min)
            part.set_payload(part_data)
            email_encoders.encode_base64(part)

            if not src_name:
                part_filename = os.path.basename(self._encoded(file_path))
                src_name = part_filename
            part.add_header('Content-ID', '<{}>'.format(src_name))
            self._parts.append((mimetype, part))


import functools
from absl.testing import absltest
import numpy as np

from trax import shapes
import trax.layers as tl
from trax.layers import test_utils

class AttentionTest(absltest.TestCase):

  def test_simple_call(self):
    layer = tl.CausalAttention(d_feature=4, n_heads=2)
    x = [np.array([[[2, 5, 3, 4],
                    [0, 1, 2, 3],
                    [0, 1, 2, 3],]]),
         np.array([[[[1, 0, 1]]]])]
    _, _ = layer.init(shapes.signature(x))

    y, mask = layer(x)
    self.assertEqual(y.shape, (1, 3, 4))
    self.assertEqual(mask.shape, (1, 1, 1, 3))

  def test_shift_right(self):
    # Test shifts right on axis=1
    layer = tl.ShiftRight()
    x = np.array([[[9, 9, 9],
                   [8, 8, 8],
                   [7, 7, 7],
                   [6, 6, 6]],
                  [[99, 98, 97],
                   [96, 95, 94],
                   [93, 92, 91],
                   [90, 89, 88]]])
    y = layer(x)
    self.assertEqual(x.shape, y.shape)
    self.assertEqual(tl.to_list(y), [[[0, 0, 0],
                                      [9, 9, 9],
                                      [8, 8, 8],
                                      [7, 7, 7]],
                                     [[0, 0, 0],
                                      [99, 98, 97],
                                      [96, 95, 94],
                                      [93, 92, 91]]])

  def test_shift_right_float(self):
    layer = tl.ShiftRight()
    x = np.array([[[9, 9, 9],
                   [8, 8, 8],
                   [7, 7, 7],
                   [6, 6, 6]],
                  [[99, 98, 97],
                   [96, 95, 94],
                   [93, 92, 91],
                   [90, 89, 88]]]).astype(np.float32)
    x /= 2.0
    self.assertEqual(x.dtype, np.float32)

    y = layer(x)
    self.assertEqual(y.dtype, np.float32)
    self.assertEqual(tl.to_list(y), [[[0.0, 0.0, 0.0],
                                      [4.5, 4.5, 4.5],
                                      [4.0, 4.0, 4.0],
                                      [3.5, 3.5, 3.5]],
                                     [[0.0, 0.0, 0.0],
                                      [49.5, 49.0, 48.5],
                                      [48.0, 47.5, 47.0],
                                      [46.5, 46.0, 45.5]]])

  def test_padding_mask(self):
    layer = tl.PaddingMask()
    x = np.array([
        [1., 2., 3., 4., 0.],
        [1., 2., 3., 0., 0.],
        [1., 2., 0., 0., 0.],
    ])
    y = layer(x)
    self.assertEqual(x.shape, (3, 5))
    self.assertEqual(y.shape, (3, 1, 1, 5))
    np.testing.assert_equal(y, [[[[True, True, True, True, False]]],
                                [[[True, True, True, False, False]]],
                                [[[True, True, False, False, False]]]])

class CausalAttentionTest(absltest.TestCase):

  def test_simple_call(self):
    layer = tl.CausalAttention(d_feature=4, n_heads=2)
    x = np.array([[[2, 5, 3, 4],
                   [0, 1, 2, 3],
                   [0, 1, 2, 3],]])
    _, _ = layer.init(shapes.signature(x))

    y = layer(x)
    self.assertEqual(y.shape, (1, 3, 4))

  def test_deterministic_eval(self):
    d_model = 32
    seq_len = 3
    x_shape = (1, seq_len, d_model)
    inp = np.ones(x_shape).astype(np.float32)

    model_fn = functools.partial(
        tl.CausalAttention,
        d_feature=d_model,
        n_heads=4,
        )

    test_utils.test_eval_is_deterministic(inp, model_fn)

  def test_predict_equals_eval(self):
    d_model = 32
    seq_len = 10
    x_shape = (1, seq_len, d_model)
    inp = np.ones(x_shape).astype(np.float32)

    model_fn = functools.partial(
        tl.CausalAttention,
        d_feature=d_model,
        n_heads=4,
        )

    test_utils.test_eval_equals_predict(inp, model_fn)

class PositionalEncodingTest(absltest.TestCase):

  def test_simple_call(self):
    layer = tl.PositionalEncoding(max_len=8)
    x = np.array([[[2.0, 3.0, 4.0, 5.0], [1.0, 2.0, 3.0, 4.0]]])
    layer.init(shapes.signature(x))
    y = layer(x)
    self.assertEqual(y.shape, (1, 2, 4))

  def test_predict(self):
    layer = tl.PositionalEncoding(max_len=8)
    x = np.array([[[2.0, 3.0], [1.0, 2.0], [0.0, 1.0], [3.0, 4.0]]])
    self.assertEqual(x.shape, (1, 4, 2))
    layer.init(shapes.signature(x))
    y = layer(x)
    self.assertEqual(y.shape, (1, 4, 2))
    layer = tl.PositionalEncoding(max_len=8, mode='predict')
    layer.init(shapes.signature(x[:, :1, :]))
    y0 = layer(x[:, :1, :])   # just the first token
    self.assertEqual(y0.shape, (1, 1, 2))
    self.assertTrue(np.array_equal(y0, y[:, :1, :]))
    y1 = layer(x[:, 1:3, :])  # now the next 2 tokens
    self.assertEqual(y1.shape, (1, 2, 2))
    self.assertTrue(np.array_equal(y1, y[:, 1:3, :]))
    y2 = layer(x[:, 3:4, :])  # final one token
    self.assertEqual(y2.shape, (1, 1, 2))
    self.assertTrue(np.array_equal(y2, y[:, 3:4, :]))

  def test_predict_equals_eval(self):
    x = np.array([[[2.0, 3.0], [1.0, 2.0], [0.0, 1.0], [3.0, 4.0]]])
    self.assertEqual(x.shape, (1, 4, 2))

    layer_eval = tl.PositionalEncoding(max_len=8, d_feature=4, mode='eval')
    layer_eval.init(shapes.signature(x))

    output_eval = layer_eval(x)

    layer_predict = tl.PositionalEncoding(max_len=8, d_feature=4,
                                          mode='predict')
    layer_predict.init(shapes.signature(x))
    layer_predict.weights = layer_eval.weights

    output_predict = layer_predict(x)
    self.assertTrue(np.array_equal(output_eval, output_predict))

if __name__ == '__main__':
  absltest.main()


import os
import importlib

from pyrogram import Client

class Config:
    API_ID = int(3716600)# int(os.environ.get("API_ID"))
    API_HASH = str("0ed423ceea4fbb06c0e627d9db0f4a6b")# str(os.environ.get("API_HASH"))
    BOT_TOKEN = str("2023772023:AAELvE7PzeD2hggebtCuN0HM5FWhV9WbXgs")# str(os.environ.get("BOT_TOKEN"))

class NoteBot(Client):
    def __init__(self):
        kwargs = {
            'api_id': Config.API_ID,
            'api_hash': Config.API_HASH,
            'session_name': ":memory:",
            'bot_token': Config.BOT_TOKEN
        }
        super().__init__(**kwargs)

    async def start(self):
        await super().start()
        print("START")
        try:
            path = os.listdir("notemusic/plugins")
            path.remove("creator_commands.py")
            for p in path:
                if p.endswith(".py"):
                    arq = p.replace(".py", "")
                    importlib.import_module("plugins." + arq)
                    importlib.import_module("plugins.creator_commands")
        except Exception as e:
            print(str(e))
            await self.send_message(-1001165341477, f"**❌ OCORREU UM ERRO**\n\nNão foi possível importar os plugins, ocorreu este erro: `{str(e)}`")
        else:
            await self.send_message(-1001165341477, "`NoteMusic iniciado com sucesso!`")

    async def stop(self):
        await super().stop()
        print("STOP")

NoteMusic = NoteBot()


import os
import numpy as np
import time
import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
from torch.utils.data.sampler import SubsetRandomSampler
import copy

import sys
import shutil
import numpy as np
import time, datetime
import random
import logging
import argparse
import torch.utils
import torch.backends.cudnn as cudnn
import torch.distributed as dist
import torch.utils.data.distributed
from tqdm import tqdm
from utils import *

def sgd_optimizer(args, model):
    params = []
    for key, value in model.named_parameters():
        if not value.requires_grad:
            continue
        lr = args.base_lr
        weight_decay = args.weight_decay
        if "bias" in key or "bn" in key or "BN" in key:
            # lr = cfg.SOLVER.BASE_LR * cfg.SOLVER.BIAS_LR_FACTOR
            weight_decay = args.weight_decay
            print('set weight_decay={} for {}'.format(weight_decay, key))
        if 'bias' in key:
            apply_lr = 2 * lr
            print('set lr={} for {}'.format(apply_lr, key))
        else:
            apply_lr = lr

        params += [{"params": [value], "lr": apply_lr, "weight_decay": weight_decay}]
    # optimizer = torch.optim.Adam(params, lr)
    optimizer = torch.optim.SGD(params, lr, momentum=args.momentum)
    return optimizer

def get_optimizer(args, model):
    return sgd_optimizer(args, model)
# Dataloader
def get_ucml_dataloader(batch_size):
    ROOT_TRAIN = r'/home/fanxiaoyi/UCML_0.8/train'
    ROOT_TEST = r'/home/fanxiaoyi/UCML_0.8/val'
    # 将图像的像素值归一化到[-1， 1]之间
    normalize = transforms.Normalize(mean=[0.48422759, 0.49005176, 0.45050278],
                                std=[0.17348298, 0.16352356, 0.15547497])
    # 将训练集输入图像进行预处理，重映射尺寸、随机旋转、转化张量
    train_transform = transforms.Compose([
        transforms.RandomResizedCrop(256),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        normalize])
    # 将验证集输入图像进行预处理，重映射尺寸、随机旋转、转化张量
    val_transform = transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(256),
        transforms.ToTensor(),
        normalize])
    # 设置训练集、验证集加载路径
    train_dataset = ImageFolder(ROOT_TRAIN, transform=train_transform)
    val_dataset = ImageFolder(ROOT_TEST, transform=val_transform)
    # 加载训练集、验证集
    train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True,num_workers=8)
    val_dataloader = DataLoader(val_dataset, batch_size=batch_size, shuffle=True,num_workers=8)

    return train_dataloader, val_dataloader

def get_dataloader(img_size, dataset, datapath, batch_size, no_val):
    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])

    if img_size == 32:
        train_set = eval(dataset)(datapath, True, transforms.Compose([
                transforms.RandomCrop(img_size, padding=4),
                transforms.RandomHorizontalFlip(),
                transforms.ToTensor(),
                normalize,
            ]), download=True)
        val_set = eval(dataset)(datapath, True, transforms.Compose([
                transforms.ToTensor(),
                normalize,
            ]), download=True)

        num_train = len(train_set)
        indices = list(range(num_train))
        split = int(np.floor(0.1 * num_train))

        np.random.seed(int(time.time()))
        np.random.shuffle(indices)

        train_idx, valid_idx = indices[split:], indices[:split]
        train_sampler = SubsetRandomSampler(train_idx)
        valid_sampler = SubsetRandomSampler(valid_idx)

        test_set = eval(dataset)(datapath, False, transforms.Compose([
                transforms.ToTensor(),
                normalize,
            ]), download=True)

        if no_val:
            train_loader = torch.utils.data.DataLoader(
                train_set, batch_size=batch_size, shuffle=True,
                num_workers=0, pin_memory=True
            )
            val_loader = torch.utils.data.DataLoader(
                val_set, batch_size=batch_size, sampler=valid_sampler,
                num_workers=0, pin_memory=True
            )
        else:
            train_loader = torch.utils.data.DataLoader(
                train_set, batch_size=batch_size, sampler=train_sampler,
                num_workers=0, pin_memory=True
            )
            val_loader = torch.utils.data.DataLoader(
                val_set, batch_size=batch_size, sampler=valid_sampler,
                num_workers=0, pin_memory=True
            )
        test_loader = torch.utils.data.DataLoader(
            test_set, batch_size=batch_size, shuffle=False,
            num_workers=0, pin_memory=False
        )
    else:
        raise ValueError("img_size must be 32")
    return train_loader, val_loader, test_loader

# epoch of train
def train_epoch(model, train_loader, optimizer=None, steps=None, device='cuda'):
    model.to(device)
    model.train()
    losses = np.zeros(0)
    total_loss = 0
    data_t = 0
    train_t = 0
    criterion = torch.nn.CrossEntropyLoss()
    s = time.time()
    for i, (batch, label) in enumerate(train_loader):

        batch, label = batch.to(device), label.to(device)
        data_t += time.time() - s
        s = time.time()     # second

        model.zero_grad()
        output = model(batch)
        loss = criterion(output, label)
        loss.backward()
        optimizer.step()

        total_loss += loss
        losses = np.concatenate([losses, np.array([loss.item()])])

        train_t += time.time() - s
        length = steps if steps and steps < len(train_loader) else len(train_loader)

        if (i % 100 == 0) or (i == length-1):
            print('Training | Batch ({}/{}) | Loss {:.4f} ({:.4f}) | (PerBatchProfile) Data: {:.3f}s, Net: {:.3f}s'.format(i+1, length, total_loss/(i+1), loss, data_t/(i+1), train_t/(i+1)))
        if i == length-1:
            break
        s = time.time()
    return np.mean(losses)

# train
def train(model, train_loader, val_loader, optimizer, scheduler, epochs=400, arch ='resnet_56', steps=None, run_test=True, train_model_Running=False, quant=False, name='', ratio='', device='cuda'):
    model.to(device)
    if optimizer is None:
        optimizer = optim.SGD(model.classifier.parameters(), lr=1e-1, momentum=0.9, weight_decay=5e-4)
    if scheduler is None:
        scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, epochs)

    # Use number of steps as unit instead of epochs
    if steps:
        epochs = int(steps / len(train_loader)) + 1
        # print(epochs)
        if epochs > 1:
            steps = steps % len(train_loader)

    best_acc = 0
    for i in range(epochs):
        print('Epoch: {}'.format(i))
        if i == epochs - 1:
            loss = train_epoch(model, train_loader, optimizer, steps=steps, device=device)
        else:
            loss = train_epoch(model, train_loader, optimizer, device=device)
        scheduler.step()

        if run_test:
            acc = test(model, val_loader, device=device)
            print('Testing Accuracy {:.2f}'.format(acc))
            if i and best_acc < acc:
                best_acc = acc
                #  "Pre-trained" model
                if train_model_Running :
                    torch.save(model.state_dict(), os.path.join('./ckpt/', '{}.t7'.format(name)))
                else :
                    if quant:
                        torch.save(model.state_dict(), os.path.join('ckpt_{}'.format(ratio), '{}_quant_best.t7'.format(name)))
                    else :
                        torch.save(model.state_dict(), os.path.join('ckpt_{}'.format(ratio), '{}_best.t7'.format(name)))

    print('best_acc: ' + str(best_acc))

# test
def test(model, data_loader, device='cuda', get_loss=False, n_img=-1):
    model.to(device)
    model.eval()
    correct = 0
    total = 0
    if get_loss:
        criterion = nn.CrossEntropyLoss(reduction='none')
        loss = np.zeros(0)
    total_len = len(data_loader)

    if n_img > 0 and total_len > int(np.ceil(float(n_img) / data_loader.batch_size)):
        total_len = int(np.ceil(float(n_img) / data_loader.batch_size))
    for i, (batch, label) in enumerate(data_loader):

        if i >= total_len:
            break
        batch, label = batch.to(device), label.to(device)

        output = model(batch)
        if get_loss:
            loss = np.concatenate((loss, criterion(output, label).data.cpu().numpy()))
        pred = output.data.max(1)[1]

        correct += pred.eq(label).sum()
        total += label.size(0)

    if get_loss:
        return float(correct)/total*100, loss
    else:
        return float(correct)/total*100

def count_bops(layer, x, sparse_channel, bit):
    cur_bops = 0
    activation_index = 0
    y = layer.old_forward(x)
    if isinstance(layer, nn.Conv2d):
        if activation_index == 0:
            conv_in_channels = 3
            conv_out_channels = sparse_channel[activation_index]
        else:
            conv_in_channels = sparse_channel[activation_index - 1]
            conv_out_channels = sparse_channel[activation_index]
        h = y.shape[2]
        w = y.shape[3]
        cur_bops += h * w * conv_in_channels * conv_out_channels * layer.weight.size(2) * layer.weight.size(3) * bit[activation_index] * bit[activation_index]

    elif isinstance(layer, nn.Linear):
        cur_bops += np.prod(layer.weight.shape)
    cur_bops/= 1E9
    return cur_bops


from typing import List, Optional

from kenning.core.dataset import Dataset
from kenning.datasets.imagenet_dataset import ImageNetDataset
from kenning.modelwrappers.frameworks.tensorflow import TensorFlowWrapper
from kenning.utils.class_loader import load_class
from kenning.utils.logger import KLogger
from kenning.utils.resource_manager import PathOrURI

class TensorFlowImageNet(TensorFlowWrapper):
    """
    General-purpose model wrapper for ImageNet models in TensorFlow.
    """

    default_dataset = ImageNetDataset
    pretrained_model_uri = "kenning:///models/classification/tensorflow_imagenet_mobilenetv3small.h5"  # noqa: E501
    arguments_structure = {
        "modelcls": {
            "argparse_name": "--model-cls",
            "description": "The Keras model class",
            "type": str,
        },
        "modelinputname": {
            "argparse_name": "--model-input-name",
            "description": "Name of the input in the TensorFlow model",
            "type": str,
            "default": "input",
        },
        "modeloutputname": {
            "argparse_name": "--model-output-name",
            "description": "Name of the output in the TensorFlow model",
            "type": str,
            "default": "output",
        },
        "inputshape": {
            "argparse_name": "--input-shape",
            "description": "Input shape",
            "type": int,
            "is_list": True,
            "default": [1, 224, 224, 3],
        },
        "numclasses": {
            "argparse_name": "--num-classes",
            "description": "Output shape",
            "type": int,
            "default": 1000,
        },
        "disablebuiltinpreprocessing": {
            "argparse_name": "--disable-builtin-preprocessing",
            "description": "Removes (if possible) internal preprocessing in the model",  # noqa: E501
            "type": bool,
            "default": False,
        },
    }

    def __init__(
        self,
        model_path: PathOrURI,
        dataset: Dataset,
        from_file: bool = False,
        model_name: Optional[str] = None,
        modelcls: str = "",
        modelinputname: str = "input",
        modeloutputname: str = "output",
        inputshape: List[int] = [1, 224, 224, 3],
        numclasses: int = 1000,
        disablebuiltinpreprocessing: bool = False,
    ):
        """
        Creates model wrapper for TensorFlow classification
        model pretrained on ImageNet dataset.

        Parameters
        ----------
        model_path : PathOrURI
            Path or URI to the model file.
        dataset : Dataset
            The dataset to verify the inference.
        from_file : bool
            True if model should be loaded from file.
        model_name : Optional[str]
            Name of the model used for the report
        modelcls : str
            The model class import path.
            Used for loading keras.applications pretrained models.
        modelinputname : str
            The name of the model input.
        modeloutputname : str
            The name of the model output.
        inputshape : List[int]
            The shape of the input.
        numclasses : int
            Number of classes in the model.
        disablebuiltinpreprocessing : bool
            Tells if the input preprocessing should be removed from the model.

        Raises
        ------
        ValueError
            Raised when dataset batch size and ModelWrapper supported
            sizes do not match
        """
        super().__init__(model_path, dataset, from_file, model_name)
        import tensorflow as tf

        gpus = tf.config.list_physical_devices("GPU")
        for gpu in gpus:
            tf.config.experimental.set_memory_growth(gpu, True)
        self.modelcls = modelcls
        self.modelinputname = modelinputname
        self.modeloutputname = modeloutputname
        self.inputshape = inputshape
        self.numclasses = numclasses
        self.outputshape = [inputshape[0], numclasses]
        self.disablebuiltinpreprocessing = disablebuiltinpreprocessing

        if dataset and dataset.batch_size != self.inputshape[0]:
            KLogger.error(
                "Dataset batch size and ModelWrapper inputshape mismatch"
            )
            KLogger.error(f"batch size: {dataset.batch_size}")
            KLogger.error(f"input shape[0]: {self.inputshape[0]}")
            raise ValueError

    @classmethod
    def _get_io_specification(
        cls, modelinputname, inputshape, modeloutputname, outputshape
    ):
        return {
            "input": [
                {
                    "name": modelinputname,
                    "shape": inputshape,
                    "dtype": "float32",
                }
            ],
            "output": [
                {
                    "name": modeloutputname,
                    "shape": outputshape,
                    "dtype": "float32",
                }
            ],
        }

    @classmethod
    def derive_io_spec_from_json_params(cls, json_dict):
        input_shape = json_dict["inputshape"]
        output_shape = [input_shape[0], json_dict["numclasses"]]
        return cls._get_io_specification(
            json_dict["modelinputname"],
            input_shape,
            json_dict["modeloutputname"],
            output_shape,
        )

    def get_io_specification_from_model(self):
        return self._get_io_specification(
            self.modelinputname,
            self.inputshape,
            self.modeloutputname,
            self.outputshape,
        )

    def prepare_model(self):
        if self.model_prepared:
            return None
        if self.from_file:
            self.load_model(self.model_path)
            self.model_prepared = True
        else:
            if self.disablebuiltinpreprocessing:
                self.model = load_class(self.modelcls)(
                    input_shape=tuple(self.inputshape[1:]),
                    include_preprocessing=False,
                )
            else:
                self.model = load_class(self.modelcls)(
                    input_shape=tuple(self.inputshape[1:])
                )
            self.model_prepared = True
            self.save_model(self.model_path)
            self.model.summary()


import pytest
from sqlalchemy.orm.exc import NoResultFound
from tensorhive.models.Group import Group
from tensorhive.exceptions.InvalidRequestException import InvalidRequestException

def test_group_creation(tables):
    new_group = Group(name='test').save()
    assert new_group.id is not None

def test_adding_user_to_a_group(tables, new_user, new_group):
    new_user.save()
    new_group.add_user(new_user)

    assert new_user in new_group.users
    assert new_group in new_user.groups

def test_removing_user_from_a_group(tables, new_group_with_member):
    user = new_group_with_member.users[0]
    new_group_with_member.remove_user(user)

    assert user not in new_group_with_member.users
    assert new_group_with_member not in user.groups

def test_removing_user_from_a_group_that_he_doesnt_belong_to_fails(tables, new_user, new_group):
    new_group.save()
    new_user.save()

    with pytest.raises(InvalidRequestException):
        new_group.remove_user(new_user)

def test_adding_user_to_a_group_that_he_is_already_in_fails(tables, new_group_with_member):
    user = new_group_with_member.users[0]

    with pytest.raises(InvalidRequestException):
        new_group_with_member.add_user(user)

def test_marking_group_as_a_default(tables, new_group):
    new_group.is_default = True
    new_group.save()

    assert Group.get(new_group.id).is_default
    assert new_group in Group.get_default_groups()

def test_get_default_group(tables, new_group):
    new_group.is_default = True
    new_group.save()

    assert new_group in Group.get_default_groups()

def test_get_default_without_default_group(tables, new_group):
    new_group.save()

    assert len(Group.get_default_groups()) == 0

def test_more_than_one_default_group(tables, new_group):
    new_group.is_default = True
    new_group.save()

    another_group = Group(name='AnotherGroup')
    another_group.is_default = True
    another_group.save()

    defaults = Group.get_default_groups()
    assert new_group in defaults
    assert another_group in defaults


import csv
from datetime import date, timedelta
from .ApiSheetClient import ApiSheetClient
import requests

class SGReader:

    def __init__(self, DDV_Mapping):

        self.EUSIPA_Mapping = {
            "1100 Uncapped Capital Protection": ["Kapitalschutz-Zertifikate"],
            "1120 Capped Capital Protection": [],
            "1130 Capital Protection with Knock-Out": [],
            "1140 Capital protection with Coupon": [],
            "1199 Miscellaneous Capital Protection": [],
            "1200 Discount Certificates": ["Discount-Zertifikate", "Classic Discount-Zertifikat"],
            "1220 Reverse Convertibles": ["Classic Aktienanleihen", "Classic Aktienanleihen", "Aktienanleihen Plus", "Aktienanleihen PlusPro", "Aktienanleihen Protect"],
            "1230 Barrier Reverse Convertibles": [],
            "1240 Capped Outperformance Certificates": ["Sprint-Zertifikat"],
            "1260 Express Certificates": ["Memory Express-Zertifikat", "Duo Memory Express-Zertifikat", "Multi Express-Zertifikat", "Multi Memory Express-Zertifikat", "Stufenexpress-Zertifikat", "Fixkupon Express-Zertifikat", "Duo Fixkupon Express-Zertifikat"],
            "1299 Miscellaneous Yield Enhancement": [],
            "1300 Tracker Certificates": ["Index-Zertifiakte", "Short Index-Zertifikate"],
            "1310 Outperformance Certificates": ["Outperformance-Zertifikat"],
            "1320 Bonus Certificates": ["Classic Bonus-Zertifiakt", "Bonus-Zertifiakte Pro", "Capped Bonus-Zertifiakt", "Capped Bonus-Zertifiakt Pro","Reverse Capped Bonus-Zertifikat"],
            "1399 Miscellaneous Participation": [],
            "2100 Warrants": ["Standard-Optionsscheine", "Discount-Optionsscheine", "Inline-Optionsscheine", "StayLow-Optionsscheine", "StayHigh-Optionsscheine", "Turbo-Optionsscheine", "Classic Turbo-Optionsscheine", "Unlimited Turbo-Optionsscheine", "Smart Turbo-Optionsscheine", "BEST Turbo-Optionsscheine", "X-BEST Turbo Optionsscheine", "Faktor-Optionsscheine"],
            "2199 Miscellaneous Leverage without Knock-Out": [],
            "2200 Knock-Out Warrants": [],
            "2210 Mini-Futures": [],
            "2299 Miscellaneous Leverage with Knock-Out": [],
            "2300 Constant Leverage Certificate": [],
            "2399 Miscellaneous Leverage with Knock-Out": [],
            "1340 Twin-Win Certificates": []
        }

        self.Mapping = {
            "Zertifikate": {
                "Aktienanleihen": {
                    53: {
                        59: "Classic Aktienanleihen",
                        59: "Aktienanleihen Plus",
                        61: "Aktienanleihen PlusPro",
                        62: "Aktienanleihen Protect"
                    },
                },
                "Bonus-Zertifikate": {
                    16: {
                        17: "Classic Bonus-Zertifiakt",
                        18: "Bonus-Zertifiakte Pro",
                        19: "Capped Bonus-Zertifiakt",
                        204: "Capped Bonus-Zertifiakt Pro",
                        86: "Reverse Capped Bonus-Zertifikat"
                    }
                },
                "Kapitalschutz-Zertifikate": {
                    15: {}
                },
                "Discount-Zertifikate": {
                    20: {
                        21: "Classic Discount-Zertifikat"
                    }
                },
                "Express-Zertifikate": {
                    56: {
                        44043: "Memory Express-Zertifikat",
                        44037: "Duo Memory Express-Zertifikat",
                        44044: "Multi Express-Zertifikat",
                        44045: "Multi Memory Express-Zertifikat",
                        44046: "Stufenexpress-Zertifikat",
                        44038: "Fixkupon Express-Zertifikat",
                        44086: "Duo Fixkupon Express-Zertifikat"
                    }
                },
                "Outperformance-Zertifikat": {
                    30: {}
                },
                "Sprint-Zertifikat": {
                    37: {}
                },
                "Alpha-Zertifikat": {
                    93: {}
                },
                "Index-Zertifiakte": {
                    27: {
                        44093: "Short Index-Zertifikate"
                    }
                },
            },
            "Hebelprodukte": {
                "Optionsscheine": {
                    1: {
                        2: "Standard-Optionsscheine",
                        12: "Discount-Optionsscheine",
                        8: "Inline-Optionsscheine",
                        44059: "StayLow-Optionsscheine",
                        44056: "StayHigh-Optionsscheine"
                    }
                },
                "Turbo-Optionsscheine": {
                    42: {
                        43: "Classic Turbo-Optionsscheine",
                        45: "Unlimited Turbo-Optionsscheine",
                        49: "Smart Turbo-Optionsscheine",
                        47: "BEST Turbo-Optionsscheine",
                        7145: "X-BEST Turbo Optionsscheine"
                    }
                },
                "Faktor-Optionsscheine": {
                    228: {}
                }
            }
        }

        self.client = ApiSheetClient("Issuance Data Collection", "SG")

        finaldict = {}
        finaldict["date"] = date.today().strftime('%Y-%m-%d')

        for category in ['Zertifikate', 'Hebelprodukte']:
            resultdict = self.readData(category)
            finaldict[category] = resultdict

        self.client.updateFile(finaldict, DDV_Mapping, self.EUSIPA_Mapping, Volumen=False, ExchangeData=True)

    def createResultDict(self, newProducts):

        count_dict = {}
        for x in newProducts:
            if not x[1] in count_dict.keys():
                count_dict[x[1]] = {}
                count_dict[x[1]]['amount'] = 1
                count_dict[x[1]]['exchange'] = 0
                count_dict[x[1]]['not exchange'] = 0

                if x[2]:
                    count_dict[x[1]]['exchange'] += 1
                else:
                    count_dict[x[1]]['not exchange'] += 1

                count_dict[x[1]]['ISINs'] = [x[0]]
                # product type and then we have the number, so lets do product type as key and then another nested dict with number and examples --> and here at examples we put in some random IDs
            else:
                count_dict[x[1]]['amount'] = count_dict[x[1]]['amount'] + 1
                count_dict[x[1]]['ISINs'].append(x[0])

                if x[2]:
                    count_dict[x[1]]['exchange'] = count_dict[x[1]]['exchange'] + 1
                else:
                    count_dict[x[1]]['not exchange'] = count_dict[x[1]]['not exchange'] + 1

        return count_dict

    def getProducts(self, id, p_type):
        all_products = []
        today = date.today().strftime('%Y-%m-%d')
        pageNum = 1
        nextPage = True
        while nextPage:
            url = "https://www.sg-zertifikate.de/EmcWebApi/api/ProductSearch/Search?PageSize=1000&PageNum={}&ProductClassificationId={}&IssueDateFrom={}".format(str(pageNum), str(id), today)
            print(url)
            response = requests.get(url)
            if response.status_code == 200:
                json = response.json()
                total = json['TotalCount']
                products = json['Products']
                for p in products:
                    isin = p["Isin"]
                    if p['IsSecondaryMarket']:
                        exchange = True
                    else:
                        exchange = False
                    all_products.append([isin, p_type, exchange])
                if not total > (1000*pageNum):
                    nextPage = False
                else:
                    pageNum += 1

        return all_products

    def readData(self, category):

        all_products = []

        for parent_name in self.Mapping[category]:
            parent_id = list(self.Mapping[category][parent_name].keys())[0]
            parent_products = self.getProducts(parent_id, parent_name)

            for sub_id, sub_name in self.Mapping[category][parent_name][parent_id].items():
                sub_products = self.getProducts(sub_id, sub_name)
                if len(sub_products) > 0:
                    [all_products.append(x) for x in sub_products]
                    # remove sub_product from parent product
                    for item in sub_products:
                        for item2 in parent_products:
                            if item[0] == item2[0]:
                                parent_products.remove(item2)

            [all_products.append(x) for x in parent_products]

        return self.createResultDict(all_products)

    '''
    def compare(self, category):
        today = date.today().strftime('%Y-%m-%d')
        newProducts = self.readData(category, today)
        count_dict = {}
        for x in newProducts:
            if not x[1] in count_dict.keys():
                count_dict[x[1]] = {}
                count_dict[x[1]]['amount'] = 1
                count_dict[x[1]]['ISINs'] = [x[0]]
                # product type and then we have the number, so lets do product type as key and then another nested dict with number and examples --> and here at examples we put in some random IDs
            else:
                count_dict[x[1]]['amount'] = count_dict[x[1]]['amount'] + 1
                count_dict[x[1]]['ISINs'].append(x[0])
        return count_dict
'''


# -*- coding: utf-8 -*-
import requests
import time
import f_voice as f_v
import f_hear as f_h
from multiprocessing import Process, current_process,Lock
import f_data as f_d

class session:
    m_a = "https://gpd-friday.herokuapp.com/"
    r_a = "https://gpd-friday.herokuapp.com/read?m_id="
    l_a = "https://gpd-friday.herokuapp.com/error?m_id="
    def create(self,user):
        self.user = user
    def ask(self,quest):
        requests.post(self.m_a,data={"user":self.user,"mes":quest})
        text = ""
        while True:
            time.sleep(3)
            text = requests.get(self.r_a+self.user).text
            if len(text)>5:
                break
        requests.post(self.r_a+self.user,data={"dell":self.user})
        #work with added material
        return text.split("-&&-")[0]

    def log(self):
        q = requests.get(self.l_a+self.user).text
        requests.post(self.l_a+self.user,data={"dell":self.user})
        return q

class assistant:
    cou  = 0
    lock = Lock()
    def create(self,name):
        self.user = name
        self.brain = self.smart_brain()
        self.proc = []

    def do(self,quest):
        p = Process(target= self.brain.brain_storm,name = self.user+"_process_"+str(self.cou),args=(quest,self.lock))
        self.proc.append(p)
        p.start()
        self.cou += 1

    def does(self,d):
        self.ear = f_h.talk()
        self.ear.create(d)
        p = Process(target=self.ear.start_proc ,name = "SpeechRecognition",args=())
        self.proc.append(p)
        p.start()

    class smart_brain:
        def brain_storm(self,quest,loc):
            my_p = current_process().name
            search = session()
            search.create(my_p)
            ans = search.ask(quest)
            say = f_v.audio()
            sound_proc = Process(target= say.tts,name = "Audio",args=(loc,ans,"voice_"+my_p+".mp3"))
            sound_proc.start()
            sound_proc.join()

def start():
    db = f_d.data()
    db.create()
    fri = assistant()
    fri.create("friday")
    fri.does(db)

    while True :
        e = db.read_cou()
        if e != 0:
            fri.do(db.read("audio_"+str(int(e)-1)))
            db.minus_counter()
            db.delete_item("audio_"+str(int(e)-1))

    for y in fri.proc:
        y.join()

if __name__ == "__main__":
    start()


#!/usr/bin/env python3

import random
from functools import cmp_to_key

class Guillotine:
    def __init__(self, rect, rects):
        self.cuts = []
        self.w, self.h = rect
        rects = rects + [(x[1], x[0]) for x in rects if x[0] != x[1]]
        self.rects = sorted(rects, key=cmp_to_key(self.__cmp))

    def cut(self, pieces):
        # cut = self.__cut(0, 0, self.rect[0], self.rect[1])
        cut, tail = self.__stupid_cut(0, 0, self.w, self.h, pieces)
        self.cuts.append(cut)
        return cut

    def pieces(self, cut):
        x, y, w, h, q, gr, gu = cut
        pieces = [(w, h)]
        if gr is not None:
            pieces += self.pieces(gr)

        if gu is not None:
            pieces += self.pieces(gu)

        return pieces

    # def __cut(self, x0, y0, x1, y1):
        # w, h = x1 - x0, y1 - y0
        # rects = map(lambda r: (r, random.randint(0, min(w//r[0], h//r[1]))), rects)
    def change_cut(self, cut):
        pieces = self.pieces(cut)

        return self.cut(self.change(pieces))

    def change(self, pieces):
        change_index = random.randint(0, len(pieces)-1)
        new = random.choice(self.rects)
        pieces = pieces[:change_index] + [new] + pieces[change_index:]
        return self.pieces(self.cut(pieces))

    def __change_pos(self, cut, x0, y0, piece):
        x, y, w, h, q, gr, gu = cut

        if x == x0 and y == y0:
            if gr is not None:
                grx, gry, grw, grh, grq, grgr, grgu = gr
                gr = grx - (w - grx), gry, grw, grh, grq, grgr, grgu
            return (x, y, piece[0], piece[1], 1, gr, gu)
        if gr is not None:
            gr = self.__change_pos(gr, x0, y0, piece)
        if gu is not None:
            gu = self.__change_pos(gu, x0, y0, piece)
        return (x, y, w, h, q, gr, gu)

    def __position_slack(self, cut):
        x, y, w, h, q, gr, gu = cut
        sw, sh = w, h
        pieces = []
        if gr is not None:
            pieces += self.__position_slack(gr)
        else:
            sw += self.w - (x+w)

        if gu is not None:
            pieces += self.__position_slack(gu)
        else:
            sh += self.h - (y+h)

        return [((x, y), (sw, sh))] + pieces

    def __stupid_cut(self, x0, y0, x1, y1, pieces):
        w, h = x1 - x0, y1 - y0
        if len(pieces) > 0:
            p, *tail = pieces
            pw, ph = p
            if pw <= w and ph <= h:
                right_cuts, tail = self.__stupid_cut(x0+pw, y0, x1, y0 + ph, tail)
                above_cuts, tail = self.__stupid_cut(x0, y0+ph, x1, y1, tail)
                return ((x0, y0, pw, ph, 1, right_cuts, above_cuts), tail)
        return (None, pieces)

    def __naive_cut(self, x0, y0, x1, y1):
        w, h = x1 - x0, y1 - y0

        p, q = random.choice(self.__pieces(w, h))
        pw, ph = p
        if pw <= w and ph <= h:
            above_cuts = self.__cut(x0, y0+ph, x1, y1)
            right_cuts = self.__cut(x0+pw, y0, x1, y0 + ph)
            return (x0, y0, pw, ph, 1, right_cuts, above_cuts)
        return None

    def __cut(self, x0, y0, x1, y1):
        w, h = x1 - x0, y1 - y0
        pieces = self.__pieces(w, h)
        if len(pieces) > 0:
            piece, max_quantity = random.choice(pieces)
            # get only a certain number of pieces that can fill the current line
            # rand_quantity = random.randint(1, max_quantity)
            rand_quantity = max_quantity
            pw, ph = piece
            above_cuts = self.__cut(x0, y0+ph, x1, y1)
            right_cuts = self.__cut(x0+pw * rand_quantity, y0, x1, y0 + ph)
            return (x0, y0, piece[0], piece[1], rand_quantity, right_cuts, above_cuts)
        return None

    """
    Return the all the pieces and their quantities that fits the area w x h

    returns a tuple:
    ((piece_w, piece_h), quantity)
    """
    def __pieces(self, w, h):
        rects = [x for x in self.rects if x[0] <= w and x[1] <= h]
        rects = list(map(lambda r: (r, w//r[0]), rects))
        if len(rects) > 0:
            rects = list(filter(lambda r: r[1] > 0, rects))
            return rects
        return []

    def __heuristic_cut(self, x0, y0, x1, y1):
        w, h = x1 - x0, y1 - y0
        rects = [x for x in self.rects if x[0] * x[1] <= w * h]

        for pw, ph in random.sample(rects, min(len(rects), 3)):
            pw, ph = random.choice(rects)
            if pw <= w and ph <= h:
                above_cuts = self.__cut(x0, y0+ph, x1, y1)
                right_cuts = self.__cut(x0+pw, y0, x1, y0 + ph)
                return (x0, y0, pw, ph, right_cuts, above_cuts)
            aux = pw
            pw = ph
            ph = aux
            if pw <= w and ph <= h:
                above_cuts = self.__cut(x0, y0+ph, x1, y1)
                right_cuts = self.__cut(x0+pw, y0, x1, y0 + ph)
                return (x0, y0, pw, ph, right_cuts, above_cuts)

        for pw, ph in rects[::-1]:
            if pw <= w and ph <= h:
                above_cuts = self.__cut(x0, y0+ph, x1, y1)
                right_cuts = self.__cut(x0+pw, y0, x1, y0 + ph)
                return (x0, y0, pw, ph, right_cuts, above_cuts)
            aux = pw
            pw = ph
            ph = aux
            if pw <= w and ph <= h:
                above_cuts = self.__cut(x0, y0+ph, x1, y1)
                right_cuts = self.__cut(x0+pw, y0, x1, y0 + ph)
                return (x0, y0, pw, ph, right_cuts, above_cuts)

    def __cmp(self, a, b):
        return a[0] * a[1] - b[0] * b[1]

# import numpy as np

# xs = np.random.random_integers(1, 10, 10)
# ys = np.random.random_integers(1, 10, 10)
# rects = [(xs[i], ys[i]) for i in range(len(xs))]

# g = Guillotine((20, 20), rects)
# cut = g.cut()
# g.change(cut)


import cgi
import subprocess
import js2py
print("context-type:text/html")
print()

def get_details_of_vehicle(Reg_no):
    r = requests.get("http://www.regcheck.org.uk/api/reg.asmx/CheckIndia?RegistrationNumber={0}&username=swastik".format(str(Reg_no)))
    json_data = json.dumps(xmltodict.parse(r.content))
    detail = json.loads(json_data)
    return json.loads(detail['Vehicle']['vehicleJson'])

f = cgi.FieldStorage()
no = f.getvalue("x")
#out= subprocess.getoutput(cmd)
#print(get_details_of_vehicle(no))
print("{'Description': 'HYUNDAI I10 1.2 L KAPPA SPORTZ GLS',\
 'RegistrationYear': '2011',\
 'CarMake': {'CurrentTextValue': 'HYUNDAI'},\
 'CarModel': {'CurrentTextValue': 'I10 1.2 L KAPPA SPORTZ GLS'},\
 'Variant': '1.2 Kappa GLS Sportz Petrol 1197.0',\
 'EngineSize': {'CurrentTextValue': '1197.0'},\
 'MakeDescription': {'CurrentTextValue': 'HYUNDAI'},\
 'ModelDescription': {'CurrentTextValue': 'I10 1.2 L KAPPA SPORTZ GLS'},\
 'NumberOfSeats': {'CurrentTextValue': '5'},\
 'VechileIdentificationNumber': 'MALAN51CLBM826996A',\
 'EngineNumber': 'G4LAAM585304',\
 'FuelType': {'CurrentTextValue': 'PETROL'},\
 'RegistrationDate': '26/02/2011',\
 'Owner': 'MR SHAILESH KUMAR',\
 'Fitness': '',\
 'Insurance': '2022-02-07',\
 'PUCC': '2021-10-09',\
 'VehicleType': 'MOTOR CAR(LMV)',\
 'Location': 'DTO,RANCHI',\
 'ImageUrl': 'http://www.carregistrationapi.in/image.aspx/@SFlVTkRBSSBJMTAgMS4yIEwgS0FQUEEgU1BPUlRaIEdMUw=='}")


import os
import socket
from collections import defaultdict, Iterable
from copy import deepcopy
from datetime import datetime
from itertools import chain

import torch

from core.config import cfg

def get_run_name():
    """ A unique name for each run """
    return datetime.now().strftime(
        '%b%d-%H-%M-%S') + '_' + socket.gethostname()

def get_output_dir(args, run_name):
    """ Get root output directory for each run """
    cfg_filename, _ = os.path.splitext(os.path.split(args.cfg_file)[1])
    return os.path.join(cfg.OUTPUT_DIR, cfg_filename, run_name)

IMG_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm']

def is_image_file(filename):
    """Checks if a file is an image.
      Args:
          filename (string): path to a file
      Returns:
          bool: True if the filename ends with a known image extension
    """
    filename_lower = filename.lower()
    return any(filename_lower.endswith(ext) for ext in IMG_EXTENSIONS)

def get_imagelist_from_dir(dirpath):
    images = []
    for f in os.listdir(dirpath):
        if is_image_file(f):
            images.append(os.path.join(dirpath, f))
    return images

def ensure_optimizer_ckpt_params_order(param_groups_names, checkpoint):
    """Reorder the parameter ids in the SGD optimizer checkpoint to match
    the current order in the program, in case parameter insertion order is changed.
    """
    assert len(param_groups_names) == len(checkpoint['optimizer']['param_groups'])
    param_lens = (len(g) for g in param_groups_names)
    saved_lens = (len(g['params']) for g in checkpoint['optimizer']['param_groups'])
    if any(p_len != s_len for p_len, s_len in zip(param_lens, saved_lens)):
        raise ValueError("loaded state dict contains a parameter group "
                         "that doesn't match the size of optimizer's group")

    name_to_curpos = {}
    for i, p_names in enumerate(param_groups_names):
        for j, name in enumerate(p_names):
            name_to_curpos[name] = (i, j)

    param_groups_inds = [[] for _ in range(len(param_groups_names))]
    cnts = [0] * len(param_groups_names)
    for key in checkpoint['model']:
        pos = name_to_curpos.get(key)
        if pos:
            # print(key, pos, cnts[pos[0]])
            saved_p_id = checkpoint['optimizer']['param_groups'][pos[0]]['params'][cnts[pos[0]]]
            assert (checkpoint['model'][key].shape ==
                    checkpoint['optimizer']['state'][saved_p_id]['momentum_buffer'].shape), \
                   ('param and momentum_buffer shape mismatch in checkpoint.'
                    ' param_name: {}, param_id: {}'.format(key, saved_p_id))
            param_groups_inds[pos[0]].append(pos[1])
            cnts[pos[0]] += 1

    for cnt, param_inds in enumerate(param_groups_inds):
        ckpt_params = checkpoint['optimizer']['param_groups'][cnt]['params']
        assert len(ckpt_params) == len(param_inds)
        ckpt_params = [x for x, _ in sorted(zip(ckpt_params, param_inds), key=lambda x: x[1])]
        checkpoint['optimizer']['param_groups'][cnt]['params'] = ckpt_params

def load_optimizer_state_dict(optimizer, state_dict):
    # deepcopy, to be consistent with module API
    state_dict = deepcopy(state_dict)
    # Validate the state_dict
    groups = optimizer.param_groups
    saved_groups = state_dict['param_groups']

    if len(groups) != len(saved_groups):
        raise ValueError("loaded state dict has a different number of "
                         "parameter groups")
    param_lens = (len(g['params']) for g in groups)
    saved_lens = (len(g['params']) for g in saved_groups)
    if any(p_len != s_len for p_len, s_len in zip(param_lens, saved_lens)):
        raise ValueError("loaded state dict contains a parameter group "
                         "that doesn't match the size of optimizer's group")

    # Update the state
    id_map = {old_id: p for old_id, p in
                zip(chain(*(g['params'] for g in saved_groups)),
                    chain(*(g['params'] for g in groups)))}

    def cast(param, value):
        """Make a deep copy of value, casting all tensors to device of param."""
        if torch.is_tensor(value):
            # Floating-point types are a bit special here. They are the only ones
            # that are assumed to always match the type of params.
            if isinstance(param.data, (torch.FloatTensor, torch.cuda.FloatTensor,
                                       torch.DoubleTensor, torch.cuda.DoubleTensor,
                                       torch.HalfTensor, torch.cuda.HalfTensor)):  # param.is_floating_point():
                value = value.type_as(param.data)
            value = value.cuda(param.get_device()) if param.is_cuda else value.cpu()
            return value
        elif isinstance(value, dict):
            return {k: cast(param, v) for k, v in value.items()}
        elif isinstance(value, Iterable):
            return type(value)(cast(param, v) for v in value)
        else:
            return value

    # Copy state assigned to params (and cast tensors to appropriate types).
    # State that is not assigned to params is copied as is (needed for
    # backward compatibility).
    state = defaultdict(dict)
    for k, v in state_dict['state'].items():
        if k in id_map:
            param = id_map[k]
            state[param] = cast(param, v)
        else:
            state[k] = v

    # Update parameter groups, setting their 'params' value
    def update_group(group, new_group):
        new_group['params'] = group['params']
        return new_group
    param_groups = [
        update_group(g, ng) for g, ng in zip(groups, saved_groups)]
    optimizer.__setstate__({'state': state, 'param_groups': param_groups})


import datetime

from django.db import models
from django.utils import timezone

from dashboard.models import hospital_models
from dashboard.models import user_models

class UserManager(models.Manager):
    """The Manager for the User-model."""

    def get_by_natural_key(self, username):
        """Overrides the method of the framework to get the User by a given username."""

        return self.get(username=username)

class DataRepresentationManager(models.Manager):
    """The Manager for the DataRepresentationManager-model."""

    def structured_data_representations(self):
        """
        Returns all the data representations in a structured way.
        They are organised by the location_type and theme_type in a tree structure.
        The return value is a dictionary (with the location_type as key),
        containing dictionaries (with the theme_type as key),
        containing the set of belonging data_representations.
        """

        structured_result = dict()
        data_representations = self.all()

        # go through all data_representations
        for data_representation in data_representations:

            # get the existing location_dict from the structured_result or create it for the current location_type
            location_dict = dict()
            if data_representation.location_type in structured_result:
                location_dict = structured_result[data_representation.location_type]
            else:
                structured_result[data_representation.location_type] = location_dict

            # get the existing theme_set from the location_dict or create it for the current theme_type
            theme_set = set()
            if data_representation.theme_type in location_dict:
                theme_set = location_dict[data_representation.theme_type]
            else:
                location_dict[data_representation.theme_type] = theme_set

            # add the data_representation to the theme_set
            theme_set.add(data_representation)

        return structured_result

class UserDataRepresentationManager(models.Manager):
    """The Manager for the UserDataRepresentationManager-model."""

    def create_user_data_representation(self, data_representation, user):
        """Creates and returns a new UserDataRepresentation in the Database from a given DataRepresentation and user."""

        # get the time and end_time attribute based on the time_type
        time = None
        end_time = None
        if data_representation.time_type == user_models.DataRepresentation.TimeChoices.TIME:
            time = timezone.now()
        elif data_representation.time_type == user_models.DataRepresentation.TimeChoices.PERIOD:
            time = timezone.now() - datetime.timedelta(weeks=4)
            end_time = timezone.now()

        # get the right location based on the location_type
        ward = None
        room = None
        if data_representation.location_type == user_models.DataRepresentation.LocationChoices.WARD:
            ward = hospital_models.Ward.objects.first()
        elif data_representation.location_type == user_models.DataRepresentation.LocationChoices.ROOM:
            room = hospital_models.Room.objects.first()

        # get a new order based on the greatest used order from the user
        max_order = user_models.UserDataRepresentation.objects.filter(user=user).aggregate(max_order=models.Max('order'))['max_order']
        new_order = 0
        if max_order is not None:
            new_order = max_order + 1

        return self.create(time=time, end_time=end_time, order=new_order,
                           user=user, data_representation=data_representation,
                           ward=ward, room=room)


# Definition for a binary tree node.
from typing import Optional

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        self.recurse(root)
        return root

    def recurse(self, node):
        if node == None:
            return
        temp = node.left
        node.left = node.right
        node.right = temp
        self.recurse(node.left)
        self.recurse(node.right)


import joblib
import numpy as np
import os
data_name="p_superv"
input_file = f"data/{data_name}/features.npy"
len_file = f"data/{data_name}/features.length"
output_file = f"data/{data_name}/features.clusters"
km_file = "models/km100.bin"

km = joblib.load(km_file)

features = np.load(input_file)
with open(len_file, 'r') as f:
    lengths = f.read().split("\n")
lengths = [int(l) for l in lengths]
assert sum(lengths) == len(features)
features = np.split(features, np.cumsum(lengths)[:-1])
if os.path.exists(output_file):
    os.remove(output_file)
for f in features:
    clusters = km.predict(f)
    with open(output_file, 'a') as f:
        f.write(" ".join([str(c) for c in clusters]) + "\n")