import time
import random
import pygame
import sys
import os
import json
import gym
import numpy as np

from stable_baselines3 import A2C, PPO, DQN
from pygame_ped_env.entities.maskedDQN import MaskableDQN
from sb3_contrib.ppo_mask import MaskablePPO

from pygame.sprite import Sprite, Group, GroupSingle
from typing import Union, Sequence

import pygame_ped_env
from pygame_ped_env.entities.agents import (
    RLVehicle,
    KeyboardVehicle,
    KeyboardPedestrian,
    RandomPedestrian,
)

class RLCrossingSim(gym.Env):
    def __init__(
        self,
        sim_area,
        scenarioList: Union[None, Sequence[int]] = None,
        human_controlled_ped=False,
        human_controlled_car=False,
        headless=False,
        seed=1234,
        basic_model: any = None,
        attr_model: any = None,
        log_path=None,
        speed_coefficient=1.0,
        position_coefficient=1.0,
        steering_coefficient=1.0,
        device="cpu",
    ) -> None:
        super().__init__()
        # np.random.seed(seed)

        self.log_path = log_path
        self.parent_log_path = os.path.dirname(os.path.dirname(self.log_path))

        # whether to render or not
        self.headless = headless

        # whether to have shaped reward or not
        # true by default, scenario will change it in reset()
        self.simple_reward = True

        # reward weightings, used to adjust for repsonse data
        self.speed_coeff = speed_coefficient
        self.pos_coeff = position_coefficient
        self.steer_coeff = steering_coefficient

        # this varible structure allows for sim_area =/= screen_rect so events on edges
        # and spawn are not displayed as all display updates use screen_rect
        self.screen_rect = pygame.Rect((0, 0), sim_area)
        assert (
            self.screen_rect.w <= 1280
        ), "simulation must be less than 1280 pixels wide"
        assert self.screen_rect.h <= 720, "simulation must be less than 720 pixels high"
        assert self.screen_rect.w > self.screen_rect.h, "simulation must be portrait"

        # 150 is offscreen pixel buffer,
        # TODO: should be associated to agent sprite rect programatically
        # self.observation_space = gym.spaces.Box(
        #     low=-150, high=self.screen_rect.w + 150, shape=(14,)
        # )
        self.observation_space = gym.spaces.Box(low=-150, high=1280 + 150, shape=(14,))

        # (8 directions * 3 speeds) + 1 no_op action
        self.action_space = gym.spaces.Discrete(25)
        self.action_space.seed(seed)

        init_sprite = Sprite()
        init_sprite.model = None
        init_sprite.rect = pygame.Rect(0, 0, 0, 0)

        self.vehicle = GroupSingle(init_sprite)
        self.traffic = GroupSingle(init_sprite)
        self.pedestrian = GroupSingle(init_sprite)

        # hook to hold ped for saving if removed from env
        self.done_ped = None

        if scenarioList is not None:
            self.scenarioList = scenarioList
        else:
            self.scenarioList = [0]

        self.scenario = lambda: np.random.choice(self.scenarioList)
        self.info = {"num_steps": 0, "done_cause": ""}

        self.roads = Group()
        self.generateRoads()

        # if not self.headless:
        #     pygame.init()
        #     self.screen = pygame.display.set_mode(self.screen_rect.size)
        #     pygame.display.set_caption("PaAVI - Pedestrian Crossing Simulation")
        #     self.background = self.generateBackground()

        self.device = device

        self.modelA = self._load_model_from_string(attr_model)
        self.modelB = self._load_model_from_string(basic_model)

        self.training = not human_controlled_ped

        self.H_traj_path = os.path.join(self.parent_log_path, "human_car_trajectories")
        self.H_collect = human_controlled_car
        if self.H_collect:
            os.makedirs(self.H_traj_path, exist_ok=True)

        self.num_steps = 0

    def action_masks(self):
        mask = np.ones(self.action_space.n).astype(bool)
        for action in range(self.action_space.n):
            mapped_action = (
                self.vehicle.sprite.action_map[action % 8]
                * self.vehicle.sprite.speed_map[np.floor(action / 8)]
            )
            next_pos = self.vehicle.sprite.rect.center + mapped_action
            if not self.screen_rect.collidepoint(next_pos):
                mask[action] = False
            else:
                mask[action] = True

        return mask

    def get_max_reward(self, shaped_reward=True):
        # highest possible reward for both cases
        # returned as +ve value to make
        # reward for perfect performance = 0
        if not shaped_reward:
            return 3 * (self.screen_rect.w / 3)
        else:
            return np.sum(
                np.array(range(0, self.screen_rect.w, 3)) / self.screen_rect.w
            )

    def generateBackground(self):
        # Setting background image and scaling to window size
        bkgrd = pygame.Surface(self.screen_rect.size)
        width_divisor, height_divisor = 2, 2
        tile_width, tile_height = (
            self.screen_rect.w / width_divisor,
            self.screen_rect.h / height_divisor,
        )
        bkgrd_img = pygame.image.load(
            os.path.join(
                os.path.dirname(pygame_ped_env.__file__),
                "images/grass/ground_grass_gen_02.png",
            )
        ).convert()
        # bkgrd = pygame.transform.scale(bkgrd_img, (self.screen_rect.size))
        bkgrd_tile = pygame.transform.scale(bkgrd_img, (tile_width, tile_height))
        for i in range(width_divisor):
            for j in range(height_divisor):
                bkgrd.blit(bkgrd_tile, (tile_width * i, tile_height * j))

        # bkgrd = pygame.transform.scale(
        #     pygame.image.load("../images/intersection.png"), screen_rect.size
        # )

        return bkgrd

    def generateRoads(self):
        scale = (self.screen_rect.w / 5, self.screen_rect.h / 5)
        # fairly ineffecient TODO: refactor to road class for generality

        vertical_path = Sprite(self.roads)
        image = pygame.transform.scale(
            pygame.image.load(
                os.path.join(
                    os.path.dirname(pygame_ped_env.__file__),
                    "images/roads/roadPLAZA.tga",
                )
            ),
            scale,
        )
        image_tile = pygame.Surface((scale[0] / 2, scale[1] / 2))
        image_tile.blit(image, (0, 0), image_tile.get_rect())
        image_rect = image_tile.get_rect()
        surf = pygame.Surface((image_rect.w, self.screen_rect.h))
        for t in range(np.floor(self.screen_rect.h / image_rect.h).astype(int) + 1):
            surf.blit(image_tile, (0, t * image_rect.h))

        vertical_path.image = surf
        vertical_path.rect = vertical_path.image.get_rect()
        vertical_path.rect.midtop = (self.screen_rect.w / 2, 0)

        horizontal_road = Sprite(self.roads)
        image_tile = pygame.transform.scale(
            pygame.image.load(
                os.path.join(
                    os.path.dirname(pygame_ped_env.__file__),
                    "images/roads/roadEW.tga",
                )
            ),
            scale,
        )
        image_rect = image_tile.get_rect()
        surf = pygame.Surface((self.screen_rect.w, image_rect.h))
        for t in range(np.floor(self.screen_rect.w / image_rect.h).astype(int) + 1):
            surf.blit(image_tile, (t * image_rect.w, 0))

        horizontal_road.image = surf
        horizontal_road.rect = horizontal_road.image.get_rect()
        horizontal_road.rect.midleft = (0, self.screen_rect.h / 2)

    def get_reward(self, agent: RLVehicle):
        if isinstance(agent.sprite, KeyboardVehicle) or isinstance(
            self.pedestrian, KeyboardPedestrian
        ):
            done = False
            if pygame.sprite.spritecollide(agent.sprite, self.pedestrian, False):
                self.done_ped = self.pedestrian.sprite
                self.pedestrian.remove(self.pedestrian.sprite)
                self.info["done_cause"] = "hit_pedestrian"
                done = True
            if pygame.sprite.spritecollide(agent.sprite, self.traffic, True):
                self.info["done_cause"] = "hit_traffic"
                done = True
            rwd = 0.0
        elif self.simple_reward:
            rwd, done = self.get_simple_reward(agent)
            # rwd += 4
        else:
            # function for social rewards
            # speed_rwd, position_rwd, heading_rwd, collide_rwd, done = self.get_primitive_reward(agent)
            p_rwd, s_rwd, h_rwd, c_rwd, done = self.get_primitive_reward(agent)
            # linearly combine rewards
            # apply convex or concave adjustment, and then shift to [-1,0)
            rwd = (
                (np.power(p_rwd, self.pos_coeff) - 1)
                + (np.power(s_rwd, self.speed_coeff) - 1)
                + (np.power(h_rwd, self.steer_coeff) - 1)
                + c_rwd
            )
            if np.isnan(rwd):
                rwd = (p_rwd - 1) + (s_rwd - 1) + (h_rwd - 1) + c_rwd

        return rwd, done

    def get_simple_reward(self, agent: RLVehicle):
        done = False
        collide_rwd = 0  # 0 no collision, -1 offroad, -infty hit pedestrian

        # if run over pedestrian, give reward reduction and end episode
        if pygame.sprite.spritecollide(agent.sprite, self.pedestrian, False):
            self.done_ped = self.pedestrian.sprite
            self.pedestrian.remove(self.pedestrian.sprite)
            self.info["done_cause"] = "hit_pedestrian"
            return -np.infty, True

        on_road = 1
        if not pygame.sprite.spritecollide(agent.sprite, self.roads, False):
            on_road = -1

        # if we have reached the destination, give max rwd
        if agent.sprite.rect.collidepoint(
            pygame.Rect([agent.sprite.objective, (0, 0)]).center
        ):
            # rwd for hitting goal
            rwd = self.get_max_reward(self.simple_reward)
            self.info["done_cause"] = "objective_reached"
            done = True
        else:
            rwd = -4 + on_road

        return rwd, done

    def get_primitive_reward(self, agent: RLVehicle):
        done = False
        collide_rwd = 0  # 0 no collision, -1 offroad, -infty hit pedestrian

        # if run over pedestrian, give reward reduction and end episode
        if pygame.sprite.spritecollide(agent.sprite, self.pedestrian, False):
            self.done_ped = self.pedestrian.sprite
            self.pedestrian.remove(self.pedestrian.sprite)
            collide_rwd = -np.infty
            self.info["done_cause"] = "hit_pedestrian"
            done = True

        if not pygame.sprite.spritecollide(agent.sprite, self.roads, False):
            collide_rwd = -1
            # elif not pygame.sprite.spritecollide(agent.sprite, self.roads.lane, False):
            # collide_rwd = -0.5
            # self.info["done_cause"] = "off_road"

        # if we have reached the destination, give max rwd
        if agent.sprite.rect.collidepoint(
            pygame.Rect([agent.sprite.objective, (0, 0)]).center
        ):
            # rwd for hitting goal
            position_rwd = self.get_max_reward(self.simple_reward)
            self.info["done_cause"] = "objective_reached"
            done = True
        else:
            # rwd for distance to goal
            # max dist same for left and right by symmetry, so just use left
            # dist from midright to topleft same as from either right corner to midleft
            # +20 to allow for vehicle size/lane offset
            max_dist = (
                np.linalg.norm(self.screen_rect.midright, ord=1) + 20
            )  # ord=1 is manhattan distance
            position_rwd = (
                (max_dist - np.linalg.norm(agent.sprite.dist_to_objective(), ord=1))
                # +1e-15 to avoid 0 issues
                + 1e-15
            ) / max_dist

        # rewarded for going as fast as possible, speed as fraction of top speed
        speed_rwd = (
            np.maximum(
                np.abs(agent.sprite.moved[-1][0]), np.abs(agent.sprite.moved[-1][1])
            )
            / agent.sprite.speed
        )

        # movement vector magnitude for this action
        delta_rho_1 = np.hypot(agent.sprite.moved[-1][0], agent.sprite.moved[-1][1])

        # movement vector magnitude for previous action
        delta_rho_2 = np.hypot(agent.sprite.moved[-2][0], agent.sprite.moved[-2][1])

        # from angle between 2 vectors definition
        theta_s = np.arccos(
            np.clip(
                np.dot(agent.sprite.moved[-1], agent.sprite.moved[-2])
                / (
                    (delta_rho_1 * delta_rho_2) + 1e-15
                ),  # 1e-15 to avoid divide by zero
                -1.0,
                1.0,
            )  # clip to avoid round off error or +1e-15 taking arg out of arccos domain [-1,1]
        )
        # punishes proportionally for turning in this action
        heading_rwd = (np.pi - theta_s) / np.pi

        # catch any bad edge cases from calculations
        if any(np.isnan([position_rwd, speed_rwd, heading_rwd, collide_rwd])):
            print("primitive reward returned NaN")
            import pdb

            pdb.set_trace()

        return position_rwd, speed_rwd, heading_rwd, collide_rwd, done

    def step(self, action):
        if isinstance(action, dict):
            if isinstance(self.vehicle.sprite, KeyboardVehicle):
                self.vehicle.sprite.update()
            else:
                self.vehicle.sprite.act(self.modelL.predict(action["obs"]))
        else:
            self.vehicle.sprite.act(action)
            # self.vehicle.sprite.act([[6], None]) # just move right for testing without trained model
        # print(self.vehicle.sprite.rect)
        self.traffic.sprite.update(self.traffic_action)
        if pygame.sprite.spritecollide(self.traffic.sprite, self.vehicle, False):
            self.traffic.empty()
            self.traffic.add(Sprite())
            self.traffic.sprite.rect = pygame.Rect(0, 0, 0, 0)
        if pygame.sprite.spritecollide(self.traffic.sprite, self.pedestrian, False):
            self.done_ped = self.pedestrian.sprite
            self.pedestrian.remove(self.pedestrian.sprite)
            self.traffic.empty()
            self.traffic.add(Sprite())
            self.traffic.sprite.rect = pygame.Rect(0, 0, 0, 0)

        # add placeholder ped if its gone offscreen and been removed
        try:
            self.pedestrian.sprite.update()
        except:
            self.pedestrian.empty()
            self.pedestrian.add(Sprite())
            self.pedestrian.sprite.rect = pygame.Rect(0, 0, 0, 0)

        if not self.headless:
            self.render()

        obs = np.hstack(
            [
                [self.vehicle.sprite.rect],
                [self.traffic.sprite.rect],  # padding for single vehicle scenario
                [self.pedestrian.sprite.rect],
                [self.vehicle.sprite.objective],
            ],
        )
        try:
            self.traffic_action = self.traffic.sprite.model.predict(obs)
        except:
            self.traffic_action = None

        rwd, self.done = self.get_reward(self.vehicle)

        self.num_steps += 1
        self.info["num_steps"] = self.num_steps

        if self.num_steps > self.screen_rect.w:
            self.info["done_cause"] = "timed_out"
            self.done = True

        # remove vehicles once they drive offscreen and finish episode
        if not self.done:
            ### should be handled by valid_action_mask now ###

            veh_pos = self.vehicle.sprite.rect.center
            if not self.screen_rect.collidepoint(veh_pos):
                print("OFFSCREEN!!!")
                self.done = True
                # if isinstance(self.vehicle.sprite, KeyboardVehicle):
                #     rwd = 0.0
                # # if not roughly at destination then punish
                # elif not (
                #     self.vehicle.sprite.dist_to_objective() <= np.ones(2) * 3
                # ).all():
                #     rwd -= 3000
                # self.info["done_cause"] = "vehicle_offscreen"
                # self.done = True

            # if vehicle not done, check for ped offscreen
            if not self.screen_rect.contains(self.pedestrian.sprite):
                self.done_ped = self.pedestrian.sprite
                self.pedestrian.remove(self.pedestrian.sprite)

        if self.H_collect and self.done and self.scenarioName != "H2":
            # save trajectory
            os.makedirs(
                os.path.join(self.H_traj_path, self.scenarioName), exist_ok=True
            )
            save_path = os.path.join(
                self.H_traj_path,
                f"{self.scenarioName}",
                f"traj_{np.random.randint(5)}",
            )

            if isinstance(self.vehicle.sprite, KeyboardVehicle):
                self.vehicle.sprite.save(save_path)
            if isinstance(self.traffic.sprite, KeyboardVehicle):
                self.traffic.sprite.save(save_path)

            print(save_path)

        return obs, rwd, self.done, self.info

    def render(self):
        self.screen.blit(self.background, (0, 0))  # display background in simulation
        self.roads.draw(self.screen)
        self.vehicle.draw(self.screen)

        try:
            self.pedestrian.draw(self.screen)
        except:
            pass

        try:
            self.traffic.draw(self.screen)
        except:
            pass

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        pygame.display.update()

        # hacky way to have ~60 FPS TODO: implentment properly
        time.sleep(0.016)

    def reset(self, scenario: int = None):
        self.num_steps = 0

        if scenario is not None:
            scenario = self.scenario_map()[scenario]
        else:
            scenario = self.scenario_map()[self.scenario()]
        self.scenarioName = scenario["name"]
        self.info["scenario"] = self.scenarioName

        self.vehicle.empty()
        agent = scenario["agentSprites"][0]

        colours = [
            "blue",
            "silver",
            "white",
            "red",
            "yellow",
            "green",
            "brown",
            "orange",
        ]
        print(colours)
        random.seed(time.process_time())
        c = random.randint(0, 7)
        print(c)
        colour = colours[c]
        print(colour)

        if agent[0] == "R":
            agentL = RLVehicle.init_from_scenario(
                agent, self.screen_rect.size, headless=self.headless, colour=colour
            )
            agentL.model = self.modelA
            self.simple_reward = False
        elif agent[0] == "S":
            agentL = RLVehicle.init_from_scenario(
                agent[1:], self.screen_rect.size, headless=self.headless, colour=colour
            )
            agentL.model = self.modelB
            self.simple_reward = True
        else:
            if self.scenarioName == "H2":
                agentL = KeyboardVehicle.init_from_scenario(
                    agent,
                    self.screen_rect.size,
                    load_path=os.path.join(
                        self.H_traj_path,
                        "H_r",
                        f"traj_{np.random.randint(5)}",
                    ),
                    colour=colour,
                )
            elif self.H_collect:
                agentL = KeyboardVehicle.init_from_scenario(
                    agent,
                    self.screen_rect.size,
                    load_path=None,
                    colour=colour,
                )
            else:
                agentL = KeyboardVehicle.init_from_scenario(
                    agent,
                    self.screen_rect.size,
                    load_path=os.path.join(
                        self.H_traj_path,
                        self.scenarioName,
                        f"traj_{np.random.randint(5)}",
                    ),
                    colour=colour,
                )

            agentL.model = None

        self.modelL = agentL.model
        self.vehicle.add(agentL)

        self.traffic.empty()
        try:
            traffic_agent = scenario["agentSprites"][1]

            if traffic_agent[0] == "R":
                agentT = RLVehicle.init_from_scenario(
                    traffic_agent, self.screen_rect.size, headless=self.headless
                )
                agentT.model = self.modelA
            elif traffic_agent[0] == "S":
                agentT = RLVehicle.init_from_scenario(
                    traffic_agent[1:], self.screen_rect.size, headless=self.headless
                )
                agentT.model = self.modelB
            else:
                if self.scenarioName == "H2":
                    agentT = KeyboardVehicle.init_from_scenario(
                        traffic_agent,
                        self.screen_rect.size,
                        load_path=os.path.join(
                            self.H_traj_path,
                            "H_l",
                            f"traj_{np.random.randint(5)}",
                        ),
                    )
                elif self.H_collect:
                    agentT = KeyboardVehicle.init_from_scenario(
                        traffic_agent,
                        self.screen_rect.size,
                        load_path=None,
                    )
                    # if isinstance(agentL, KeyboardVehicle):
                    #     agentT.load(
                    #         os.path.join(
                    #             self.H_traj_path,
                    #             f"{self.scenarioName}",
                    #             f"traj_{np.random.randint(5)}",
                    #         )
                    #     ),

                else:
                    agentT = KeyboardVehicle.init_from_scenario(
                        traffic_agent,
                        self.screen_rect.size,
                        load_path=os.path.join(
                            self.H_traj_path,
                            f"{self.scenarioName}",
                            f"traj_{np.random.randint(5)}",
                        ),
                    )
                    # agentT.replay = True

                agentT.model = None
        except:
            agentT = Sprite()
            agentT.rect = pygame.Rect(0, 0, 0, 0)
            agentT.model = None

        self.modelT = agentT.model
        self.traffic.add(agentT)

        # add pedestrian, keyboard for experiment or random if just training or code evalling
        self.pedestrian.empty()
        if self.training or self.H_collect:
            self.pedestrian.add(
                RandomPedestrian(
                    # add slight noise in pedestrian start position
                    (self.screen_rect.w / 2) + (np.random.rand() * 4) - 2,
                    (self.screen_rect.h * (7 / 8)) + (np.random.rand() * 4) - 2,
                    "up",
                    headless=self.headless,
                )
            )
        else:
            self.pedestrian.add(
                KeyboardPedestrian(
                    self.screen_rect.w / 2, self.screen_rect.h * (7 / 8), "up"
                )
            )

        if not self.headless:
            pygame.init()
            self.screen = pygame.display.set_mode(self.screen_rect.size)
            pygame.display.set_caption("PaAVI - Pedestrian Crossing Simulation")
            self.background = self.generateBackground()
            # grey out screen and wait 1 second
            # on starting next scenario when rendering
            self.screen.fill([127, 127, 127])
            pygame.display.flip()
            time.sleep(1)

        try:
            self.traffic_action = self.traffic.sprite.model.predict(obs)
        except:
            self.traffic_action = None

        self.done = False
        obs = np.hstack(
            [
                [self.vehicle.sprite.rect],
                [self.traffic.sprite.rect],  # padding for single vehicle scenario
                [self.pedestrian.sprite.rect],
                [self.vehicle.sprite.objective],
            ],
        )

        return obs

    def run(self):
        # count = 0
        obs = self.reset()
        done = self.done
        while not done:
            # advance sim by one timestep
            obs, _, done, _ = self.step(self.vehicle.sprite.model.predict(obs)[0])

            # display the simulation
            if not self.headless:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        sys.exit()

                self.render()
        pygame.quit()

    def load_model(self, path):
        return self._load_model_from_string(path)

    def close(self, saveDir=None, info=None):
        if not self.headless:
            pygame.display.quit()
            pygame.quit()
            # sys.exit()

        if saveDir is None:
            saveDir = self.log_path

        try:
            self.traffic.sprite.save(os.path.join(saveDir, "second_vehicle_agent.pkl"))
            self.vehicle.sprite.save(os.path.join(saveDir, "first_vehicle_agent.pkl"))
        except:
            self.vehicle.sprite.save(os.path.join(saveDir, "vehicle_agent.pkl"))

        try:
            self.pedestrian.sprite.save(os.path.join(saveDir, "pedestrian.pkl"))
        except:
            self.done_ped.save(os.path.join(saveDir, "pedestrian.pkl"))

        if info is not None:
            with open(os.path.join(saveDir, "env_info.json"), "w+") as filePath:
                json.dump(info, filePath, ensure_ascii=False, indent=4)
                # json.dumps() # returns string obj and doesnt save

    @classmethod
    def init_scenario(cls, scenario, sim_area, **kwargs):
        # entities = []
        # scen = cls.scenario_map()[scenario]
        # for agent in scen.agentSprites:
        #     if agent[0] == "H":
        #         entities.append(RLVehicle.init_from_scenario(agent))
        #         kwargs["simple_reward"] = False
        #     elif agent[0] == "S":
        #         entities.append(RLVehicle.init_from_scenario(agent[1:]))
        #         kwargs["simple_reward"] = True
        #     else:
        #         entities.append(KeyboardVehicle.init_from_scenario(agent))

        # # add pedestrian
        # if training:
        #     entities.append(
        #         RandomPedestrian(sim_area[0] / 2, sim_area[1] * (7 / 8), "up")
        #     )
        # else:
        #     entities.append(
        #         KeyboardPedestrian(sim_area[0] / 2, sim_area[1] * (7 / 8), "up")
        #     )

        return (cls(sim_area, cls.scenario_map()[scenario].agentList, **kwargs),)

    def _load_model_from_string(self, path):
        name = path.split(os.sep)[-1].split("_")[0]
        if name == "dqn":
            alg = DQN
        elif name == "ppo":
            alg = PPO
        elif name == "a2c":
            alg = A2C
        elif name == "maskedDQN":
            alg = MaskableDQN
        elif name == "train":
            alg = MaskableDQN
        elif name == "maskedPPO":
            alg = MaskablePPO
        else:
            raise ValueError("Unknown model type: ", name)

        try:
            return alg.load(path, env=self, device=self.device)
        # if no or wrong model given
        except FileNotFoundError:
            # load default
            init_path = os.path.join(
                self.parent_log_path, "simple_reward_agent", f"{name}_init_model"
            )
            try:
                model = alg.load(init_path, env=self, device=self.device)
                print("No model found, loading default model")
                print("Loading default model from: ", init_path)
                return model
            # if no default exists make it
            except FileNotFoundError:
                model = alg(
                    "MlpPolicy",
                    self,
                    verbose=0,
                    tensorboard_log=os.path.join(
                        self.parent_log_path, "simple_reward_agent"
                    ),
                )
                model._setup_model()
                model.save(init_path, include="env")
                print("No model found, nor a default model of this algorithm.")
                print("Created default and saved to: ", init_path)

                return alg.load(init_path, env=self, device=self.device)

    @staticmethod
    def scenario_map():
        return {
            0: {
                "name": "RL_r",
                "agentSprites": ["RL_right"],
            },
            1: {
                "name": "RL_l",
                "agentSprites": ["RL_left"],
            },
            2: {
                "name": "RL2_r",
                "agentSprites": ["RL_right", "RL_left"],
            },
            3: {
                "name": "RL2_l",
                "agentSprites": ["RL_left", "RL_right"],
            },
            4: {
                "name": "RL_SRL_r",
                "agentSprites": ["RL_right", "SRL_left"],
            },
            5: {
                "name": "RL_SRL_l",
                "agentSprites": ["RL_left", "SRL_right"],
            },
            6: {
                "name": "RL_H_r",
                "agentSprites": ["RL_right", "H_left"],
            },
            7: {
                "name": "RL_H_l",
                "agentSprites": ["RL_left", "H_right"],
            },
            8: {
                "name": "SRL_r",
                "agentSprites": ["SRL_right"],
            },
            9: {
                "name": "SRL_l",
                "agentSprites": ["SRL_left"],
            },
            10: {
                "name": "SRL2_r",
                "agentSprites": ["SRL_right", "SRL_left"],
            },
            11: {
                "name": "SRL2_l",
                "agentSprites": ["SRL_left", "SRL_right"],
            },
            12: {
                "name": "SRL_RL_r",
                "agentSprites": ["SRL_right", "RL_left"],
            },
            13: {
                "name": "SRL_RL_l",
                "agentSprites": ["SRL_left", "RL_right"],
            },
            14: {
                "name": "SRL_H_r",
                "agentSprites": ["SRL_right", "H_left"],
            },
            15: {
                "name": "SRL_H_l",
                "agentSprites": ["SRL_left", "H_right"],
            },
            16: {
                "name": "H_r",
                "agentSprites": ["H_right"],
            },
            17: {
                "name": "H_l",
                "agentSprites": ["H_left"],
            },
            18: {
                "name": "H2",
                "agentSprites": ["H_right", "H_left"],
            },
        }


