from typing import Any, Tuple

import torch
import torch.distributions as D
import torch.nn as nn
import torch.nn.functional as F

from ..tools import *
from .actorcritic import *
from .networks.common import *
from .math_functions import *
from .networks.encoders import *
from .networks.decoders import *
from .networks.rssm_component import *
from .networks.rssm import *
# from .rssm_simplified import RSSMCore, RSSMCell
from .probes import *
from .tools_v3 import *
from .networks import *
from .world_models import *

class Dreamer_agent(nn.Module):

    def __init__(self, conf,obs_space,act_space,step,device=None):
        super().__init__()
        assert conf.action_dim > 0, "Need to set action_dim to match environment"
        features_dim = conf.deter_dim + conf.stoch_dim * (conf.stoch_discrete or 1)
        self.iwae_samples = conf.iwae_samples
        self.imag_horizon = conf.imag_horizon
        if device:
            self._device=device
        else:
            self._device=conf.device

        # World model
        self.wm_type=conf.wm_type
        # if self.wm_type=='v2':
        self.wm = WorldModel(obs_space,step,conf,self._device)
        # elif self.wm_type=='v3':
            # self.wm = WorldModel_v3(obs_space,step,conf,self._device)

        # Actor critic

        # if self.wm_type=='v2':
        self.ac = ActorCritic(conf,self.wm,self._device)
        # elif self.wm_type=='v3':
        #     self.ac=ActorCritic_v3(conf,self.wm,self._device)
            #  self.ac = ActorCritic_v2(conf
            #                   )

        # Map probe

        # if conf.probe_model == 'map':
        #     probe_model = MapProbeHead(features_dim + 4, conf)
        # elif conf.probe_model == 'goals':
        #     probe_model = GoalsProbe(features_dim, conf)
        # elif conf.probe_model == 'map+goals':
        #     probe_model = MapGoalsProbe(features_dim, conf)
        # elif conf.probe_model == 'none':
        probe_model = NoProbeHead()
        # else:
        #     raise NotImplementedError(f'Unknown probe_model={conf.probe_model}')
        self.probe_model = probe_model
        self.probe_gradients = conf.probe_gradients

    def init_optimizers(self, lr, lr_actor=None, lr_critic=None, eps=1e-5,ac_eps=1e-5):
        if not self.probe_gradients:
            optimizer_wm = torch.optim.AdamW(self.wm.parameters(), lr=lr, eps=eps)
            optimizer_probe = torch.optim.AdamW(self.probe_model.parameters(), lr=lr, eps=eps)
            optimizer_actor = torch.optim.AdamW(self.ac.actor.parameters(), lr=lr_actor or lr, eps=ac_eps)
            optimizer_critic = torch.optim.AdamW(self.ac.critic.parameters(), lr=lr_critic or lr, eps=ac_eps)
            return optimizer_wm, optimizer_probe, optimizer_actor, optimizer_critic
        else:
            optimizer_wmprobe = torch.optim.AdamW(self.wm.parameters(), lr=lr, eps=eps)
            optimizer_actor = torch.optim.AdamW(self.ac.actor.parameters(), lr=lr_actor or lr, eps=ac_eps)
            optimizer_critic = torch.optim.AdamW(self.ac.critic.parameters(), lr=lr_critic or lr, eps=ac_eps)
            return optimizer_wmprobe, optimizer_actor, optimizer_critic

    def grad_clip(self, grad_clip, grad_clip_ac=None):
        if not self.probe_gradients:
            grad_metrics = {
                'grad_norm': nn.utils.clip_grad_norm_(self.wm.parameters(), grad_clip),
                'grad_norm_probe': nn.utils.clip_grad_norm_(self.probe_model.parameters(), grad_clip),
                'grad_norm_actor': nn.utils.clip_grad_norm_(self.ac.actor.parameters(), grad_clip_ac or grad_clip),
                'grad_norm_critic': nn.utils.clip_grad_norm_(self.ac.critic.parameters(), grad_clip_ac or grad_clip),
            }
        else:
            grad_metrics = {
                'grad_norm': nn.utils.clip_grad_norm_(self.wm.parameters(), grad_clip),
                'grad_norm_actor': nn.utils.clip_grad_norm_(self.ac.actor.parameters(), grad_clip_ac or grad_clip),
                'grad_norm_critic': nn.utils.clip_grad_norm_(self.ac.critic.parameters(), grad_clip_ac or grad_clip),
            }
        return grad_metrics

    def init_state(self, batch_size: int):
        return self.wm.init_state(batch_size)

    def inference(self,
                  obs: Dict[str, Tensor],
                  in_state: Any,
                  ) -> Tuple[D.Distribution, Any, Dict]:
        assert 'action' in obs, 'Observation should contain previous action'
        act_shape = obs['action'].shape
        assert len(act_shape) == 3 and act_shape[0] == 1, f'Expected shape (1,B,A), got {act_shape}'

        # Forward (world model)

        features, out_state = self.wm.forward(obs, in_state)

        # Forward (actor critic)
        if self.wm_type=='v2':

            feature = features[:, :, 0]  # (T=1,B,I=1,F) => (1,B,F) ## features.shape(1,1,1,2048)T*B*I*(D+S)
            action_distr=self.ac.forward_actor(feature)
            value=self.ac.forward_value(feature)
            metrics = dict(policy_value=value.detach().mean())
        elif self.wm_type=='v3':
            feature = features[:, :, 0]
            # feature = features[0, :, :] ##features.shape(1,1,1536)T*B*(D+S)
            action_distr = self.ac.forward_actor(feature)  # (1,B,A)
            value = self.ac.critic(feature)  # (1,B)
            metrics={}
            metrics.update(tensorstats(value.mode().detach(), "policy_value"))
            # metrics = dict(policy_value=value.detach().mean())
            # feature = features[:, :, 0]  # (T=1,B,I=1,F) => (1,B,F) ## features.shape(1,1,1,2048)T*B*I*(D+S)
            # action_distr=self.ac.forward_actor(feature)
            # value=self.ac.forward_value(feature)
            # metrics = dict(policy_value=value.detach().mean())

        return action_distr, out_state, metrics

    def training_step(self,
                      obs: Dict[str, Tensor],
                      in_state: Any,
                      iwae_samples: Optional[int] = None,
                      imag_horizon: Optional[int] = None,
                      do_open_loop=False,
                      do_image_pred=False,
                      do_dream_tensors=False,
                      ):
        assert 'action' in obs, '`action` required in observation'
        assert 'reward' in obs, '`reward` required in observation'
        assert 'reset' in obs, '`reset` required in observation'
        assert 'terminal' in obs, '`terminal` required in observation'
        iwae_samples = int(iwae_samples or self.iwae_samples)
        imag_horizon = int(imag_horizon or self.imag_horizon)
        T, B = obs['action'].shape[:2]
        I, H = iwae_samples, imag_horizon
        # print(T,B,I,H)
        # World model

        if self.wm_type=='v2':
            loss_model, features, states, out_state, metrics, tensors = \
                self.wm.training_step(obs,
                                    in_state,
                                    iwae_samples=iwae_samples,
                                    do_open_loop=do_open_loop,
                                    do_image_pred=do_image_pred)
        elif self.wm_type=='v3':
            # loss_model,features, post, context, metrics,tensors=self.wm.training_step(obs,do_image_pred=do_image_pred)
            # out_state={key: tensor[-1] for key, tensor in post.items()}
            loss_model, features, states, out_state, metrics, tensors = \
                self.wm.training_step(obs,
                                    in_state,
                                    iwae_samples=iwae_samples,
                                    do_open_loop=do_open_loop,
                                    do_image_pred=do_image_pred)

        # Map probe

        features_probe = features.detach() if not self.probe_gradients else features
        loss_probe, metrics_probe, tensors_probe = self.probe_model.training_step(features_probe, obs)
        metrics.update(**metrics_probe)
        tensors.update(**tensors_probe)

        # Policy

        in_state_dream: StateB = map_structure(states, lambda x: flatten_batch(x.detach())[0])
        # type: ignore  # (T,B,I) => (TBI)
        # if self.wm_type=='v2':
        features_dream, actions_dream, rewards_dream, terminals_dream, states_dream = \
        self.dream(in_state_dream, H, self.ac._conf.actor_grad == 'dynamics')  # (H+1,TBI,D)

        # elif self.wm_type=='v3':
        # #     # states=post
        # #     flatten = lambda x: x.reshape([-1] + list(x.shape[2:]))
        # #     in_state_dream = {k: flatten(v) for k, v in states.items()}
        # #     # in_state_dream={key: tensor[0] for key, tensor in states.items()}
        # #     # in_state_dream=map_structure(states, lambda x: flatten_batch(x.detach())[0])
        # # # Note features_dream includes the starting "real" features at features_dream[0]
        #     features_dream, actions_dream, rewards_dream, terminals_dream, states_dream = \
        #     self.dream(in_state_dream, H, self.ac._conf.actor_grad == 'dynamics')
            # states_dream={key: tensor.detach() for key, tensor in states_dream.items()}
        if self.wm_type=="v2":
            (loss_actor, loss_critic), metrics_ac, tensors_ac = \
                self.ac.training_step(features_dream.detach(),
                                    actions_dream.detach(),
                                    rewards_dream.mean.detach(),
                                    terminals_dream.mean.detach())
            # tensors.update(policy_value=unflatten_batch(tensors_ac['value'][0], (T, B, I)).mean(-1))
        elif self.wm_type=="v3":
            #  (loss_actor, loss_critic), metrics_ac, tensors_ac = \
            #     self.ac.training_step(features_dream.detach(),
            #                         actions_dream.detach(),
            #                         rewards_dream.mean.detach(),
            #                         terminals_dream.mean.detach(),
            #                         # states_dream
            #                         )
            (loss_actor, loss_critic), metrics_ac, tensors_ac = \
                self.ac.training_step(features_dream.detach(),
                                    actions_dream.detach(),
                                    rewards_dream.mode().detach(),
                                    terminals_dream.mode().detach())
            # tensors.update(policy_value=unflatten_batch(tensors_ac['value'][0], (T, B, I)).mean(-1))
        metrics.update(**metrics_ac)

        # Dream for a log sample.
        ## 扰动和刻意的action应该都可以在这里加。
        dream_tensors = {}
        if self.wm=="v2":
            if do_dream_tensors and self.wm.decoder.image is not None:
                with torch.no_grad():  # careful not to invoke modules first time under no_grad (https://github.com/pytorch/pytorch/issues/60164)
                    # The reason we don't just take real features_dream is because it's really big (H*T*B*I),
                    # and here for inspection purposes we only dream from first step, so it's (H*B).
                    # Oh, and we set here H=T-1, so we get (T,B), and the dreamed experience aligns with actual.
                    # 这里实际做的时候，T=1，只从第一步想象
                    in_state_dream: StateB = map_structure(states, lambda x: x.detach()[0, :, 0])  # type: ignore  # (T,B,I) => (B)
                    ## 基本上只改了这一步
                    # non_zero_indices = torch.nonzero(in_state_dream[1])

                    # print(non_zero_indices)
                    features_dream, actions_dream, rewards_dream, terminals_dream,states_dream = self.dream(in_state_dream, T - 1)  # H = T-1
                    # features_dream, actions_dream, rewards_dream, terminals_dream = self.dream_cond_action(in_state_dream, obs['action'])
                    image_dream = self.wm.decoder.image.forward(features_dream)
                    ## 拿Dreamer_agent的数据只训练actor_critic
                    # _, _, tensors_ac = self.ac.training_step(features_dream, actions_dream[1:,:,:], rewards_dream.mean, terminals_dream.mean, log_only=True)
                    _, _, tensors_ac = self.ac.training_step(features_dream, actions_dream, rewards_dream.mean, terminals_dream.mean, log_only=True)
                    # The tensors are intentionally named same as in tensors, so the logged npz looks the same for dreamed or not
                    # dream_tensors = dict(action_pred=actions_dream,  # first action is real from previous step
                    #                      reward_pred=rewards_dream.mean,
                    #                      terminal_pred=terminals_dream.mean,
                    #                      image_pred=image_dream,
                    #                      **tensors_ac)
                    dream_tensors = dict(action_pred=torch.cat([obs['action'][:1], actions_dream]),  # first action is real from previous step
                                        reward_pred=rewards_dream.mean,
                                        terminal_pred=terminals_dream.mean,
                                        image_pred=image_dream,
                                        **tensors_ac)
                    assert dream_tensors['action_pred'].shape == obs['action'].shape
                    assert dream_tensors['image_pred'].shape == obs['image'].shape
        elif self.wm_type=="v3":
            if do_dream_tensors:
                with torch.no_grad():  # careful not to invoke modules first time under no_grad (https://github.com/pytorch/pytorch/issues/60164)
                    # The reason we don't just take real features_dream is because it's really big (H*T*B*I),
                    # and here for inspection purposes we only dream from first step, so it's (H*B).
                    # Oh, and we set here H=T-1, so we get (T,B), and the dreamed experience aligns with actual.
                    # 这里实际做的时候，T=1，只从第一步想象
                    # in_state_dream={key: tensor[0] for key, tensor in states.items()}
                    in_state_dream: StateB = map_structure(states, lambda x: x.detach()[0, :, 0])
                    ## 基本上只改了这一步
                    # non_zero_indices = torch.nonzero(in_state_dream[1])

                    # print(non_zero_indices)
                    features_dream, actions_dream, rewards_dream, terminals_dream,states_dream = self.dream(in_state_dream, T - 1)  # H = T-1
                    # features_dream, actions_dream, rewards_dream, terminals_dream = self.dream_cond_action(in_state_dream, obs['action'])
                    image_dream = self.wm.decoder.image.forward(features_dream)
                    # image_dream = self.wm.decoder.image.forward(features_dream)
                    _, _, tensors_ac = self.ac.training_step(features_dream, actions_dream, rewards_dream.mode(), terminals_dream.mode(), log_only=True)
                    ## 拿Dreamer_agent的数据只训练actor_critic
                    # _, _, tensors_ac = self.ac.training_step(features_dream, actions_dream[1:,:,:], rewards_dream.mean, terminals_dream.mean, log_only=True)
                    # _, _, tensors_ac = self.ac.training_step(features_dream, actions_dream, rewards_dream.mean, terminals_dream.mean, log_only=True)
                    # (actor_loss,value_loss),features, states, actions, metrics=self.ac.training_step(features_dream.detach(),
                    #                 actions_dream.detach(),
                    #                 rewards_dream.detach(),
                    #                 terminals_dream.detach(),
                    #                 states_dream)
                    # The tensors are intentionally named same as in tensors, so the logged npz looks the same for dreamed or not
                    # dream_tensors = dict(action_pred=actions_dream,  # first action is real from previous step
                    #                      reward_pred=rewards_dream.mean,
                    #                      terminal_pred=terminals_dream.mean,
                    #                      image_pred=image_dream,
                    #                      **tensors_ac)
                    dream_tensors = dict(action_pred=torch.cat([obs['action'][:1], actions_dream]),  # first action is real from previous step
                                        reward_pred=rewards_dream.mode(),
                                        terminal_pred=terminals_dream.mode(),
                                        image_pred=image_dream,
                                        )
                    assert dream_tensors['action_pred'].shape == obs['action'].shape
                    assert dream_tensors['image_pred'].shape == obs['image'].shape
        if not self.probe_gradients:
            losses = (loss_model, loss_probe, loss_actor, loss_critic)
        else:
            losses = (loss_model + loss_probe, loss_actor, loss_critic)
        return losses, out_state, metrics, tensors, dream_tensors

    def dream_cond_action(self, in_state, actions, dynamics_gradients=False):
        features = []
        imag_horizon=actions.shape[0]-1
        state = in_state
        self.wm.requires_grad_(False)  # Prevent dynamics gradiens from affecting world model

        ## 如果想设计一些简单的任务，比如说一直往左转，那么可以在这里修改action的选取
        for i in range(imag_horizon):
            feature = self.wm.dynamics.to_feature(*state)
            # print(feature.shape)
            # action_dist = self.ac.forward_actor(feature)
            # if dynamics_gradients:
            #     action = action_dist.rsample()
            # else:
            #     action = action_dist.sample()
            features.append(feature)
            action=actions[i+1,:,:]
            # When using dynamics gradients, this causes gradients in RSSM, which we don't want.
            # This is handled in backprop - the optimizer_model will ignore gradients from loss_actor.
            _, state = self.wm.dynamics.cell.forward_prior(action, None, state)

        feature = self.wm.dynamics.to_feature(*state)
        features.append(feature)
        features = torch.stack(features)  # (H+1,TBI,D)
        # actions = torch.stack(actions)  # (H,TBI,A)

        rewards = self.wm.decoder.reward.forward(features)      # (H+1,TBI)
        terminals = self.wm.decoder.terminal.forward(features)  # (H+1,TBI)

        self.wm.requires_grad_(True)
        return features, actions, rewards, terminals

    def dream(self, in_state,imag_horizon: int, dynamics_gradients=False,perturb='None'):
        features = []
        actions = []
        states=[]
        state = in_state
        self.wm.requires_grad_(False)  # Prevent dynamics gradiens from affecting world model

        ## 如果想设计一些简单的任务，比如说一直往左转，那么可以在这里修改action的选取
        for i in range(imag_horizon):
            feature = self.wm.dynamics.to_feature(*state)
            if self.wm_type=='v2':
                action_dist = self.ac.forward_actor(feature)
            elif self.wm_type=="v3":
                # feature = self.wm.dynamics.to_feature(state)
                # feature=torch.cat((state[0], state[1]), -1)
                action_dist = self.ac.forward_actor(feature)
            if perturb=='guassian':
                # Get the batch shape and event shape of the given distribution.
                batch_shape = action_dist.batch_shape
                event_shape = action_dist.event_shape

                # Create a new standard normal distribution with the same structure.
                perturb_dist = torch.distributions.Normal(loc=torch.zeros(*batch_shape, *event_shape),
                                                    scale=torch.ones(*batch_shape, *event_shape))
                # perturb_dist =perturb_dist.to(action_dist.device)
                action=action_dist.sample()
                action=action+perturb_dist.sample().to(action.device)
            ## offline的情况
            elif perturb=='random_policy':
                # 需要生成的one-hot向量的形状
                action_sample=action_dist.sample()
                tensor_shape = action_sample.shape
                act_dim=action_sample.shape[1]

                # 生成一个介于[0, 18)的随机整数tensor，形状为(480, 4)
                random_indices = torch.randint(low=0, high=act_dim, size=(tensor_shape[0],))

                # 使用one_hot函数将随机整数tensor转换为one-hot编码
                action = F.one_hot(random_indices, num_classes=act_dim).to(torch.float32).to(action_sample.device)

                # 验证one_hot_tensor的形状

            ## '3' means be attacked
            elif perturb == 'attack_s':
                # Apply adversarial attack to the feature
                adversarial_feature = self.ac.adversarial_attack(feature,epsilon=0.2)

                # Compute action distribution for the adversarial feature
                action_dist_adv = self.ac.forward_actor(adversarial_feature)

                # Sample an action from the adversarial action distribution
                action = action_dist_adv.sample()
            elif perturb == 'attack_m':
                # Apply adversarial attack to the feature
                adversarial_feature = self.ac.adversarial_attack(feature,epsilon=0.8)

                # Compute action distribution for the adversarial feature
                action_dist_adv = self.ac.forward_actor(adversarial_feature)

                # Sample an action from the adversarial action distribution
                action = action_dist_adv.sample()
            elif perturb == 'attack_l':
                # Apply adversarial attack to the feature
                adversarial_feature = self.ac.adversarial_attack(feature,epsilon=2)

                # Compute action distribution for the adversarial feature
                action_dist_adv = self.ac.forward_actor(adversarial_feature)

                # Sample an action from the adversarial action distribution
                action = action_dist_adv.sample()
            elif perturb=='None':
                if dynamics_gradients:
                    action = action_dist.rsample()
                else:
                    action = action_dist.sample()
            features.append(feature)
            actions.append(action)
            states.append(state)
            # When using dynamics gradients, this causes gradients in RSSM, which we don't want.
            # This is handled in backprop - the optimizer_model will ignore gradients from loss_actor.
            # if self.wm_type=='v2':
            _, state = self.wm.dynamics.cell.forward_prior(action, None, state)
            # elif self.wm_type=='v3':
            #     state=self.wm.dynamics.img_step(state,action)

        # if self.wm_type=='v2':
            feature = self.wm.dynamics.to_feature(*state)
                # action_dist = self.ac.forward_actor(feature)
        # elif self.wm_type=="v3":
        #         feature = self.wm.dynamics.to_feature(state)
        #         # feature=torch.cat((state[0], state[1]), -1)
        #         # action_dist = self.ac.actor(feature)
        features.append(feature)
        states.append(state)
        features = torch.stack(features)  # (H+1,TBI,D)
        actions = torch.stack(actions)  # (H,TBI,A)
        # states=torch.stack(states)
        if self.wm_type=='v2':
            ##返回的是一个分布
            rewards = self.wm.decoder.reward.forward(features)      # (H+1,TBI)
            terminals = self.wm.decoder.terminal.forward(features)  # (H+1,TBI)
        elif self.wm_type=='v3':
            # rewards=self.wm.heads["reward"](features)
            # terminals=self.wm.heads["terminal"](features)
            rewards = self.wm.decoder.reward.forward(features)      # (H+1,TBI)
            terminals = self.wm.decoder.terminal.forward(features)  # (H+1,TBI)
            # # 获取字典中的键
            # keys =states[0].keys()

            # # 为每个键堆叠张量
            # states = {key: torch.stack([d[key] for d in states]) for key in keys}

        self.wm.requires_grad_(True)
        return features, actions, rewards, terminals,states

    def __str__(self):
        # Short representation
        s = []
        s.append(f'Model: {param_count(self)} parameters')
        if self.wm_type=='v2':
            for submodel in (self.wm.encoder, self.wm.decoder, self.wm.dynamics, self.ac, self.probe_model):
                if submodel is not None:
                    s.append(f'  {type(submodel).__name__:<15}: {param_count(submodel)} parameters')
        elif self.wm_type=="v3":
            for submodel in (self.wm.encoder, self.wm.decoder, self.wm.dynamics,self.ac):
                if submodel is not None:
                    s.append(f'  {type(submodel).__name__:<15}: {param_count(submodel)} parameters')
        return '\n'.join(s)

    def __repr__(self):
        # Long representation
        return super().__repr__()


import random
import argparse
from particle import Particle
from writer import write_particles, set_initial_filename
from yaml_parser import parse_yaml

parser = argparse.ArgumentParser(description="Generate initial conditions for N-Body simulation")
parser.add_argument("-f", "--file", help="Yaml file to read initial conditions from", type=str)
parser.add_argument("-r", "--random", help="Generate random initial conditions with N particles", type=int)
parser.add_argument("-o", "--output", help="Output file", type=str, default="initial.ibin")

args = parser.parse_args()

print(args)

set_initial_filename(args.output)

if args.file:
    parse_yaml(args.file)

elif args.random:
    particles = []
    for i in range(args.random):
        particles.append(
            Particle((random.randint(0, 800), random.randint(0, 800)), (random.randint(-10, 10), random.randint(-10, 10)),
                     random.randint(0, 5)))

    write_particles(particles)

else:
    from pygame_editor import run_editor
    run_editor()


# this file has two duties:
# 1. contain application factory
# 2. tells python flaskr directory should be treated as package
import os

from flask import Flask

# create_app is app factory function
# test_config can be passed to the factory
def create_app(test_config=None):
    # create and configure the app
    # create the flask instance
    # __name__ => name of current python module

    # instance_relative_config=True => config files are relative to instance folder
    # instance folder located outside flaskr package, can hold local data
    # that should not be commited to version control (config secrets/db file)
    app = Flask(__name__, instance_relative_config=True)

    # app.config.from_mapping() => sets default config app will use
    # dev should be overridden when deploying
    # DATABASE => path where SQLite db file will be saved
    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        # overrides the default config with values taken from config.py
        # ie when deploying, can be used to set real SECRET_KEY
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)

    # ensure the instance folder exists
    try:
        # os.makedirs() => ensures app.instance_path exists
        os.makedirs(app.instance_path)
    except OSError:
        pass

    # a simple page that says hello
    # creates connection between URL /hello and a function
    # that returns a response
    @app.route('/hello')
    def hello():
        return 'Hello, world!'

    return app