#Vivaan Gupta
#09/07/2021
#We are going to learn how to use a for loop

#Import Library
import os

#Use library to clear terminal
os.system('cls')

#Input number of stars
stars = int(input("How many stars do you want? "))
line=stars
space = 0   #Start number of spaces

# for i in range(line):
#     for counter in range(stars):
#         print("*", end=" ")
#     print()
#     stars = stars-1

# for line in range(stars):
#     for space in range(stars):
#         spaceText = "  "*space    #Turn the number of spaces into text
#         print(spaceText, end="")  #Print the spaces
#         space = space+1   #Increase number of spaces needed by 1
#         for counter in range(stars):
#             print("*", end=" ")   #Print number of stars
#         print()
#         stars=stars-1     #Decrease number of stars by 1

for line in range(stars):
    for counter in range(stars):    #Print stars
        print("*", end="")
    spaceText = " "*space
    print (spaceText, end="")   #Print number of spaces needed
    for counter in range(stars):
        print("*", end="")  #Print stars again
    print()
    space += 2  #Increase spaces by 2, shortcut for space = space + 2
    stars -= 1  #Decrease stars by 1, shortcut for stars = stars - 1

#Ending
print("Thank you!")


from pathlib import Path

def main():
    workingdirectory = Path.cwd()

    #here we define an empty array:
    newfilelist = []

    #languages is a python dictionary
    #left value is the abbreviation we have in our filesnames
    #right value is the function name in our code that handles that language
    languages = {
        'ToRu' : 'convertToRussian',
        'ToCs' : 'convertToCzech',
        'ToDe' : 'convertToGerman',
        'ToNl' : 'convertToDutch',
        'ToEs' : 'convertToSpanish'
    }

    #here we get a list of files from the inputfiles directory
    #and go through this list and examine each filename for signs that it needs special processing.
    for filename in workingdirectory.glob('InputFiles/*.txt'):

        #for each file we have, we don't yet know if we'll need all translations
        #so we will set this true for the file once here
        #and down below, if it becomes unnecessary, we will set it false below
        ThisFileNeedsAllTranslations = True

        #break the filename into it's pieces ie Catalog_ToRu becomes 2 pieces Catalog + ToRu
        parts = filename.stem.split("_")

        for part in parts:

            # here we compare the part we have
            # (for example 'Catalog' or 'Ru" to our languages dictionary we defined above)
            # to what is in the dictionary
            if part in languages:
                # - if it's found (ie ToRu)
                # we use the globals() functon of python to call the function listed in the dictionary
                # ex: if 'part' = 'ToRu' then [languages[part]] will be set to the string 'convertToRussia' and the globals function will call the convertToRussia
                globals()[languages[part]](filename)

                #since we called a specific language, we assume this file doesn't need all translations:
                ThisFileNeedsAllTranslations = False

        if ThisFileNeedsAllTranslations:
            convertToLanguages(filename, languages)