import torch
import torchvision as tv
import torchvision.transforms as transforms
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import TensorDataset
from torch.autograd import Variable

from torch.nn import functional as F

import numpy as np
import matplotlib.pyplot as plt

from Input_initiation import input_initiation
from Input_selection import input_selection
from GP_build import conf_build, ratio_build, opc_predict

import warnings
warnings.filterwarnings('ignore')

import time
import os

import kernel_matrix

'''
Input selection and build gaussian model for c and r = c'/c
'''

seed = 1
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)

np.random.seed(1)

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

class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # Convolution (In LeNet-5, 32x32 images are given as input. Hence
        # padding of 2 is done below)
        self.conv1 = torch.nn.Conv2d(
            in_channels=1, out_channels=6, kernel_size=5, stride=1, padding=2, bias=True)
        # Max-pooling
        self.max_pool_1 = torch.nn.MaxPool2d(kernel_size=2)
        # Convolution
        self.conv2 = torch.nn.Conv2d(
            in_channels=6, out_channels=16, kernel_size=5, stride=1, padding=0, bias=True)
        # Max-pooling
        self.max_pool_2 = torch.nn.MaxPool2d(kernel_size=2)
        # Fully connected layer
        self.fc1 = torch.nn.Linear(16 * 2 * 2, 120)
        self.fc2 = torch.nn.Linear(120, 84)
        self.fc3 = torch.nn.Linear(84, 10)

    def forward(self, x):
        x = torch.nn.functional.relu(self.conv1(x))
        x = self.max_pool_1(x)
        x = torch.nn.functional.relu(self.conv2(x))
        x = self.max_pool_2(x)
        x = x.view(x.size()[0], -1)
        x = torch.nn.functional.relu(self.fc1(x))
        x = torch.nn.functional.relu(self.fc2(x))
        x = self.fc3(x)

        return x
    # last layer output

    def hidden(self, x):
        x = torch.nn.functional.relu(self.conv1(x))
        x = self.max_pool_1(x)
        x = torch.nn.functional.relu(self.conv2(x))
        x = self.max_pool_2(x)
        x = x.view(x.size()[0], -1)
        x = torch.nn.functional.relu(self.fc1(x))
        x = torch.nn.functional.relu(self.fc2(x))

        return x

def orig_profit(model, x_test, y_test):
    # get confidence
    softmaxes = F.softmax(model.fc3(x_test), dim=1)
    confidences, predictions = torch.max(softmaxes, 1)
    predictions = predictions.detach().numpy()
    confidences = confidences.detach().numpy()
    y_test = y_test.detach().numpy()

    index = np.where(predictions != y_test)
    corr = np.sum(confidences[index] > 0.9)
    print('high mis is ', corr)
    index = np.where(predictions == y_test)
    incorr = np.sum(confidences[index] > 0.9)
    print('high correct is ', incorr)

    deter = predictions == y_test
    score = np.square(deter - confidences)
    bs = np.mean(score)
    print('borel score is {}'.format(bs))
    acc = np.mean(deter)
    unc = acc * (1 - acc)
    print('uncertainy is {}'.format(unc))
    return corr, incorr, bs, unc

def calibrated_profit(model, clf, x_test, y_test, center_):
    softmaxes = F.softmax(model.fc3(x_test), dim=1)
    _, predictions = torch.max(softmaxes, 1)
    predictions = predictions.detach().numpy()
    y_test = y_test.detach().numpy()

    confidences, _ = opc_predict(model, clf, x_test, center_)
    indicate = predictions == y_test

    index = np.where(predictions != y_test)
    incorr = np.sum(confidences[index] > 0.9)
    # print('high mis is ', corr)
    index = np.where(predictions == y_test)
    corr = np.sum(confidences[index] > 0.9)
    # print('high correct is ', incorr)

    deter = predictions == y_test
    score = np.square(deter - confidences)
    bs = np.mean(score)
    # print('borel score is {}'.format(score))

    return corr, incorr, bs

def load_results(stat, init_size, final_size):
    orig_profit(model, x_test, y_test)

    corr, incorr, bs = 0, 0, 0
    for k in range(stat):
        ind = torch.load('exp_results/index-record/stat{0}.pt'.format(k))
        center_ind = ind[0:init_size]
        center_ = x_op[center_ind].detach().numpy()
        index = ind[0:final_size + init_size]
        x_select = x_op[index]
        y_select = y_op[index]
        select_index = index
        gp = ratio_build(model, x_op, x_select,
                         y_select, select_index, center_)

        c, i, b = calibrated_profit(model, gp, x_test, y_test, center_)
        corr += c
        incorr += i
        bs += b
    print('size is {0},high conf corr is {1}, high conf incorr is {2}, average bs is {3}'.format(
        final_size, corr / stat, incorr / stat, bs / stat))

if __name__ == '__main__':
    # load original model
    model_dir = 'model/LeNet-5.pth'
    model = Net()
    model.load_state_dict(torch.load(model_dir))

    # load operational test data
    x_test, y_test = torch.load('./data/test.pt')
    x_test = torch.FloatTensor(x_test)
    y_test = torch.LongTensor(y_test)
    x_test = torch.unsqueeze(x_test, dim=1)
    x_test, y_test = x_test.to(device), y_test.to(device)
    x_test = model.hidden(x_test)

    # load operational valid data
    x_valid, y_valid = torch.load('./data/valid.pt')
    x_valid = torch.FloatTensor(x_valid)
    y_valid = torch.LongTensor(y_valid)
    x_valid = torch.unsqueeze(x_valid, dim=1)
    x_op, y_op = x_valid.to(device), y_valid.to(device)
    x_op = model.hidden(x_op)

    stat = 8
    init_size = 10
    final_size = 600
    load_results(stat, init_size, final_size)


import math

from six import iteritems

PARAM_K1 = 1.5
PARAM_B = 0.75
EPSILON = 0.25

class BM25(object):
    """Implementation of Best Matching 25 ranking function.

    Attributes
    ----------
    corpus_size : int
        Size of corpus (number of documents).
    avgdl : float
        Average length of document in `corpus`.
    doc_freqs : list of dicts of int
        Dictionary with terms frequencies for each document in `corpus`. Words used as keys and frequencies as values.
    idf : dict
        Dictionary with inversed documents frequencies for whole `corpus`. Words used as keys and frequencies as values.
    doc_len : list of int
        List of document lengths.
    """

    def __init__(self, corpus):
        """
        Parameters
        ----------
        corpus : list of list of str
            Given corpus.

        """
        self.corpus_size = 0
        self.corpus = corpus
        self.avgdl = 0
        self.doc_freqs = []
        self.idf = {}
        self.doc_len = []
        self.nd = {}
        self._initialize(corpus)

    def _initialize(self, corpus):
        """Calculates frequencies of terms in documents and in corpus. Also computes inverse document frequencies."""
        nd = {}  # word -> number of documents with word
        num_doc = 0
        for document in corpus:
            self.corpus_size += 1
            self.doc_len.append(len(document))
            num_doc += len(document)

            frequencies = {}
            for word in document:
                if word not in frequencies:
                    frequencies[word] = 0
                frequencies[word] += 1
            self.doc_freqs.append(frequencies)

            for word, freq in iteritems(frequencies):
                if word not in nd:
                    nd[word] = 0
                nd[word] += 1

        self.avgdl = float(num_doc) / self.corpus_size
        # collect idf sum to calculate an average idf for epsilon value
        idf_sum = 0
        # collect words with negative idf to set them a special epsilon value.
        # idf can be negative if word is contained in more than half of documents
        negative_idfs = []
        for word, freq in iteritems(nd):
            idf = math.log(self.corpus_size - freq + 0.5) - math.log(freq + 0.5)
            self.idf[word] = idf
            idf_sum += idf
            if idf < 0:
                negative_idfs.append(word)
        self.average_idf = float(idf_sum) / len(self.idf)

        eps = EPSILON * self.average_idf
        for word in negative_idfs:
            self.idf[word] = eps

    def get_score(self, document, index):
        """Computes BM25 score of given `document` in relation to item of corpus selected by `index`.

        Parameters
        ----------
        document : list of str
            Document to be scored.
        index : int
            Index of document in corpus selected to score with `document`.

        Returns
        -------
        float
            BM25 score.

        """
        score = 0
        doc_freqs = self.doc_freqs[index]
        for word in document:
            if word not in doc_freqs:
                continue
            score += (self.idf[word] * doc_freqs[word] * (PARAM_K1 + 1)
                      / (doc_freqs[word] + PARAM_K1 * (1 - PARAM_B + PARAM_B * self.doc_len[index] / self.avgdl)))
            # score += self.idf[word] * doc_freqs[word]

        return score

    def get_scores(self, document):
        """Computes and returns BM25 scores of given `document` in relation to
        every item in corpus.

        Parameters
        ----------
        document : list of str
            Document to be scored.

        Returns
        -------
        list of float
            BM25 scores.

        """
        scores = [self.get_score(document, index) for index in range(self.corpus_size)]
        return scores

    def get_words_score(self,document, index):

        words_score = {}
        doc_freqs = self.doc_freqs[index]
        for word in document:
            if word not in doc_freqs:
                continue
            score = (self.idf[word] * doc_freqs[word] * (PARAM_K1 + 1)
                      / (doc_freqs[word] + PARAM_K1 * (1 - PARAM_B + PARAM_B * self.doc_len[index] / self.avgdl)))
            # score = self.idf[word] * doc_freqs[word]
            if word not in words_score:
                words_score[word] = score
            else:
                words_score[word] = max(words_score[word],score)
        word_score_tuples = [(word, score) for word, score in words_score.items()]
        word_score_tuples = sorted(word_score_tuples,key=lambda x:x[1],reverse=True)
        return word_score_tuples

    def get_keywords(self, index, mention_tokens):
        document = self.corpus[index]
        intersection = list(set(document).intersection(set(mention_tokens)))
        words_scores = self.get_words_score(intersection,index)
        keywords = [ws[0] for ws in words_scores if ws[1] > 0 ]
        return keywords