#end main function

#Conversion functions
#could these be reduced to a single function with the language passed in?
#perhapse the langage codes used by the translator could be the abbreviated codes used in the file names?
def convertToRussian(file):
    print("converting " + file.stem + " to Russian")
    #conversion logic here
    #create file.stem.mp3 in output directory

def convertToCzech(file):
    print("converting " + file.stem + " to Czech")
    #conversion logic here
    #create file.stem.mp3 in output directory

def convertToGerman(file):
    print("converting " + file.stem + " to German")
    #conversion logic here
    #create file.stem.mp3 in output directory

def convertToDutch(file):
    print("converting " + file.stem + " to Dutch")
    #conversion logic here
    #create file.stem.mp3 in output directory

def convertToSpanish(file):
    print("converting " + file.stem + " to Spanish")
    #conversion logic here
    #create file.stem.mp3 in output directory

def convertToLanguages(file,languages):
    print("well look here, we have a file that needs to be converted to ALL languages!")
    for languagefunction in languages.values():
        globals()[languagefunction](file)

main() #begin program by calling main function


import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, roc_auc_score, auc, confusion_matrix
import numpy as np
import re
import os

def print_confusion_as_csv(eng_abbrs, confusion_matrix):
    _confusion_matrix = confusion_matrix.tolist()

    LEN = len(eng_abbrs)
    print('-, ', end='')
    for abbr in eng_abbrs:
        print(abbr ,end=', ')
    print('')
    for i in range(LEN):
        print(eng_abbrs[i] ,end=', ')
        for j in range(LEN):
            print(_confusion_matrix[i][j] ,end=', ')
        print('')

def draw_auc(targets, predicts, savefig_filename='auc.png'):
    # print(savefig_filename)
    # print(targets)
    # print(predicts)
    fpr, tpr, threshold = roc_curve(targets, predicts)
    #print(fpr, tpr, threshold)

    auc1 = auc(fpr, tpr)
    ## Plot the result
    plt.title('Receiver Operating Characteristic')
    plt.plot(fpr, tpr, color = 'orange', label = 'AUC = %0.2f' % auc1)
    plt.legend(loc = 'lower right')
    plt.plot([0, 1], [0, 1],'r--')
    plt.xlim([0, 1])
    plt.ylim([0, 1])
    plt.ylabel('True Positive Rate')
    plt.xlabel('False Positive Rate')
    plt.savefig(savefig_filename)
    plt.close()

def total_hit_topk(outputs, label, k):
    hit = 0
    for row in range(len(outputs)):
        # top k
        _, indices = outputs[row].topk(k, dim = 0, largest = True, sorted = True)
        for j in range(len(indices)):
            if label[row][indices[j].item()].item() == 1.0:
                hit += 1
                break
    return hit

def cal_confusion_matrix(targets, predicts):
    target_class , predict_class = [], []
    for t,p in zip(targets, predicts):
        target_class.append(t.index(max(t)))
        predict_class.append(p.index(max(p)))

    cm = confusion_matrix(target_class, predict_class)

    return np.matrix(cm)