"""
week4 task for computer security practice course.

"""
import doctest
from turtle import pos

# Aux function
def decompose(msg:str) -> list:
    """
    Auxiliary function to decompose a message to a list of separated chars.
    """
    return ([msg[c:c+1] for c in range(0, len(msg), 1)])

# First task
def encrypt_by_add_mod(msg:str, key:int) -> str:
    """
    >>> encrypt_by_add_mod('Hello',123)
    'Ãàççê'
    >>> encrypt_by_add_mod(encrypt_by_add_mod('Hello',123),133)
    'Hello'
    >>> encrypt_by_add_mod(encrypt_by_add_mod('Cryptography',10),246)
    'Cryptography'
    """
    result=[]
    sub_message = decompose(msg)
    for char in sub_message:
        result.append((ord(char) + key) % 256)
        final = "".join([chr(c) for c in result])
    return final

# Second task
def encrypt_xor_with_changing_key_by_prev_cipher(msg:str, key:int, method:str) -> str:
    """
    >>> encrypt_xor_with_changing_key_by_prev_cipher('Hello',123,'encrypt')
    '3V:V9'
    >>> encrypt_xor_with_changing_key_by_prev_cipher(encrypt_xor_with_changing_key_by_prev_cipher('Hello',123,'encrypt'),123,'decrypt')
    'Hello'
    >>> encrypt_xor_with_changing_key_by_prev_cipher(encrypt_xor_with_changing_key_by_prev_cipher('Cryptography',10,'encrypt'),10,'decrypt')
    'Cryptography'
    """
    cipher, plain = [], []
    sub_message = decompose(msg)
    if method == "encrypt":
        # Encryption
        ctr = 1
        c1 = ord(sub_message[0]) ^ key
        cipher.append(c1)
        for m in sub_message[1:]:
            cipher.append(ord(m) ^ cipher[ctr-1])
            ctr += 1
        final_cipher = "".join([chr(c) for c in cipher])
        return final_cipher
    elif method == "decrypt":
        # Decryption
        ctr = 1
        rev_cipher = sub_message[::-1]
        last_m = ord(rev_cipher[0]) ^ ord(rev_cipher[1])
        plain.append(chr(last_m))
        for c in rev_cipher[1:]:
            if ctr == (len(rev_cipher)-1):
                plain.append(chr(ord(c) ^ key))
            else:
                plain.append(chr(ord(c) ^ ord(rev_cipher[ctr+1])))
            ctr += 1
        final_plain = "".join([m for m in plain[::-1]])
    else:
        return "Please enter a correct method. {encrypt/decrypt}"
    return final_plain

# auxiliary function
def break_me(s: str) -> list:
    """
    Auxiliary function to divide the string to multiple strings
    according to the definition.
    'abcdefghij' -> ['aei','bfj','cg','dh']
    """
    return [s[i::4] for i in range(5)]

# Third task
# def encrypt_xor_with_changing_key_by_prev_cipher_longer_key(msg: str, key_list: list, method: str) -> str:
#     """
#     >>> key_list = [0x20, 0x44, 0x54,0x20]
#     >>> encrypt_xor_with_changing_key_by_prev_cipher_longer_key('abcdefg', key_list, 'encrypt')
#     'A&7D$@P'
#     >>> encrypt_xor_with_changing_key_by_prev_cipher_longer_key('aaabbbb', key_list, 'encrypt')
#     'A%5B#GW'
#     >>> encrypt_xor_with_changing_key_by_prev_cipher_longer_key(
#     ...    encrypt_xor_with_changing_key_by_prev_cipher_longer_key('abcdefg',key_list,'encrypt'),
#     ...        key_list,'decrypt')
#     'abcdefg'
#     >>> encrypt_xor_with_changing_key_by_prev_cipher_longer_key(
#     ...    encrypt_xor_with_changing_key_by_prev_cipher_longer_key('Hellobello, it will work for a long message as well',key_list,'encrypt'),
#     ...        key_list,'decrypt')
#     'Hellobello, it will work for a long message as well'
#     """
#     result = []
#     new_keys = [int(str(k)[:2]) for k in key_list]
#     if method == "encrypt":
#        # TODO
#         for k in new_keys:
#             result.append(encrypt_xor_with_changing_key_by_prev_cipher(i, new_keys[k], "encrypt") for i in break_me(msg))
#         return result
#     elif method == "decrypt":
#         # TODO
#         return result
#     else:
#         return "Please enter a correct method. {encrypt/decrypt}"

#     return result

if __name__ == "__main__":
    doctest.testmod()

    # Debug section:
    # key_list = [0x20, 0x44, 0x54,0x20]
    # print(encrypt_xor_with_changing_key_by_prev_cipher_longer_key('abcdefg', key_list, 'encrypt'))


import os
from datetime import datetime
from airflow import DAG
from airflow.operators import update_sensor
from airflow.operators.bash_operator import BashOperator
from airflow.operators.email_operator import EmailOperator
from spark_bash_commands import convert_parquet, update_db

'''
Run the batch job using Airflow Scheduler
    1. Check if new xml files are updated
    2. If so, convert them into Parquet format
    3. Run the NLP processes and save the results to ES through Spark
    4. Email the engineer about the job completion
'''
email_address = os.environ["AIRFLOW_EMAIL"]

dag = DAG('Job_Posting_Scheduler',
          description = 'Update_the_job_postings',
          schedule_interval = '@once', # '@daily'
          start_date = datetime(2019, 10, 10), catchup = False)

check_new_data = update_sensor(task_id = 'check_for_new_file',
                               poke_interval = 60*60*23,
                               email_on_failure = True,
                               email = email_address,
                               dag = dag)

convert_to_parquet = BashOperator(task_id = 'convert_parquet',
                                  bash_command = convert_parquet,
                                  email_on_failure = True,
                                  email = email_address,
                                  dag = dag)

update_database = BashOperator(task_id = 'update_the_database',
                                  bash_command = update_db,
                                  email_on_failure = True,
                                  email = email_address,
                                  dag = dag)

email = EmailOperator(task_id = 'send_email',
                      to = email_address,
                      subject = 'Airflow Alert',
                      html_content=""" <h3> Database Updated </h3> """,
                      dag = dag)

check_new_data >> convert_to_parquet >> update_database >> email


#!/usr/bin/env python3.4
#
# author: maijiaheng
#
# PHE相关算法取自 data61/python-paillier 项目，url: https://github.com/data61/python-paillier
#
import math

import phe.encoding
from phe import paillier

class ExampleEncodedNumber(phe.encoding.EncodedNumber):
    BASE = 64
    LOG2_BASE = math.log(BASE, 2)

# 模拟客户端
class Client:
    # 必须定义密钥对
    def __init__(self, pub_key, pri_key, encrypted_x=None, encrypted_y=None):
        self.pub_key = pub_key
        self.pri_key = pri_key
        self.encrypted_x = encrypted_x
        self.encrypted_y = encrypted_y

    # 加密
    def encrypt(self, x, y):
        # 对加密数据进行编码包装，标识加密数据
        encoded_x = ExampleEncodedNumber.encode(self.pub_key, x)
        encoded_y = ExampleEncodedNumber.encode(self.pub_key, y)
        # 执行加密
        self.encrypted_x = self.pub_key.encrypt(encoded_x)
        self.encrypted_y = self.pub_key.encrypt(encoded_y)

    # 解密
    def decrypt(self, encrypted):
        return self.pri_key.decrypt_encoded(encrypted, ExampleEncodedNumber).decode()

    # 评估函数
    @classmethod
    def evaluate(cls, x, y):
        return x + y

    # 目标计算函数
    @classmethod
    def expect(cls, x, y):
        return x + y

# 模拟云服务
class Cloud:
    # 必须定义公钥与评估函数
    def __init__(self, pub_key, evaluate):
        self.pub_key = pub_key
        self.evaluate = evaluate

    # 模拟云服务计算
    def calculate(self, x, y):
        return self.evaluate(x, y)

def math_example(pub_key, pri_key, a, b, h=None):
    client = Client(pub_key, pri_key)
    # 客户端加密
    client.encrypt(a, b)
    cloud = Cloud(pub_key, Client.evaluate)
    # 云服务计算
    encrypted = cloud.calculate(client.encrypted_x, client.encrypted_y)
    # 客户端解密
    result = client.decrypt(encrypted)
    assert abs(Client.expect(p1, p2) - result) < 1e-15
    print("成功")

if __name__ == "__main__":
    print("生成密钥对...")
    public_key, private_key = paillier.generate_paillier_keypair()
    print("生成密钥对完毕")
    p1 = 102545 + (64 ** 8)
    p2 = 13254 + (8 ** 20)
    # 完成一次数学运算
    math_example(public_key, private_key, p1, p2)