def output_predict_result_sgfs(stat, eng_abbrs, tags_ch):
    TagCPattern = '[^AP]C\[([^\]]*)\]'
    for i , (p,t,sgf) in enumerate(zip(stat['predicts'],stat['target'], stat['sgf'])):
        comment = re.findall(TagCPattern, sgf)[-1]
        sgfstr = sgf.replace(comment, 'predict:{}  target:{}'.format(tags_ch[ p.index(max(p)) ] ,tags_ch[t.index(max(t))]))

        with open(os.path.join('../tempsgf',str(i)+'.sgf'), 'w') as fout:
            fout.write(sgfstr)


"""
URL mappings for the user API.
"""
from django.urls import path

from modules.users import views

app_name = 'auth'

urlpatterns = [
    path('register/', views.CreateUserView.as_view(), name='register'),
    path('login/', views.CreateTokenView.as_view(), name='login'),
    path('logout/', views.LogoutUserView.as_view(), name='logout'),
    path('me/', views.ManageUserView.as_view(), name='me'),
]


n,c,k=map(int,input().split())
a=[int(input()) for _ in range(n)]

a.sort()
count=0
c_count=1
box=a[0]
for i in range(1,n):
    if c_count<c:
        if a[i]-box<=k:
            count+=1
            c_count+=1
        else:
            box=a[i]
            c_count=1
    else:
        box=a[i]
        c_count=1
    #print(count)
print(n-count)


import random
import numpy as np

from torch.utils.data.dataset import Dataset

from src.datasets.bengali import IMAGE_KEY, INPUT_KEYS
from src.utils.utils import rand_bbox, to_one_hot

class CutMixUpDataset(Dataset):
    def __init__(self,
                 dataset,
                 image_key,
                 input_keys,
                 num_classes,
                 num_mix=1,
                 beta=1.,
                 prob=1.0):

        self.dataset = dataset
        self.num_mix = num_mix
        self.beta = beta
        self.prob = prob

        self.image_key = image_key
        self.input_keys = input_keys
        self.num_classes = num_classes

    def __getitem__(self, index):
        sample = self.dataset[index]
        img = sample[self.image_key]

        for _ in range(self.num_mix):
            r = np.random.rand(1)
            if self.beta <= 0 or r > self.prob:
                continue

            # generate mixed sample
            lam = np.random.beta(self.beta, self.beta)
            rand_index = random.randint(a=0, b=len(self))

            sample_ = self.dataset[rand_index]
            img_ = sample_[self.image_key]

            height, width = img_.size()[-2:-1]

            l, t, r, b = rand_bbox(lam, height, width)

            sample[self.image_key][:, t:b, l:r] = \
                img_[self.image_key][:, t:b, l:r]

            lam = 1 - float((r - l) * (b - t)) / (height * width)

            for input_key, num_classes in zip(self.input_keys, self.num_classes):
                sample[input_key] = lam * to_one_hot(sample[input_key], num_classes) + \
                            (1. - lam) * to_one_hot(sample_[input_key], num_classes)
        return img

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


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

"""
Cloudformation Template Generation
"""

from troposphere_mate import (
    Template, Ref,
    sqs, iam, dynamodb, awslambda, events,
    canned,
    helper_fn_sub,
)

from seedinvest_monitor.devops.config_init import config

template = Template()

param_env_name = canned.parameter.param_env_name
template.add_parameter(param_env_name)