# -*- coding: utf-8 -*-
"""
Created on Mon Nov  4 02:40:20 2019

@author: PaulGraham
"""
import numpy as np
class StumpClass:
    def __init__(self, data, labels, weights , midPoint):
        self.data = data #Data in R^[dim] and with a number of size "dataSize"
        self.labels = labels #The labels are either -1 or 1 and has size "dataSize"
        self.weights = weights #The weights are
        self.components = []
        self.dataSize , self.dim = data.shape
        self.params = [0,True,0]#The first component is the index, the second is true if reater than or equal to and the third component is the ineq condition
    def predict(self, data):
        final_loss = -1
        for index in range(self.dim):
            final_pred = []
            data_s = np.sort(data[:,index])#sort the data and looks at only the component labeled by "indez"
            if midPoint == True:
                data_s = 0.5 * (data_s[0:self.dataSize-1] + data_s[1:self.dataSize])
            for check in data_s:#Runs over all of the pieces of data
                temp_pred = 2 * (data_s >= check) - 1#This is a labeling with 1 if componenet is greater than datum
                temp_loss = (1/self.dataSize)*np.sum(np.multiply(self.weights , np.multiply(temp_pred , self.labels)))#This will add one
                #if label is accurate and subtract one if label is wrong
                if temp_loss >= final_loss:
                    final_loss = temp_loss
                    final_pred = temp_pred
                    self.params = [index , True , check]
                if -1 * temp_loss >= final_loss:
                    final_loss = -1 * temp_loss
                    final_pred = -1 * temp_pred
                    self.params = [index , False , check]
        return final_pred
    def getParams(self):
        return self.params


from color import random_color, random_color_range
from HelperFunctions import get_reasonable_speed, Faders, one_in

class Sparkles(object):
    def __init__(self, treemodel):
        self.name = "Sparkles"
        self.tree = treemodel
        self.sparkles = Faders(treemodel)
        self.speed = 0.3
        self.color = random_color()
        self.spark_num = self.tree.num_pixels / 20
        self.count = 0

    def next_frame(self):

        self.tree.black_all_cells()

        while True:

            while self.sparkles.num_faders() < self.spark_num:
                self.sparkles.add_fader(color=random_color_range(self.color, 0.05),
                                        pos=self.tree.rand_cell(),
                                        intense=0.01,
                                        growing=True,
                                        change=1.0 / get_reasonable_speed()
                                        )
            self.sparkles.cycle_faders()

            # Change the colors
            if one_in(100):
                self.color = random_color_range(self.color, 0.1)

            self.count += 1

            yield self.speed


import base64
import sys
import os

abspath = os.path.abspath(sys.argv[0])

dname = os.path.dirname(abspath)

os.chdir(dname)

def deobfuscateFile(inFile):
    buffer = inFile.read()
    finalFile = inflate(buffer)
    outFile = open(inFile.name+".inflated",'wb')
    print(outFile.name)
    outFile.write(finalFile)

if __name__ == "__main__":

    if len(sys.argv) > 1:
        for i, arg in enumerate(sys.argv):
            if i > 0:
                deobfuscateFile(open(arg,'rb'))
    else:
        filename = input("Enter path to the file:")
        deobfuscateFile(open(filename,'rb'))


'''
  풀이요약
    1. 0부터 최대 가능한 거리 distance까지 이분 탐색을 반복 수행하며, 중간 값을 가능한 최대 거리라 가정합니다.
    2. 중간 값보다 간격이 적은 바위들을 하나씩 제거하며 제거한 바위 수가 n과 동일할 경우 answer를 중간값으로 변경해줍니다.
'''
def solution(distance, rocks, n):
    answer = 0
    left, right = 0, distance
    rocks.append(distance)
    rocks.sort()

    while left <= right:
        mid = (left + right) // 2
        current, cnt = 0, 0

        for rock in rocks:
            if rock - current < mid:
                cnt += 1
                if cnt > n:
                    break
            else:
                current = rock
        if cnt > n:
            right = mid - 1
        else:
            left = mid + 1
            answer = mid

    return answer


import time
import cv2
import math
import numpy as np
from Person import *

class Camera(object):
    def __init__(self, input):

        #clock
        self.trustworth_time = 10 #moing queue1 to querue2 every 10s
        self.sys_clear_time = self.trustworth_time/2
        self.no_detection_time = time.time()

        self.input = input
        self.video = cv2.VideoCapture(self.input)
        # self.video.set(3,1280)
        # self.video.set(4,720)
        self.w = int(self.video.get(3))
        self.h = int(self.video.get(4))
        self.rangeLeft = int(1*self.w/8)
        self.rangeRight = int(7*self.w/8)
        self.midLine = int(4*self.w/8)

        self.start_time = time.time()
        self.entered = 0

        #queue1
        self.persons= []
        self.pid = 1
        self.check_key = True
        self.last_checklist = {}

        #queue2
        self.stable_persons= []
        self.stable_pid = 1
        self.stable_check_key = True
        self.stable_last_checklist = {}
        self.display_pid = []

        #queue3
        self.valid_persons = []

    def __del__(self):
        self.video.release()

    def frameDetections(self):
        return self.video.read()

    def fack_preson_check(self):
        #check every ppl location in every "sys_clear_time"
        '''

        '''
        if int(time.time() - self.start_time) % self.sys_clear_time == 0 and self.check_key == True:
            cur_checklist = {}
            cur_indexlist = {}
            for index, p in enumerate(self.persons):

                fix_dist = math.sqrt((p.getX())**2 + (p.getY())**2)
                cur_checklist["pid" + str(p.getId())] = fix_dist
                cur_indexlist["pid" + str(p.getId())] = index

            self.check_key = False
            for key in self.last_checklist.keys():
                try:
                    if cur_checklist[key] == self.last_checklist[key]:
                        print("[POP] pop q1 : ", key)
                        self.persons.pop(cur_indexlist[key])
                        cur_checklist.pop(key)

                        ## DEBUG:
                        #print("[INFO] stay in q1 pid = " , [k for k in cur_checklist.keys()])

                except Exception as e:
                    pass

            self.last_checklist = cur_checklist

        elif int(time.time() - self.start_time) % self.sys_clear_time != 0:
            self.check_key = True

    def stabel_fack_preson_check(self):
        #check every ppl location in every sys_clear_time
        if int(time.time() - self.start_time) % self.sys_clear_time == 0 and self.stable_check_key == True:
            cur_checklist = {}
            cur_indexlist = {}
            for index, p in enumerate(self.stable_persons):
                fix_dist = math.sqrt((p.getX())**2 + (p.getY())**2)
                cur_checklist["pid" + str(p.getId())] = fix_dist
                cur_indexlist["pid" + str(p.getId())] = index

            self.stable_check_key = False

            for key in self.stable_last_checklist.keys():
                try:
                    if cur_checklist[key] == self.stable_last_checklist[key]:

                        print("[MOVE] Q2 pid{} -> Q3".format(p.getId()))
                        p = self.stable_persons[cur_indexlist[key]]
                        p.updateLeavetime(time.time()-self.sys_clear_time) #update person leave time
                        self.stable_persons.pop(cur_indexlist[key])
                        cur_checklist.pop(key)
                        self.face_pool.pop(key) #clear face pool
                        self.entered += 1
                        self.valid_persons.append(p)

                except Exception as e:
                    pass

            self.stable_last_checklist = cur_checklist

        elif int(time.time() - self.start_time) % self.sys_clear_time != 0:
            self.stable_check_key = True

    def people_tracking(self, rects):

        '''
        if no detection longer than 3min flush system
        '''
        # if len(rects) == 0 and (time.time() - self.no_detection_time) > 180:
        #     self.persons = []
        #     self.stable_persons = []
        #     self.no_detection_time = time.time()
        #     print("[WARNING] no detection")

        self.display_pid = [] #fresh display list must here !!!!!
        for person in rects:
            xCenter, yCenter, w, h = person['rect']
            gender = person['gender']
            age = person['age']
            proj = person['project']
            new = True
            inActiveZone= xCenter in range(self.rangeLeft,self.rangeRight)

            """
            queue1
            """
            self.fack_preson_check()

            for index, p in enumerate(self.persons):
                #if person stay in frame over 5s
                if time.time()- p.getEnter_t() > self.trustworth_time:
                    print("[MOVE] q1 pid{} -> q2 pid{} ".format(p.getId(), str(self.stable_pid)))
                    p.updatePid(self.stable_pid) #replace the pid with new pid
                    self.stable_persons.append(p)
                    self.persons.pop(index) #pop person from the persons list
                    self.stable_pid += 1

                dist = math.sqrt((xCenter - p.getX())**2 + (yCenter - p.getY())**2)
                p.updateAttris(age, gender, proj)

                if dist <= w and dist <=h:
                    if inActiveZone:
                        new = False
                        self.display_pid.append([p.getId(), (10, 10, 200)]) #id, display color
                        p.updateCoords(xCenter,yCenter)
                        break
                    else:
                        try:
                            self.persons.pop(index)
                            print("[POP]  pid{} removed from q1".format(str(p.getId())))
                            self.last_checklist.pop("pid" + str(p.getId())) #pop last frame dict id --- > 1st then pop list
                        except Exception as e:
                            pass

            """
            queue2
            """
            self.stabel_fack_preson_check()
            for index, p in enumerate(self.stable_persons):
                dist = math.sqrt((xCenter - p.getX())**2 + (yCenter - p.getY())**2)
                p.updateAttris(age, gender, proj)
                if dist <= w and dist <=h:
                    if inActiveZone:
                        new = False
                        self.display_pid.append([p.getId(), (10, 200, 10)]) #id, display color
                        p.updateCoords(xCenter,yCenter)
                        break
                    else:
                        self.entered += 1 #count ppl in the area
                        try:
                            self.stable_last_checklist.pop("pid" + str(p.getId())) #pop last frame dict id --- > 1st then pop list
                        except Exception as e:
                            pass

                        print("[MOVE] q2 pid{} -> q3".format(p.getId()))
                        self.stable_persons.pop(index)
                        p.updateLeavetime(time.time()) #update person leave time
                        self.valid_persons.append(p)
            #make sure the total persons number wont excess the bounding box
            if new == True and inActiveZone and len(self.persons) + len(self.stable_persons) + 1 <= len(rects) :
                print("[CREAT] new pid" + str(self.pid))
                enter_t = time.time()
                p = Person(self.pid, xCenter, yCenter, enter_t)
                self.persons.append(p)
                self.pid += 1


import cv2
import numpy as np

def getContours(img, cThr=[100, 100], showCanny=False, minArea=1000, filter=0, draw=False):
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1)
    imgCanny = cv2.Canny(imgBlur, cThr[0], cThr[1])
    kernel = np.ones((5, 5))
    imgDial = cv2.dilate(imgCanny, kernel, iterations=3)
    imgThre = cv2.erode(imgDial, kernel, iterations=2)
    if showCanny: cv2.imshow('Canny', imgThre)

    # 寻找所有的外轮廓
    contours, hiearchy = cv2.findContours(imgThre, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    finalCountours = []
    # 遍历找到的轮廓
    for i in contours:
        area = cv2.contourArea(i)  # 轮廓的面积
        if area > minArea:  # 如果大于设置的最小轮廓值，就往下走
            peri = cv2.arcLength(i, True)  # 封闭的轮廓的长度
            approx = cv2.approxPolyDP(i, 0.02 * peri, True)  # 封闭轮廓的拐点
            bbox = cv2.boundingRect(approx)  # 找到边界框
            if filter > 0:  # 需不需要根据拐点个数进行过滤轮廓
                if len(approx) == filter:  # 拐点个数，面积，拐点位置，边界框，轮廓
                    finalCountours.append([len(approx), area, approx, bbox, i])
            else:
                finalCountours.append([len(approx), area, approx, bbox, i])
    finalCountours = sorted(finalCountours, key=lambda x: x[1], reverse=True)  # 根据轮廓大小进行从大到小的排序
    if draw:  # 是否要画出来轮廓
        for con in finalCountours:
            cv2.drawContours(img, con[4], -1, (0, 0, 255), 3)
    return img, finalCountours

# 四个点是随机的，于是重新排序
def reorder(myPoints):
    myPointsNew = np.zeros_like(myPoints)
    myPoints = myPoints.reshape((4, 2))
    add = myPoints.sum(1)
    myPointsNew[0] = myPoints[np.argmin(add)]
    myPointsNew[3] = myPoints[np.argmax(add)]
    diff = np.diff(myPoints, axis=1)
    myPointsNew[1] = myPoints[np.argmin(diff)]
    myPointsNew[2] = myPoints[np.argmax(diff)]

    return myPointsNew

def warpImg(img, points, w, h, pad=20):
    # print(points)
    points = reorder(points)
    pts1 = np.float32(points)
    pts2 = np.float32([[0, 0], [w, 0], [0, h], [w, h]])
    matrix = cv2.getPerspectiveTransform(pts1, pts2)
    imgWrap = cv2.warpPerspective(img, matrix, (w, h))
    imgWrap = imgWrap[pad:imgWrap.shape[0] - pad, pad:imgWrap.shape[1] - pad]

    return imgWrap

def findDis(pts1, pts2):
    return ((pts2[0] - pts1[0]) ** 2 + (pts2[1] - pts1[1]) ** 2) ** 0.5


"""
Student: Oliver Näslund
Mail: oliver.naslund@gmail.com
Reviewed by: Hannah M
Date reviewed: 16 Maj 2023
"""

import matplotlib.pyplot as plt
import random
from time import perf_counter as pc
from time import sleep as pause
from math import pi, gamma
import functools
import concurrent.futures as future

def pi_calc(n, plot=False):
    punkter_in_x = [] ; punkter_in_y = []
    punkter_ut_x = [] ; punkter_ut_y = []
    for i in range(n):
        x = random.uniform(-1, 1) ; y = random.uniform(-1,1)
        if x**2 + y**2 <= 1:
            punkter_in_x.append(x) ; punkter_in_y.append(y)
        elif x**2 + y**2 > 1:
            punkter_ut_x.append(x) ; punkter_ut_y.append(y)
    pie = 4*len(punkter_in_x)/n
    if plot:
        plt.plot(punkter_in_x, punkter_in_y, 'ro', markersize = 4)
        plt.plot(punkter_ut_x, punkter_ut_y, 'bo', markersize = 4)
        plt.show()
    return pie

def hypersphere(n, d, r=1):
    start = pc()
    vec_längder_in = list(filter(lambda x: x < 1, [functools.reduce(lambda x,y: x+y, map(lambda x: x**2, [random.uniform(0,1) for i in range(d)])) for e in range(n)]))
    end = pc()
    return (2**d)*len(vec_längder_in)/n, f'time: {round(end-start, 2)}'

def hypersphere_time(n, d, r=1, processes=10):
    start = pc()

    with future.ProcessPoolExecutor() as ex:
        #results = []
        #for _ in range(processes):
        #    results.append(ex.submit(hypersphere, int(n/processes), d, r)) #använd map
        results = ex.map(hypersphere, [int(n/processes) for i in range(processes)], [d for i in range(processes)])
        #results = [i.result() for i in results]
        results = [i[0] for i in results]

    end = pc()
   # print(f"Process took {round(end-start, 2)} seconds")
    return sum(results)/processes, f'time: {round(end-start, 2)}'

def hypersphere_exact(n, d, r=1):
    return (pi**(d/2)/(gamma(d/2 + 1)))*r**2

def main():
    print('----Calculation of pi with graphs (MA4:1.1)----')
    for i in [1000, 10000, 100000]:
        print(f'pi = {pi_calc(i, True)} for n = {i}')

    print('----Calculation hypersphere (MA4:1.2)----')
    print('Calculation (n,d) = (100000, 2)', hypersphere(100000, 2))
    print('Exact Calculation (n,d) = (100000, 2)', hypersphere_exact(100000, 2))
    print('Calculation (n,d) = (100000, 11)', hypersphere(100000,11))
    print('Exact Calculation (n,d) = (100000, 11)', hypersphere_exact(100000,11))

    print('----Multiprocessing calculation hypersphere (MA4:1.3)----')
    n = 1000000 ; d = 11
    print('Calculation hypersphere without multiprocessing: ', hypersphere(n,d)) #ca 29sec
    print('Exact calculation hypersphere: ',hypersphere_exact(n, d))
    print('Calculation hyperesphere with multiprocessing: ',hypersphere_time(n, d, 1, 10)) #ca 15 sec

    print('Done')

if __name__ == "__main__":
    main()


# 11780: 플로이드 2
n = int(input())
m = int(input())
inf = 1000000001
cost = [[inf]*(n+1) for _ in range(n+1)]
nxt = [[0]*(n+1) for _ in range(n+1)]

for _ in range(m):
	a,b,c = map(int,input().split(" "))
	if cost[a][b] > c:
		cost[a][b] = c
		nxt[a][b] = b

for city in range(1,n+1):
	for i in range(1,n+1):
		for j in range(1,n+1):
			if i != j and cost[i][j] > cost[i][city] + cost[city][j]:
				cost[i][j] = cost[i][city] + cost[city][j]
				nxt[i][j] = nxt[i][city]

for i in range(1,n+1):
	for j in range(1,n+1):
		if cost[i][j] == inf:
			print(0,end = ' ')
		else:
			print(cost[i][j],end = ' ')
	print()
for i in range(1,n+1):
	for j in range(1,n+1):
		if i == j:
			print(0)
		else:
			result = []
			start,end = i,j
			while start != end:
				result.append(start)
				start = nxt[start][end]
			result.append(end)
			print(len(result),end = ' ')
			for r in result:
				print(r,end = ' ')
			print()


from datetime import datetime, timedelta
import json
import logging
import requests
import magic
from tenacity import retry, stop_after_attempt, wait_exponential
from urllib.parse import urlunsplit

logger = logging.getLogger(__file__)

def get_api_url(site_config, url):
    print("GET_API_URL")
    print(url)
    if url.find("www.eea.europa.eu") > -1:
#        if url.find("/api/") > -1 and not url.find("www.eea.europa.eu/en") > -1:
        if url.find("/api/") > -1:
            return url

    if site_config.get("fix_items_url", None):
        if f'{site_config["fix_items_url"]["without_api"]}/' in url:
            url = url.replace(
                site_config["fix_items_url"]["without_api"],
                site_config["fix_items_url"]["with_api"],
            )
        if url == site_config["fix_items_url"]["without_api"]:
            url = site_config["fix_items_url"]["with_api"]
        return url

    if site_config["url_api_part"].strip("/") == "":
        return url

    if f'/{site_config["url_api_part"]}' in url:
        logger.info(
            "Found url_api_part (%s) in url: %s",
            site_config["url_api_part"],
            url,
        )
        return url

    url_parts = url.split("/")
    if "://" in url:
        url_parts.insert(3, site_config["url_api_part"])
    else:
        url_parts.insert(1, site_config["url_api_part"])

    print("/".join(url_parts))
    return "/".join(url_parts)

def get_no_api_url(site_config, url):
    print("GET_NO_API_URL")
    print(url)
    if site_config.get('url_to_parse', None):
        return site_config.get('url_to_parse', None)
    if site_config.get("fix_items_url", None):
        if f'{site_config["fix_items_url"]["without_api"]}/' in url:
            return url
        if f'{site_config["fix_items_url"]["with_api"]}/' in url:
            return url.replace(
                site_config["fix_items_url"]["with_api"],
                site_config["fix_items_url"]["without_api"],
            )
        with_api2 = site_config["fix_items_url"].get("with_api2", None)
        if with_api2 is not None and f"{with_api2}/" in url:
            return url.replace(
                site_config["fix_items_url"]["with_api2"],
                site_config["fix_items_url"]["without_api"],
            )
        if url in [site_config["fix_items_url"].get("without_api",""), site_config["fix_items_url"].get("with_api",""), site_config["fix_items_url"].get("with_api2", "")]:
            return site_config["fix_items_url"]["without_api"]

    url_parts = url.split("://")
    protocol = url_parts[0]
    url = url_parts[1]

    ret_url = "/".join(url.split("/" + site_config["url_api_part"] + "/"))

    # Handle languages
    if url.find("www.eea.europa.eu") > -1:
        if url.find("/api/") > -1:
            ret_url = "/".join(ret_url.split("/api/"))
    print(ret_url)
    return f"{protocol}://{ret_url}"

def build_queries_list(site_config, query_config):
    query_limit = ""
    if query_config.get("quick", False):
        today = datetime.now()
        yesterday = today - timedelta(1)
        query_limit = f"&modified.query:date={yesterday.strftime('%m-%d-%Y')}&modified.range=min"
    url = site_config["url"].strip("/")
    if site_config.get("fix_items_url", None):
        if site_config["fix_items_url"]["without_api"] in url:
            url = url.replace(
                site_config["fix_items_url"]["without_api"],
                site_config["fix_items_url"]["with_api"],
            )
    else:
        url_api_part = site_config["url_api_part"].strip("/")
        if url_api_part != "":
            url = f"{url}/{url_api_part}"
    ts = datetime.now().timestamp()
    if site_config.get("portal_types", None):
        # queries = []
        queries = [
            f"{url}/@search?b_size={query_config['query_size']}&metadata_fields=modification_date&metadata_fields=modified&show_inactive=true&sort_order=reverse&sort_on=Date&portal_type={portal_type}{query_limit}&ts={ts}"
            for portal_type in site_config["portal_types"]
        ]
        if site_config.get("languages", None):
            for language in site_config.get("languages"):
                queries.append(
                    f"{url}/{language}/@search?b_size={query_config['query_size']}&metadata_fields=modification_date&metadata_fields=modified&show_inactive=true&sort_order=reverse&sort_on=Date{query_limit}&ts={ts}"
                )
    else:
        queries = [
            f"{url}/@search?b_size={query_config['query_size']}&metadata_fields=modification_date&metadata_fields=modified&show_inactive=true&sort_order=reverse&sort_on=Date{query_limit}&ts={ts}"
        ]
    return queries

@retry(wait=wait_exponential(), stop=stop_after_attempt(3))
def request_with_retry(url, method="get", data=None):
    print("Query:")
    print(url)
    print("-------------")
    logger.info("Fetching %s", url)
    handler = getattr(requests, method)
    resp = ""
    try:
        resp = handler(
            url,
            headers={"Accept": "application/json"},
            data=json.dumps(data),
            timeout=120,
        )
        logger.info("Response: %s", resp.text)
    except:
        logger.info("Timeout")

    assert json.loads(resp.text)  # test if response is json
    logger.info("Response is valid json")

    return resp.text

def execute_query(query):
    while True:
        resp = request_with_retry(query)
        docs = json.loads(resp)
        for doc in docs["items"]:
            yield (doc)
        next_query = docs.get("batching", {}).get("next", False)
        if next_query:
            query_base = query.split("@search")[0].split("#")[0]
            next_query_base = next_query.split("@search")[0].split("#")[0]
            query = next_query.replace(next_query_base, query_base)
        else:
            break

def get_docs(query):
    docs = execute_query(query)
    for doc in docs:
        yield (doc)

def get_doc_from_plone(site_config, doc_id):
    url_with_api = get_api_url(site_config, doc_id)
    r_url = f"{url_with_api}?expand=object_provides&eea_index=1"
    if site_config.get("avoid_cache_api", False):
        dt = datetime.now()
        # dts = datetime.strptime(
        #         dt.split("T")[0], "%Y-%m-%d"
        #     )
        r_url = f"{r_url}&crawler={dt}"

    r = request_with_retry(r_url)

    return r

@retry(wait=wait_exponential(), stop=stop_after_attempt(5))
def scrape_with_retry(v, url, js=False):
    logger.info("Scraping url: %s", url)
    hc = v.get("headless_chrome").get("endpoint")
    if js:
        resp = requests.post(
            hc,
            headers={"Content-Type": "application/json"},
            data=f'{{"url":"{url}", "js":true,"raw":true}}',
        )
        downloaded = resp.text
        status = resp.status_code
        final_url = resp.headers.get("final_url", "")
    else:
        resp = requests.get(url)
        downloaded = resp.text
        status = resp.status_code
        final_url = resp.headers.get("final_url", "")

    if magic.from_buffer(downloaded) == "data":
        return {
            "downloaded": None,
            "status_code": status,
            "final_url": final_url.split("?scrape")[0],
        }

    logger.info("Downloaded: %s", downloaded)

    return {
        "downloaded": downloaded,
        "status_code": status,
        "final_url": final_url.split("?scrape")[0],
    }

def scrape(v, site_config, doc_id):
    url_without_api = get_no_api_url(site_config, doc_id)
    scrape = False
    s_url = ""
    scrape_with_js = False
    if site_config.get("scrape_pages", False):
        s_url = url_without_api
        scrape_with_js = site_config.get("scrape_with_js", False)
        scrape = True
    response = {}
    if scrape:
        if site_config.get("avoid_cache_web", False):
            dt = datetime.now()
            # dts = datetime.strptime(
            #         dt.split("T")[0], "%Y-%m-%d"
            #     )
            s_url = f"{url_without_api}?scrape={dt}"
        response = scrape_with_retry(v, s_url, scrape_with_js)
    return response

FIELD_MARKERS = {"file": {"content-type", "download", "filename"}}

def is_field_of_type(field, _type):
    if not isinstance(field, dict):
        return False

    if _type not in FIELD_MARKERS:
        return False

    return set(field.keys()).issuperset(FIELD_MARKERS[_type])

def fix_download_url(download_url, source_url):
    if "www.eea.europa.eu" in source_url:
        return download_url.replace("@@download", "at_download")
    return download_url

CONTENT_TYPES_TO_EXTRACT = [
    "application/msword",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "application/vnd.ms-word.document.macroEnabled.12",
]

def extract_attachments(json_doc, nlp_service_params, extract_pdf):

    url = json_doc["id"]
    params = nlp_service_params["converter"]

    logger.info("Extract attachments %s %s", json_doc, url)

    converter_dsn = urlunsplit(
        ("http", params["host"] + ":" + params["port"], params["path"], "", "")
    )

    text_fragments = []

    for name, value in json_doc.items():

        # if (
        #     is_field_of_type(value, "file")
        #     and value["content-type"] == "application/pdf"
        # ):
        extract_doc = False
        if is_field_of_type(value, "file"):
            if value["content-type"] == "application/pdf" and extract_pdf:
                extract_doc = True
            if value["content-type"] in CONTENT_TYPES_TO_EXTRACT:
                extract_doc = True

        if extract_doc:
            download_url = fix_download_url(value["download"], url)
            logger.info("Download url found: %s", download_url)
            try:
                resp = request_with_retry(
                    converter_dsn, "post", {"url": download_url}
                )
            except Exception:
                logger.exception("failed file extraction, retry")
                download_url = value["download"]
                logger.info("Retry with download url: %s", download_url)
                resp = request_with_retry(
                    converter_dsn, "post", {"url": download_url}
                )
            if isinstance(resp, str):
                resp = json.loads(resp)
            for doc in resp["documents"]:
                text_fragments.append(doc["text"].strip())

    text = "\n".join(text_fragments)

    logger.info("Retrieved file content: %r", text)

    return text

def extract_pdf(v, site_config, doc):
    pdf_text = ""
    nlp_service_params = v.get("nlp_services")
    should_extract_pdf = True

    if site_config.get("pdf_days_limit", 0) > 0:
        current_date = datetime.now()
        logger.info("CHECK DATE")
        mod_date_str = doc.get("modification_date", None)
        if mod_date_str:
            mod_date = datetime.strptime(
                mod_date_str.split("T")[0], "%Y-%m-%d"
            )
            logger.info(current_date)
            logger.info(mod_date)
            diff = current_date - mod_date
            delta = diff.days
            logger.info(delta)
            logger.info(site_config.get("pdf_days_limit"))
            if delta > site_config.get("pdf_days_limit"):
                should_extract_pdf = False
    # if should_extract_pdf:

    logger.info("EXTRACT DOCUMENT")
    logger.info(doc["id"])

    pdf_text = extract_attachments(doc, nlp_service_params, should_extract_pdf)

    return pdf_text


class Solution(object):
  def findIntegers(self, num):
    """
    :type num: int
    :rtype: int
    """
    n = bin(num)[2:][::-1]  # removes "0b"
    length = len(n)
    A = [1 for _ in range(length)]  # ends with 0
    B = [1 for _ in range(length)]  # ends with 1

    for i in range(1, len(n)):
      A[i] = A[i - 1] + B[i - 1]
      B[i] = A[i - 1]
    ans = A[-1] + B[-1]
    for i in range(length - 2, -1, -1):
      if n[i:i + 2] == "11":
        break
      if n[i:i + 2] == "00":
        ans -= B[i]
    return ans


#Question 1 solution
def hello_name(user_name):
    """Display a simple greeting."""
    print("Hello, " + user_name.title() + "!")

hello_name('joanne')

#Question 2 solution
odd_numbers = list(range(1,101,2))
print(odd_numbers)

#Question 3 solution
def max_num_in_list(a_list):
    max_num = max(a_list)
    return max_num

test = max_num_in_list([1,2,3,4,5,6])
print(max_num_in_list([1,2,3,4,5,6]))

#Question 4 solution
def is_leap_year(a_year):
    if a_year % 4 == 0 and a_year % 100 != 0:
        print(f'{a_year} is a leap year')
    elif a_year % 400 == 0:
        print(f'{a_year} is a leap year')
    else:
        a_year = False
        print(f'{a_year}')

# Question 4 1.b solution

def is_leap(a_year):
    if a_year % 4 == 0 or (a_year % 100 != 0):
        print(True)
    else:
        print(False)

is_leap_year(2019)

#Question 5 solution
def is_consecutive(a_list):
    i = 0
    status = True
    while i < len(a_list) - 1:
        if a_list[i] + 1 == a_list[i + 1]:
            i += 1
        else:
            status = False
            break
    print(status)

is_consecutive([0,1,2,3,4,5])


import sys
import xbmc
import xbmcgui

selectHeading       = 'Choose your test'
testList            = ['browse','browsemultiple','browsesingle','input',
                        'multiselect','notification','numeric','ok',
                        'textviewer','yesno']

def chooseYourTest():
    while True:
        testChosen = xbmcgui.Dialog().select(selectHeading, testList)
        if testChosen < 0:
            break
        elif testList[testChosen] == 'browse':
            testBrowse()
        elif testList[testChosen] == 'browsemultiple':
            testBrowseMultiple()
        elif testList[testChosen] == 'browsesingle':
            testBrowseSingle()
        elif testList[testChosen] == 'input':
            testInput()
        elif testList[testChosen] == 'multiselect':
            testMultiSelect()
        elif testList[testChosen] == 'notification':
            testNotification()
        elif testList[testChosen] == 'numeric':
            testNumeric()
        elif testList[testChosen] == 'ok':
            testOk()
        elif testList[testChosen] == 'textviewer':
            testTextViewer()
        elif testList[testChosen] == 'yesno':
            testYesNo()

# type : integer - the type of browse dialog.
#     - 0 : ShowAndGetDirectory
#     - 1 : ShowAndGetFile
#     - 2 : ShowAndGetImage
#     - 3 : ShowAndGetWriteableDirectory
# heading : string or unicode - dialog heading.
# shares : string or unicode - from sources.xml. (i.e. 'myprograms')
# mask : [optional] string or unicode - '|' separated file mask. (i.e. '.jpg|.png')
# useThumbs : [optional] boolean - if True autoswitch to Thumb view if files exist.
# treatAsFolder : [optional] boolean - if True playlists and archives act as folders.
# defaultt : [optional] string - default path or file.
# enableMultiple : [optional] boolean - if True multiple file selection is enabled. Is ignored if type is 0 or 3
# RETURN If enableMultiple is False (default): returns filename and/or path as a string
#           to the location of the highlighted item, or default value if canceled.
#       If enableMultiple is True: returns tuple of marked filenames as a string, or empty tuple if canceled
# SINCE (at least) 12.X Frodo
def testBrowse():
    xbmcgui.Dialog().browse(type=2,heading='Test browse',shares='files',
            mask='.png|.jpg|.jpeg|.gif',useThumbs=True,treatAsFolder=False,
            defaultt='special://',enableMultiple=True)

# type : integer - the type of browse dialog.
#     - 1 : ShowAndGetFile
#     - 2 : ShowAndGetImage
# heading : string or unicode - dialog heading.
# shares : string or unicode - from sources.xml. (i.e. 'myprograms')
# mask : [optional] string or unicode - '|' separated file mask. (i.e. '.jpg|.png')
# useThumbs : [optional] boolean - if True autoswitch to Thumb view if files exist (default=false).
# treatAsFolder : [optional] boolean - if True playlists and archives act as folders (default=false).
# defaultt : [optional] string - default path or file.
# RETURN tuple of marked filenames as a string, or empty tuple if canceled
# SINCE 13.X Gotham
def testBrowseMultiple():
    xbmcgui.Dialog().browseMultiple(type=1,heading='Test browsemultiple',
            shares='myprograms',useThumbs=True,defaultt='addons://sources/executable')

# type : integer - the type of browse dialog.
#    - 0 : ShowAndGetDirectory
#    - 1 : ShowAndGetFile
#    - 2 : ShowAndGetImage
#    - 3 : ShowAndGetWriteableDirectory
# heading : string or unicode - dialog heading.
# shares : string or unicode - from sources.xml. (i.e. 'myprograms')
# mask : [optional] string or unicode - '|' separated file mask. (i.e. '.jpg|.png')
# useThumbs : [optional] boolean - if True autoswitch to Thumb view if files exist (default=False).
# treatAsFolder : [optional] boolean - if True playlists and archives act as folders (default=False).
# defaultt : [optional] string - default path or file.
# RETURN filename and/or path as a string to the location of the highlighted item, or default value if canceled
# SINCE 13.X Gotham
def testBrowseSingle():
    xbmcgui.Dialog().browseSingle(type=1,heading='Test browsesingle',shares='files',
            mask='.jpg|.pdf|.txt',treatAsFolder=False,
            defaultt='special://masterprofile/script_data/XBMC Lyrics')

# heading : string - dialog heading.
# defaultt : [optional] string - default value. (default=empty string)
# type : [optional] integer - the type of keyboard dialog. (default=xbmcgui.INPUT_ALPHANUM)
#     - xbmcgui.INPUT_ALPHANUM (standard keyboard)
#     - xbmcgui.INPUT_NUMERIC (format: #)
#     - xbmcgui.INPUT_DATE (format: DD/MM/YYYY)
#     - xbmcgui.INPUT_TIME (format: HH:MM)
#     - xbmcgui.INPUT_IPADDRESS (format: #.#.#.#)
#     - xbmcgui.INPUT_PASSWORD (return md5 hash of input, input is masked)
# option : [optional] integer - option for the dialog.
#     - xbmcgui.PASSWORD_VERIFY (verifies an existing (default) md5 hashed password) for type xbmcgui.INPUT_PASSWORD
#     - xbmcgui.ALPHANUM_HIDE_INPUT (masks input) for type xbmcgui.INPUT_ALPHANUM
# autoclose : [optional] integer - milliseconds to autoclose dialog. (default=do not autoclose)
# RETURN the entered data as a string, or an empty string if canceled
# SINCE 13.X Gotham
def testInput():
    xbmcgui.Dialog().input(heading='Test input',defaultt='12:10',type=xbmcgui.INPUT_TIME,autoclose=0)

# heading : string or unicode - dialog heading.
# options : list of string - options to choose from.
# autoclose : [optional] integer - milliseconds to autoclose dialog. (default=do not autoclose)
# RETURN the selected items as a list of indices, or None if cancelled
# SINCE 16.X Jarvis
def testMultiSelect():
    xbmcgui.Dialog().multiselect(heading='Test multiselect',
            options=['Select 1', 'Select 2', 'Select 3', 'Choose me !'],autoclose=10000)

# heading : string - dialog heading.
# message : string - dialog message.
# icon : [optional] string - icon to use. (default xbmcgui.NOTIFICATION_INFO)
#   - xbmcgui.NOTIFICATION_INFO
#   - xbmcgui.NOTIFICATION_WARNING
#   - xbmcgui.NOTIFICATION_ERROR
# time : [optional] integer - time in milliseconds (default 5000)
# sound : [optional] bool - play notification sound (default True)
# SINCE 15.X Isengard
def testNotification():
    xbmcgui.Dialog().notification(heading='Test notification',message='Here is your notification message',
            icon=xbmcgui.NOTIFICATION_WARNING,time=6000,sound=False)

# type : integer - the type of numeric dialog.
#   - 0 : ShowAndGetNumber (default format: #)
#   - 1 : ShowAndGetDate (default format: DD/MM/YYYY)
#   - 2 : ShowAndGetTime (default format: HH:MM)
#   - 3 : ShowAndGetIPAddress (default format: #.#.#.#)
# heading : string or unicode - dialog heading.
# defaultt : [optional] string - default value.
# RETURN the entered value as a string (return default value if dialog is canceled)
# SINCE (at least) 12.X Frodo
def testNumeric():
    xbmcgui.Dialog().numeric(type=0,heading='Test numeric',defaultt='42')

# heading : string or unicode - dialog heading.
# line1 : string or unicode - line #1 multi-line text.
# line2 : [optional] string or unicode - line #2 text.
# line3 : [optional] string or unicode - line #3 text.
# RETURN True if 'Ok' was pressed, else False
# SINCE (at least) 12.X Frodo
def testOk():
    xbmcgui.Dialog().ok(heading='Test ok',line1='First line of text',line2='Second line of text',line3='Third line of text')

# heading : string or unicode - dialog heading.
# list : string list - list of items.
# autoclose : [optional] integer - milliseconds to autoclose dialog. (default=do not autoclose)
# RETURN the position of the highlighted item as an integer (return 1 for "option1")
# SINCE (at least) 12.X Frodo
def testSelect():
    xbmcgui.Dialog().select(heading='Test select',list=['option1', 'option2', 'option3'],autoclose=0)

# heading : string or unicode - dialog heading.
# text : string or unicode - text.
# SINCE 16.X Jarvis
def testTextViewer():
    xbmcgui.Dialog().textviewer(heading='Test textviewer',text='Some random text')

# heading : string or unicode - dialog heading.
# line1 : string or unicode - line #1 multi-line text.
# line2 : [optional] string or unicode - line #2 text.
# line3 : [optional] string or unicode - line #3 text.
# nolabel : [optional] label to put on the no button.
# yeslabel : [optional] label to put on the yes button.
# autoclose : [optional] integer - milliseconds to autoclose dialog. (default=do not autoclose)
# RETURN True if 'Yes' was pressed, else False
# SINCE (at least) 12.X Frodo
def testYesNo():
    xbmcgui.Dialog().yesno(heading='Test yesno',line1='First line',line2='Second line',line3='Third line',
            nolabel='nop',yeslabel='why not',autoclose=0)

### Start of script
if (__name__ == '__main__'):
    chooseYourTest()


import d2lzh as d2l
from mxnet import autograd, gluon, init, nd
from mxnet.gluon import nn, data as gdata, loss as gloss
import numpy as np
import time

def get_data_ch7():
    data = np.genfromtxt('data/airfoil_self_noise.dat', delimiter = '\t')
    data = (data - data.mean(axis=0)) / data.std(axis=0)
    return nd.array(data[:1500, : -1]), nd.array(data[:1500, -1])

features, labels = get_data_ch7()
print(features.shape)

def sgd(params, states, hyperparams):
    for p in params:
        p[:] -= hyperparams['lr'] * p.grad

def train_ch7(trainer_fn, states, hyperparams, features, labels, batch_size=10, num_epochs=2):
    # initialize model
    net, loss = d2l.linreg, d2l.squared_loss
    w = nd.random.normal(scale=0.01, shape=(features.shape[1], 1))
    b = nd.zeros(1)
    w.attach_grad()
    b.attach_grad()

    def eval_loss():
        return loss(net(features, w, b), labels).mean().asscalar()

    ls = [eval_loss()]
    data_iter = gdata.DataLoader(gdata.ArrayDataset(features, labels), batch_size, shuffle=True)
    for _ in range(num_epochs):
        start = time.time()
        for batch_i, (X, y) in enumerate(data_iter):
            with autograd.record():
                l = loss(net(X, w, b), y).mean() # use average loss
            l.backward()
            trainer_fn([w, b], states, hyperparams) # iter model params
            if(batch_i + 1) * batch_size % 100 == 0:
                ls.append(eval_loss()) # record the moment train loss per 100 samples

        # print ouput and draw
        print('loss: %f, %f sec per epoch' % (ls[-1], time.time() - start))
        d2l.set_figsize()
        d2l.plt.plot(np.linspace(0, num_epochs, len(ls)), ls)
        d2l.plt.xlabel('epoch')
        d2l.plt.ylabel('loss')

def train_sgd(lr, batch_size, num_epochs=2):
    train_ch7(sgd, None, {'lr':lr}, features, labels, batch_size, num_epochs)

# train_sgd(1, 1500, 6)
train_sgd(0.005, 1)


import time

def main():
	fractions = set()
	for num in xrange(10, 100):
		for den in xrange(10, 100):
			# Fractions ending in 0 are considered to be trivial, so we skip them
			if num % 10 == 0 and den % 10 == 0:
				continue

			# The fractions we are looking for are less than one in value
			# so let's skip the fraction in which num is equal or more than den
			if num >= den:
				continue

			num_s = str(num)
			den_s = str(den)

			for x in xrange(0, 2):
				for y in xrange(0, 2):

					# If the digits are not the same, we can not simplify them
					if num_s[x] != den_s[y]:
						continue

					# Find the new numerator and denominator after the 'simplification'
					num2 = float(num_s[1-x])
					den2 = float(den_s[1-y])

					if den2 != 0.0 and num2 / den2 == num / float(den):
						fractions.add((num, den))

	final_fraction = (1, 1)
	for fraction in fractions:
		final_fraction = (final_fraction[0] * fraction[0], final_fraction[1] * fraction[1])

	print("The result is %d/%d." % (final_fraction[0], final_fraction[1]))

if __name__ == '__main__':
	start = time.time()
	main()
	done = time.time()
	print("The solution took %.4f seconds to compute." % (done - start))


import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 添加一层神经层
def add_layer(inputs, in_size, out_size, activation_function=None):
    with tf.name_scope("layer"):
        with tf.name_scope("weights"):
            # 权重  矩阵
            Weights = tf.Variable(tf.random_normal([in_size, out_size]), name="W")
        with tf.name_scope("biasesa"):
            # 推荐值不为0
            biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name="b")
        with tf.name_scope("Wx_plus_b"):
            # 没激活的值
            Wx_plus_b = tf.add(tf.matmul(inputs, Weights), biases)
        # 激活函数执行
        if activation_function is None:
            outputs = Wx_plus_b
        else:
            outputs = activation_function(Wx_plus_b)
        return outputs

if __name__ == '__main__':
    x_data = np.linspace(-1, 1, 300)[:, np.newaxis]
    noise = np.random.normal(0, 0.05, x_data.shape)
    y_data = np.square(x_data) - 0.5 + noise

    # plt.scatter(y_data)
    with tf.name_scope("inputs"):
        xs = tf.placeholder(tf.float32, [None, 1], name="x_input")
        ys = tf.placeholder(tf.float32, [None, 1], name="y_input")
    # 输入层
    l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu)

    # 输出层
    predition = add_layer(l1, 10, 1, activation_function=None)
    with tf.name_scope("loss"):
        # loss = tf.square(y_data-predition)
        loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - predition), reduction_indices=[1]))
    with tf.name_scope("train"):
        train_step = tf.train.AdamOptimizer(0.1).minimize(loss)
    init = tf.initialize_all_variables()

    sess= tf.Session()
    writer=tf.summary.FileWriter("logs/",sess.graph)
#     python C:\Users\goldwind\AppData\Roaming\Python\Python36\site-packages\tensorboard\main.py --logdir=logs

莫烦课程学习/可视化练习2.py