# -- declare aws resoure
iam_role_for_lbd_func = iam.Role(
    "IamRoleForLbdFunc",
    template=template,
    RoleName=helper_fn_sub("{}-lbd-execution", param_env_name),
    AssumeRolePolicyDocument=canned.iam.create_assume_role_policy_document([
        canned.iam.AWSServiceName.aws_Lambda,
    ]),
    ManagedPolicyArns=[
        canned.iam.AWSManagedPolicyArn.awsLambdaBasicExecutionRole,
        canned.iam.AWSManagedPolicyArn.amazonSQSFullAccess,
        canned.iam.AWSManagedPolicyArn.amazonDynamoDBFullAccess,
        canned.iam.AWSManagedPolicyArn.amazonS3FullAccess,
    ]
)

dynamodb_table_startup = dynamodb.Table(
    "DynamoDBTableStartup",
    template=template,
    TableName=helper_fn_sub("{}-startup", param_env_name),
    KeySchema=[
        dynamodb.KeySchema(
            AttributeName="id",
            KeyType="HASH",
        ),
    ],
    BillingMode="PAY_PER_REQUEST",
    AttributeDefinitions=[
        dynamodb.AttributeDefinition(
            AttributeName="id",
            AttributeType="S",
        ),
    ]
)

sqs_queue = sqs.Queue(
    "SQSQueueScheduler",
    template=template,
    QueueName=helper_fn_sub("{}-download-job", param_env_name),
    VisibilityTimeout=180,
)

#--- Lambda Function
aws_lambda_func_code = awslambda.Code(
    S3Bucket=config.S3_BUCKET_FOR_DEPLOY.get_value(),
    S3Key=config.LAMBDA_CODE_S3_KEY.get_value()
)
aws_lambda_layers = config.LAMBDA_LAYERS.get_value()
aws_lambda_environment = awslambda.Environment(
    Variables={
        k: v
        for k, v in config.to_dict(prefix="SEEDINVEST_MONITOR_").items()
        if isinstance(v, (str, int))
    },
)

lbd_func_update_new_project = awslambda.Function(
    "LbdFuncUpdateNewProject",
    template=template,
    FunctionName=helper_fn_sub("{}-update-new-project", param_env_name),
    Code=aws_lambda_func_code,
    Layers=aws_lambda_layers,
    Handler="seedinvest_monitor.handlers.update_new_project.handler",
    MemorySize=128,
    Timeout=120,
    Runtime="python3.6",
    Environment=aws_lambda_environment,
    Role=iam_role_for_lbd_func.iam_role_arn,
)

event_rule_update_new_project = events.Rule(
    "EventRuleUpdateNewProject",
    template=template,
    State="ENABLED",
    ScheduleExpression=config.UPDATE_NEW_PROJECT_RATE.get_value(),
    Targets=[
        events.Target(
            Id="EventRuleUpdateNewProject",
            Arn=lbd_func_update_new_project.lbd_func_arn,
        )
    ],
    DependsOn=[
        lbd_func_update_new_project,
    ]
)

lbd_permission_event_rule_update_new_project = awslambda.Permission(
    "LbdPermissionEventRuleUpdateNewProject",
    template=template,
    Action="lambda:InvokeFunction",
    FunctionName=lbd_func_update_new_project.lbd_func_arn,
    Principal="events.amazonaws.com",
    SourceArn=event_rule_update_new_project.event_rule_arn,
    DependsOn=[
        event_rule_update_new_project,
        lbd_func_update_new_project,
    ]
)

lbd_func_start_crawler = awslambda.Function(
    "LbdFuncStartCrawler",
    template=template,
    FunctionName=helper_fn_sub("{}-start-crawler", param_env_name),
    Code=aws_lambda_func_code,
    Layers=aws_lambda_layers,
    Handler="seedinvest_monitor.handlers.start_crawler.handler",
    MemorySize=128,
    Timeout=120,
    Runtime="python3.6",
    Environment=aws_lambda_environment,
    Role=iam_role_for_lbd_func.iam_role_arn,
)

event_rule_start_crawler = events.Rule(
    "EventRuleStartCrawler",
    template=template,
    State="ENABLED",
    ScheduleExpression=config.START_CRAWLER_RATE.get_value(),
    Targets=[
        events.Target(
            Id="EventRuleStartCrawler",
            Arn=lbd_func_start_crawler.lbd_func_arn,
        )
    ],
    DependsOn=[
        lbd_func_start_crawler,
    ]
)

lbd_permission_event_rule_start_crawler = awslambda.Permission(
    "LbdPermissionEventRuleStartCrawler",
    template=template,
    Action="lambda:InvokeFunction",
    FunctionName=lbd_func_start_crawler.lbd_func_arn,
    Principal="events.amazonaws.com",
    SourceArn=event_rule_start_crawler.event_rule_arn,
    DependsOn=[
        event_rule_start_crawler,
        lbd_func_start_crawler,
    ]
)

lbd_func_worker = awslambda.Function(
    "LbdFuncWorker",
    template=template,
    FunctionName=helper_fn_sub("{}-worker", param_env_name),
    Code=aws_lambda_func_code,
    Layers=aws_lambda_layers,
    Handler="seedinvest_monitor.handlers.worker.handler",
    MemorySize=128,
    Timeout=120,
    Runtime="python3.6",
    Environment=aws_lambda_environment,
    Role=iam_role_for_lbd_func.iam_role_arn,
)

sqs_event_source_mapping = awslambda.EventSourceMapping(
    "DownloaderLambdaEventMapping",
    template=template,
    BatchSize=10,
    Enabled=True,
    EventSourceArn=sqs_queue.sqs_queue_arn,
    FunctionName=Ref(lbd_func_worker),
    DependsOn=[
        sqs_queue,
        lbd_func_worker,
    ]
)

# --- post process ---
common_tags = {
    "ProjectName": config.PROJECT_NAME_SLUG.get_value(),
    "Stage": config.STAGE.get_value(),
    "EnvironmentName": config.ENVIRONMENT_NAME.get_value(),
}
template.create_resource_type_label()
template.update_tags(common_tags)


# @Time    : 2021/5/25 17:28
# @Author  : lucas
# @File    : auth_gitee_request.py
# @Project : SSO
# @Software: PyCharm
import requests
from request.auth_base_request import AuthBaseRequest
from auth_source import AuthSource
from utils.utils import build_url

class AuthGiteeRequest(AuthBaseRequest):
    # https://gitee.com/api/v5/oauth_doc#/
    source = AuthSource.GITEE

    def __init__(self, config):
        self.client_id = config.get("client_id")
        self.client_secret = config.get("client_secret")
        self.redirect_uri = config.get("redirect_uri")
        self.refresh_token = ""

    def get_access_token(self, code):
        body = {
            "grant_type": "authorization_code",
            "client_id": self.client_id,
            "redirect_uri": self.redirect_uri,
            "client_secret": self.client_secret,
            "code": code
        }
        response = requests.post(self.source.get("access_token"), json=body)
        result = response.json()
        self.refresh_token = result.get("refresh_token")
        return result.get("access_token")

    def get_user_info(self, access_token):
        params = {"access_token": access_token}
        response = requests.get(build_url(self.source.get("user_info"), params=params))
        result = response.json()
        return result

    def get_refresh_token(self):
        params = {"grant_type": "refresh_token",
                  "refresh_token": self.refresh_token}
        response = requests.get(build_url(self.source.get("access_token"), params=params))
        result = response.json()
        print(result)

    def authorize(self):
        params = {
            "client_id": self.client_id,
            "redirect_uri": self.redirect_uri,
            "response_type": "code"
        }
        return build_url(self.source.get("authorize"), params)

if __name__ == "__main__":
    from auth_config import AuthConfig
    gitee = AuthGiteeRequest(AuthConfig.GITEE)
    print(gitee.authorize())


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root is None:
            return []
        res = []
        deque = [root]  # 双端队列
        num = 1  # 第一层
        while deque:
            one_level_list = []
            size = len(deque)  # 每层的遍历次数

            for i in range(size):
                popnode = None
                if num % 2 == 1:  # 奇数层(遍历方向->)
                    popnode = deque.pop(0)
                    if popnode.left:
                        deque.append(popnode.left)
                    if popnode.right:
                        deque.append(popnode.right)
                else:  # 偶数层(遍历方向<-)
                    popnode = deque.pop()
                    if popnode.right:
                        deque.insert(0, popnode.right)
                    if popnode.left:
                        deque.insert(0, popnode.left)
                one_level_list.append(popnode.val)

            res.append(one_level_list)
            num += 1
        return res

103二叉树的锯齿形层序遍历.py


from pstack import  Circle

class Tire(Circle):
     'tires are circle with corrected parameters '

     def perimeter(self):
         return  Circle.perimeter(self) *1.25

if __name__ == '__main__':

    t= Tire(22)
    print( 'a tire of radius ',t.radius)
    print( 'has an area of ',t.area())
    print(' also an odometer corrected perimieter of ',)
    print( t.perimeter())


import sys

N,M = map(int,input().split())
name_list = {}
dcbo= []
for i in range(N+M):
    name = sys.stdin.readline().strip()
    if not name in name_list:
        name_list[name] = 1
    else:
        dcbo.append(name)

dcbo.sort()
print(len(dcbo))
for i in dcbo:
    print(i)


from MainControlLoop.lib.drivers.APRS import APRS
from MainControlLoop.lib.StateFieldRegistry import StateFieldRegistry, StateField, StateFieldRegistryLocker
from MainControlLoop.lib.modes import Mode
from MainControlLoop.tasks.APRS.actuate_task import APRSActuateTask, APRSCriticalMessage
from MainControlLoop.tasks.DownLinkProducer import DownLinkProducer

import re
from enum import Enum

class BeaconInterval(Enum):
    FAST = 30
    SLOW = 120
    CUSTOM = -1
    NEVER = 1

class APRSCommands(Enum):
    BEACON = r"TJ:C;APRS;beacon;;"
    BEACON_INTERVAL = r"TJ:C;APRS;beacon_interval;\d+;"
    SFR = r"TJ:C;APRS;SFR;;"
    SFR_TIME = r"TJ:C;APRS;SFR_time;\d+;"
    SF = r"TJ:C;APRS;SF;[\w\d_]+;"
    RESET = r"TJ:C;APRS;reset;;"

    ANTENNA_DEPLOY_INITIATED = r"pFS:AntennaDeployer;DEPLOYED;"

class APRSControlTask:

    def __init__(self, aprs: APRS, state_field_registry: StateFieldRegistry, locker: StateFieldRegistryLocker,
                 actuate_task: APRSActuateTask):
        self.aprs: APRS = aprs
        self.state_field_registry: StateFieldRegistry = state_field_registry
        self.locker = locker
        self.mode: Mode = Mode.BOOT

        self.actuate_task: APRSActuateTask = actuate_task

    def execute(self, commands):
        # TODO: control task logic HAS NOT been decided for boot/startup/safe mode

        current_sys_time: float = self.state_field_registry.get(StateField.TIME)
        command_joined = ''.join(commands)  # join all commands from list to single string

        if self.mode == Mode.SAFE:  # switch off beacon if in safe mode
            self.state_field_registry.update(StateField.APRS_BEACON_INTERVAL, BeaconInterval.NEVER.value)
            return

        if self.mode == Mode.STARTUP: # if in startup mode and antenna has been deployed, enable a critical message that the antenna has been deployed
            if re.search(APRSCommands.ANTENNA_DEPLOY_INITIATED.value, command_joined) is not None:
                self.actuate_task.set_critical_message(APRSCriticalMessage.ANTS_DEPLOYED)
                self.actuate_task.enable_critical_message()

        if self.mode == Mode.LOW_POWER:  # set beacon interval to slow if in low power mode
            self.state_field_registry.update(StateField.APRS_BEACON_INTERVAL, BeaconInterval.SLOW.value)

        if self.mode == Mode.COMMS:  # if in comms mode, turn off beacon, enable aprs to dump statefield
            self.state_field_registry.update(StateField.APRS_BEACON_INTERVAL, BeaconInterval.NEVER.value)

            dump = self.locker.find(current_sys_time)
            self.actuate_task.set_dump(dump)
            self.actuate_task.enable_dump()

        if self.mode == Mode.NORMAL:  # if in normal mode, set beacon interval to fast
            self.state_field_registry.update(StateField.APRS_BEACON_INTERVAL, BeaconInterval.FAST.value)

        if re.search(APRSCommands.SFR.value, command_joined) is not None:  # if sfr method is in command_joined, create  adump for the current statefield
            dump = DownLinkProducer.create_dump(self.state_field_registry)
            self.actuate_task.set_dump(dump)
            self.actuate_task.enable_dump()

        match = re.search(APRSCommands.SFR_TIME.value, command_joined)
        if match is not None: # if sfr time in command_joined, find previous dump and enable dunp
            cmd = command_joined[match.start(): match.end()]
            arg = cmd.split(";")[-2]
            timestamp = float('0' + re.sub(r"[^\d.]", '', arg))

            dump = self.locker.find(timestamp)
            self.actuate_task.set_dump(dump)
            self.actuate_task.enable_dump()

        match = re.search(APRSCommands.SF.value, command_joined)
        if match is not None:
            cmd = command_joined[match.start(): match.end()]
            arg = cmd.split(";")[-2]
            try:
                state_field = StateField(arg)
                response = DownLinkProducer.create_response(self.state_field_registry, state_field)
                if response != '':
                    self.actuate_task.set_response(response)
                    self.actuate_task.enable_response()
            except:
                pass

        if re.search(APRSCommands.RESET.value, command_joined) is not None:
            self.state_field_registry.update(StateField.APRS_BEACON_INTERVAL, BeaconInterval.NEVER)
            self.actuate_task.enable_reset()

        interval = self.state_field_registry.get(StateField.APRS_BEACON_INTERVAL)
        last_beacon_time: float = self.state_field_registry.get(StateField.APRS_LAST_BEACON_TIME)

        if current_sys_time - last_beacon_time > interval or re.search(APRSCommands.BEACON.value,
                                                                       command_joined) is not None:  # create a beacon with state field registry if over time interval or beacon value in command
            beacon = DownLinkProducer.create_beacon(self.state_field_registry)
            self.actuate_task.set_beacon(beacon)
            self.actuate_task.enable_beacon()


#### Pendiente:
#### - regla jq para tasa cae que esta en distintas posiciones
#### - solo se extrajo motos de calle hay que subir nivel tags
dirhtm = os.path.abspath(os.path.join(os.getcwd(),'../motos/html/'))
strfle = marcas["strmak05"]
strext = '.html'
xptmod = '//*[@id="home_micrositio"]/div/div/div/div/a'
xptitm = '//*[@id="home_micrositio"]/div/div/div/div/a'
xpttoc = '/html/body/div[2]/header/nav/div[4]/a'
xptbtn = '//*[@id="navbar"]/div/ul/li[3]/a'

#### Crear elementos lista 'www.honda.cl' {{{
lsttoc = browser.find_elements_by_xpath(xpttoc)
lstbtn = browser.find_elements_by_xpath(xptbtn)
lstmod = browser.find_elements_by_xpath(xptmod)
lstmod = lstmod[:8]
lstitm = browser.find_elements_by_xpath(xptitm)
for nummod in range(0,len(lstmod)):
    lstmod = browser.find_elements_by_xpath(xptmod)
    lstmod = lstmod[:8]
    lstmod[nummod].click()
    time.sleep(8)
    lstitm = browser.find_elements_by_xpath(xptitm)
    for numitm in range(0,len(lstitm)):
        lstitm = browser.find_elements_by_xpath(xptitm)
        lstitm[numitm].location_once_scrolled_into_view
        lstitm[numitm].click()
        time.sleep(10)
        # Escribir pagina a disco
        strfnm = str(dirhtm)+'/'+str(strfle)+'_'+str(nummod).zfill(2)+'_'+str(numitm).zfill(2)+'_'+time.strftime("%Y_%m_%d")+str(strext)
        strcnt = browser.page_source.encode('utf-8')
        with open(str(strfnm),'wb') as fle:
                fle.write(strcnt)
        # Regresar nivel 2
        browser.back()
        time.sleep(4)
    # Regresar nivel 1
    lsttoc = browser.find_elements_by_xpath(xpttoc)
    lsttoc[0].click()
    lstbtn = browser.find_elements_by_xpath(xptbtn)
    lstbtn[0].click()
    time.sleep(4)
#### }}}

#### Generar linea {{{
lstmod = browser.find_elements_by_xpath(xptmod)
lstmod = lstmod[:8]
lstlon = [None] * len(lstmod)
lstlin = [None] * len(lstmod)
for numlon in range(0,len(lstmod)):
    lstlon[numlon] = lstmod[numlon].get_attribute('href')
    lstlin[numlon] = re.search('.*\/(.*)', lstlon[numlon]).group(1)
#### }}}
browser.quit()


# - - coding:utf-8 - -
"""
# author: wktxzr
# Created Time : 20180503
# File Name: calculate_q_main.py
# Description:
计算IDF
"""

import os
import multiprocessing

CUR_PATH = os.path.split(os.path.realpath(__file__.split('/')[-1]))[0]
TOPICS = 'MB226 MB230 MB254 MB265 MB267 MB320 MB358 MB362 MB371 MB377 MB391 MB392 MB409 MB425'

def sys_order(topic):
	# 预处理后的推特数据
	data_path = CUR_PATH + '/init_data/'
	# 扩展词
	# dic[topic] = word_list
	topic_day_path = CUR_PATH + '/id_newsexword_dic_20.pkl'

	output_path = CUR_PATH + '/' + topic + '.pkl'

	order = 'python calculate_q.py' + ' -d ' + data_path + ' -o ' + \
	output_path + ' -i ' + topic_day_path +  ' -w ' + topic + ' -k ' + \
	k1 +  ' -b ' + b +  ' -v ' + avgdl
	os.system(order)

if __name__ == '__main__':
	pool = multiprocessing.Pool(processes = 7)
	topic_list = TOPICS.split(' ')
	for topic in topic_list:
		pool.apply_async(sys_order, args = (topic, ))
	pool.close()
	pool.join()
	# topic_list = TOPICS.split(' ')
	# for topic in topic_list:
	# 	sys_order(topic)


from typing import Union, Dict, List, AnyStr, Any, TextIO, Literal

import tempfile
import xmltodict

from commons import *
from varvault import ResourceNotFoundError

vault_file_new = f"{DIR}/new-vault.xml"
existing_vault = f"{DIR}/existing-vault.xml"

class XmlResource(varvault.BaseResource):

    KEY = "VAULT"

    def __init__(self, path: str, mode: Literal["r", "w", "a", "r+", "w+", "a+"] = "r"):
        self.file_io = None
        super(XmlResource, self).__init__(path, mode)

    @property
    def resource(self) -> TextIO:
        return self.file_io

    def create(self) -> None:
        """Creates the resource self.file_io for this handler which we'll use to read and write to."""
        path = self.path
        assert path, "Path is not defined"
        dirname = os.path.dirname(path)

        create_dir = lambda: os.makedirs(dirname, exist_ok=True) if dirname else None
        write = lambda: self.do_write({})

        if self.mode_properties.create and not self.mode_properties.load:
            create_dir()
            write()

        elif self.mode_properties.load and self.mode_properties.create:
            if not self.exists():
                create_dir()
                write()

        elif self.mode_properties.load and not self.mode_properties.create:
            try:
                self.do_read()
            except Exception as e:
                if not self.mode_properties.live_update:
                    raise ResourceNotFoundError(f"Unable to read from resource at {path} (mode is {self.mode})", self) from e
                else:
                    return
        else:
            raise NotImplementedError(f"Mode {self.mode} is not valid ({self.mode_properties})")

        self.file_io = open(self.path, "r+")
        self.file_io.close()

    @property
    def state(self):
        import hashlib
        hash_md5 = hashlib.md5()
        with open(self.path, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash_md5.update(chunk)
        return hash_md5.hexdigest()

    @property
    def path(self) -> Union[AnyStr, Any]:
        return self.raw_path

    def writable(self, obj: Dict) -> bool:
        obj = {self.KEY: obj}
        try:
            xmltodict.unparse(obj, pretty=True)
            return True
        except:
            return False

    def exists(self) -> bool:
        return os.path.exists(self.path)

    def do_write(self, vault: dict):
        # An XML file must have exactly one root. We assign the vault to the root self.KEY
        vault = {self.KEY: vault}
        xmltodict.unparse(vault, open(self.path, "w"), pretty=True)

    def do_read(self) -> Union[Dict, List]:
        vault = xmltodict.parse(open(self.path, "rb"))
        return vault[self.KEY]

class Keyring(varvault.Keyring):
    string_value = varvault.Key("string_value")
    int_value = varvault.Key("int_value")
    list_value = varvault.Key("list_value")

class TestXmlVault:
    @classmethod
    def setup_class(cls):
        tempfile.tempdir = "/tmp" if sys.platform == "darwin" or sys.platform == "linux" else tempfile.gettempdir()

    def setup_method(self):
        try:
            os.remove(vault_file_new)
        except:
            pass

    def test_create_xml_vault(self):
        vault = varvault.create(keyring=Keyring, resource=XmlResource(vault_file_new, mode="w"))

        @vault.manual(output=(Keyring.string_value, Keyring.int_value, Keyring.list_value))
        def _set():
            return "valid", 1, [1, 2, 3, 4, 5]

        _set()

        data_in_file = xmltodict.parse(open(vault_file_new, "rb"))[XmlResource.KEY]
        logger.info(data_in_file)
        assert Keyring.string_value in data_in_file and data_in_file[Keyring.string_value] == "valid"
        # XML data is actually just strings. But we still want to support using XML files, but it will take some manual labour to get it working correctly.
        assert Keyring.int_value in data_in_file and data_in_file[Keyring.int_value] == "1"
        assert Keyring.list_value in data_in_file

    def test_read_from_xml_vault(self):
        vault = varvault.create(keyring=Keyring, resource=XmlResource(existing_vault, "r"))

        @vault.manual(input=(Keyring.string_value, Keyring.int_value))
        def _get(string_value=None, int_value=None):
            assert string_value == "valid"
            assert int_value == "1"

        _get()