import math

import torch
import torch.nn.functional as F
from torch import optim, Tensor
from torch import nn

import torchvision
import pytorch_lightning as pl

"""
Defines the VGG encoder with beta-TCVAE loss module. As the decoder for the
MNIST and dSprites data, an InfoGAN, and for the OCT data, a DCGAN architecture is
automatically selected. Also the VGG size depends on the data.
"""

class betaTCVAE_VGG(pl.LightningModule):
    def __init__(self,
                 latent_dim=10,
                 input_dim=784,
                 lr=0.001,
                 anneal_steps: int = 200,
                 alpha: float = 1.,
                 beta: float = 1.,
                 gamma: float = 1.,
                 dataset = "mnist",
                 c = 64
                 ):
        super(betaTCVAE_VGG, self).__init__()
        self.save_hyperparameters()
        self.c = c
        self.num_iter = 0
        self.dataset = dataset

        if dataset == "mnist":
            self.scale = 7
            self.trainset_size = 50000
        elif dataset=="dSprites":
            self.scale = 16
            self.trainset_size = 600000
        elif dataset == "OCT":
            self.scale = 50
            self.trainset_size = 85600

        # Encoder

        if dataset == "OCT":
            model = torchvision.models.vgg19_bn()
            model = list(model.features.children())[1:53]
        else:
            model = torchvision.models.vgg16_bn()
            model = list(model.features.children())[1:36]

        self.enc_conv1 = nn.Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        self.vgg = nn.Sequential(*model)
        self.enc_avgpool = nn.AdaptiveAvgPool2d(output_size=(1,1))

        self.enc_fc = nn.Linear(in_features=512, out_features=10*c)
        self.fc_mu = nn.Linear(in_features=10*c, out_features=latent_dim)
        self.fc_logvar = nn.Linear(in_features=10*c, out_features=latent_dim)

        # Decoder

        if dataset == "OCT":
            self.decoder = nn.Sequential(
                nn.ConvTranspose2d(in_channels=latent_dim, out_channels=self.scale * 8, kernel_size=12, stride=1, padding=0, bias=False),
                nn.BatchNorm2d(self.scale * 8),
                nn.ReLU(True),
                nn.ConvTranspose2d(in_channels=self.scale * 8, out_channels=self.scale * 4, kernel_size=12, stride=2, padding=1, bias=False),
                nn.BatchNorm2d(self.scale * 4),
                nn.ReLU(True),
                nn.ConvTranspose2d(in_channels=self.scale * 4, out_channels=self.scale * 2, kernel_size=14, stride=2, padding=1, bias=False),
                nn.BatchNorm2d(self.scale * 2),
                nn.ReLU(True),
                nn.ConvTranspose2d(in_channels=self.scale * 2, out_channels=self.scale, kernel_size=14, stride=2, padding=1, bias=False),
                nn.BatchNorm2d(self.scale),
                nn.ReLU(True),
                nn.ConvTranspose2d(in_channels=self.scale, out_channels=1, kernel_size=14, stride=2, padding=1, bias=False),
                nn.Sigmoid()
            )
        else:
            self.decoder = nn.Sequential(
                nn.BatchNorm1d(latent_dim),
                nn.Linear(in_features=latent_dim, out_features=c*2*self.scale*self.scale),
                nn.BatchNorm1d(c*2*self.scale*self.scale),
                nn.Unflatten(1, (self.c*2, self.scale, self.scale)),
                nn.ConvTranspose2d(in_channels=c*2, out_channels=c, kernel_size=4, stride=2, padding=1),
                nn.ReLU(), nn.BatchNorm2d(c),
                nn.ConvTranspose2d(in_channels=c, out_channels=1, kernel_size=4, stride=2, padding=1),
                nn.Sigmoid()
            )

    def encode(self, x):
        x = self.enc_conv1(x)
        x = self.vgg(x)
        x = self.enc_avgpool(x)

        try:
            x = torch.squeeze(x, dim=3)
            x = torch.squeeze(x, dim=2)
        except IndexError:
            pass

        x = F.relu(self.enc_fc(x))
        mu = self.fc_mu(x)
        log_var = self.fc_logvar(x)
        return mu, log_var

    def sampling(self, mu, log_var):
        std = torch.exp(log_var * 0.5)
        q = torch.distributions.Normal(mu, std)
        z = q.rsample()
        return z

    def decode(self, z):
        if self.dataset=="OCT":
            z = torch.unsqueeze(z,2)
            z = torch.unsqueeze(z,3)

        x = self.decoder(z)
        return x

    def forward(self, x):
        mu, log_var = self.encode(x)
        return mu

    def log_density_gaussian(self, x: Tensor, mu: Tensor, logvar: Tensor):
        norm = - 0.5 * (math.log(2 * math.pi) + logvar)
        log_density = norm - 0.5 * ((x - mu) ** 2 * torch.exp(-logvar))
        return log_density

    def loss(self, recons, x, mu, log_var, z):
        # Inspired by: https://github.com/YannDubs/disentangling-vae/blob/7b8285baa19d591cf34c652049884aca5d8acbca/disvae/models/losses.py#L316
        recons_loss = F.binary_cross_entropy(
            recons.view(-1, self.hparams.input_dim).clamp(0, 1),
            x.view(-1, self.hparams.input_dim),
            reduction='sum')

        log_q_zx = self.log_density_gaussian(z, mu, log_var).sum(dim=1)

        zeros = torch.zeros_like(z)
        log_p_z = self.log_density_gaussian(z, zeros, zeros).sum(dim=1)

        batch_size, latent_dim = z.shape
        mat_log_q_z = self.log_density_gaussian(z.view(batch_size, 1, latent_dim),
                                                mu.view(1, batch_size,
                                                        latent_dim),
                                                log_var.view(1, batch_size, latent_dim))

        # Estimate the three KL terms (log(q(z))) via importance sampling
        strat_weight = (self.trainset_size - batch_size + 1) / \
            (self.trainset_size * (batch_size - 1))

        importance_weights = torch.Tensor(batch_size, batch_size).fill_(
            1 / (batch_size - 1)).to(x.device)

        importance_weights.view(-1)[::batch_size] = 1 / self.trainset_size
        importance_weights.view(-1)[1::batch_size] = strat_weight
        importance_weights[batch_size - 2, 0] = strat_weight
        log_importance_weights = importance_weights.log()

        mat_log_q_z += log_importance_weights.view(batch_size, batch_size, 1)

        log_q_z = torch.logsumexp(mat_log_q_z.sum(2), dim=1, keepdim=False)
        log_prod_q_z = torch.logsumexp(
            mat_log_q_z, dim=1, keepdim=False).sum(1)

        # Three KL Term components
        mi_loss = (log_q_zx - log_q_z).mean()
        tc_loss = (log_q_z - log_prod_q_z).mean()
        kld_loss = (log_prod_q_z - log_p_z).mean()

        if self.training:
            self.num_iter += 1
            anneal_rate = min(0 + 1 * self.num_iter /
                              self.hparams.anneal_steps, 1)
        else:
            anneal_rate = 1

        loss = recons_loss/batch_size + \
            self.hparams.alpha * mi_loss + \
            self.hparams.beta * tc_loss + \
            self.hparams.gamma * anneal_rate * kld_loss

        return loss

    def training_step(self, batch, batch_idx):
        x, _ = batch
        mu, log_var = self.encode(x)
        z = self.sampling(mu, log_var)

        recons = self.decode(z)

        vae_loss = self.loss(recons, x, mu, log_var, z)

        self.log('loss', vae_loss, on_epoch=False, prog_bar=True, on_step=True,
                 sync_dist=True if torch.cuda.device_count() > 1 else False)

        return vae_loss

    def validation_step(self, batch, batch_idx):
        x, _ = batch
        mu, log_var = self.encode(x)
        z = self.sampling(mu, log_var)

        recons = self.decode(z)

        vae_loss = self.loss(recons, x, mu, log_var, z)

        self.log('val_loss', vae_loss, on_epoch=True, prog_bar=True,
                 sync_dist=True if torch.cuda.device_count() > 1 else False)

        return vae_loss

    def configure_optimizers(self):
        return torch.optim.Adam(self.parameters(), lr=self.hparams.lr)

    def get_progress_bar_dict(self):
        tqdm_dict = super().get_progress_bar_dict()
        if 'v_num' in tqdm_dict:
            del tqdm_dict['v_num']
        return tqdm_dict


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import sys
import time
import random
import threading
import logging

from six.moves import xrange

import numpy as np
import tensorflow as tf

flags = tf.app.flags

flags.DEFINE_string("save_path", None, "Directory to write the model and training sammaries.")
flags.DEFINE_string("train_data", None, "Training text file.")
flags.DEFINE_integer("embedding_size", 100, "The embedding dimension size.")
flags.DEFINE_integer("samples_to_train", 1, "Number of samples to train(*Million).")
flags.DEFINE_float("learning_rate", 0.025, "Initial learning rate.")
flags.DEFINE_integer("num_neg_samples", 5, "Negative samples per training example.")
flags.DEFINE_integer("batch_size", 1, "Number of training examples processed per step.")
flags.DEFINE_integer("num_threads", 4, "Number of threads training step.")
flags.DEFINE_integer("min_count", 5, "The min_count of edges for it to be included")
flags.DEFINE_integer("order", 2, "Model type, preserve first-order or second-order proximity.")
FLAGS = flags.FLAGS

class Options(object):
    '''Options used by LINE model.'''

    def __init__(self):
        #Model options.

        #Embedding dimension.
        self.emb_dim = FLAGS.embedding_size

        #training text file.
        self.train_data = FLAGS.train_data

        #Number of Negative samples per example.
        self.num_samples = FLAGS.num_neg_samples

        #The initial learning rate.
        self.learning_rate = FLAGS.learning_rate

        #Number of samples to train.
        self.samples_to_train = FLAGS.samples_to_train * 1000000

        #Number of threads.
        self.num_threads = FLAGS.num_threads

        #Number of examples for one training step.
        self.batch_size = FLAGS.batch_size

        #The minium number of edges for it to be included.
        self.min_count = FLAGS.min_count

        #Where to write out embeddings.
        self.save_path = FLAGS.save_path

        #order, can be 1 or 2.
        self.order = FLAGS.order

class LINE(object):
    '''LINE model.'''

    def __init__(self, options, session):
        self._options = options
        self._session = session
        self._vertex2id = {}
        self._id2vertex = []
        self._vid2degree = []
        self._edge_source_id = []
        self._edge_target_id = []
        self._edge_weight = []
        self._alias = []
        self._prob = []
        self._edge_count = 0
        self._read_data(self._options.train_data)
        self.InitAliasTable()
        self.build_graph()

    def _read_data(self, filename):
        '''Read data from training file.'''
        for line in open(filename):
            chunkes = line.strip().split()
            assert len(chunkes) == 3
            [name_v1, name_v2, weight] = chunkes
            weight = float(weight)
            '''Add current vertex to dict if it is not included yet.'''
            if not self._vertex2id.has_key(name_v1):
                self._vertex2id[name_v1] = len(self._vertex2id)
                self._id2vertex.append(name_v2)
                self._vid2degree.append(0)

            if not self._vertex2id.has_key(name_v2):
                self._vertex2id[name_v2] = len(self._vertex2id)
                self._id2vertex.append(name_v2)
                self._vid2degree.append(0)

            vid = self._vertex2id[name_v1]
            self._vid2degree[vid] += weight
            self._edge_source_id.append(vid)

            vid = self._vertex2id[name_v2]
            self._vid2degree[vid] += weight
            self._edge_target_id.append(vid)

            self._edge_weight.append(weight)

        self._edge_num = len(self._edge_weight)
        self._options.vertex_size = len(self._id2vertex)
        logging.info("Edge number : %d" % (self._edge_num))
        logging.info("Vertex number : %d" % (self._options.vertex_size))

    def InitAliasTable(self):
        '''The alias sampling algo, which is used to sample an edge in O(1) time.'''
        norm_prob = []
        large_block = []
        small_block = []

        sum = 0.0

        for weight in self._edge_weight:
            sum += float(weight)

        for k in xrange(self._edge_num):
            norm_prob.append(self._edge_weight[k] * self._edge_num / sum)

        num_small_block = 0
        num_large_block = 0
        cur_small_block = 0
        cur_large_block = 0

        for k in xrange(self._edge_num - 1, -1, -1):
            if norm_prob[k] < 1:
                small_block.append(k)
            else:
                large_block.append(k)

        num_small_block = len(small_block)
        num_large_block = len(large_block)
        assert (num_small_block + num_large_block == self._edge_num)

        for i in xrange(self._edge_num):
            self._alias.append(0)
            self._prob.append(0.0)

        while True:
            if num_small_block ==0 or num_large_block == 0:
               break
            num_small_block -= 1
            num_large_block -= 1
            cur_small_block = small_block[num_small_block]
            cur_large_block = large_block[num_large_block]
            self._prob[cur_small_block] = norm_prob[cur_small_block]
            self._alias[cur_small_block] = cur_large_block
            norm_prob[cur_large_block] = norm_prob[cur_small_block] + norm_prob[cur_small_block] - 1.0
            if norm_prob[cur_large_block] < 1:
                small_block[num_small_block] = cur_large_block
                num_small_block += 1
            else:
                large_block[num_large_block] = cur_large_block
                num_large_block += 1
        while num_large_block > 0:
            num_large_block -= 1
            self._prob[large_block[num_large_block]] = 1
        while num_small_block > 0:
            num_small_block -= 1
            self._prob[small_block[num_small_block]] = 1
        logging.info("prob table length:%d" % (len(self._prob)))
        logging.info("alias table length:%d" % (len(self._alias)))

    def SampleAnEdge(self):
            '''sample an edge in O(1).'''
            opts = self._options
            self._edge_count += opts.batch_size
            inputs = np.ndarray(shape = (opts.batch_size), dtype = np.int32)
            labels = np.ndarray(shape = (opts.batch_size), dtype = np.int32)
            for i in range(opts.batch_size):
                r_value1 = random.random()
                r_value2 = random.random()
                k = int(self._edge_num * r_value1)
                k = k if r_value2 < self._prob[k] else self._alias[k]
                inputs[i] = self._edge_source_id[k]
                labels[i] = self._edge_target_id[k]
            return inputs, labels

    def forward(self, sources, targets):
        '''Build the graph for the forward pass.'''
        opts = self._options
        #embedding:[vertex_size,emb_dim]
        init_width = 0.5
        #emb_vertex, order=1
        emb_vertex = tf.Variable(tf.random_uniform([opts.vertex_size, opts.emb_dim], -init_width, init_width), name = 'emb_vertex')
        #emb_context, order=2
        emb_context = tf.Variable(tf.zeros([opts.vertex_size, opts.emb_dim], dtype = tf.float32), name = 'emb_context')
        self._emb_vertex = emb_vertex
        self._emb_context = emb_context
        self.global_step = tf.Variable(0, trainable=False, name='global_step',dtype=tf.int32)
        targets_matrix = tf.reshape(tf.cast(targets, dtype = tf.int64), [opts.batch_size, 1])
        #Negative sampling.
        sampled_ids,_,_ = (tf.nn.fixed_unigram_candidate_sampler(
            true_classes = targets_matrix,
            num_true = 1,
            num_sampled = opts.num_samples,
            unique = True,
            range_max=opts.vertex_size,
            distortion = 0.75,
            unigrams = self._vid2degree
            ))
        #embedding for sources
        example_emb = tf.nn.embedding_lookup(emb_vertex, sources)

        #embedding for targets
        if opts.order == 1:
            target_emb = tf.nn.embedding_lookup(emb_vertex, targets)
        elif opts.order == 2:
            target_emb = tf.nn.embedding_lookup(emb_context, targets)
        else:
            logging.error("unsupported order: %d" % (opts.order))
            sys.exit(1)

        #true logits
        true_logits  = tf.reduce_sum(tf.mul(example_emb, target_emb), 1)

        #embeddings for negative-sampled vertex
        if opts.order == 1:
            sampled_emb = tf.nn.embedding_lookup(emb_vertex, sampled_ids)
        else:
            sampled_emb = tf.nn.embedding_lookup(emb_context, sampled_ids)
        #sampled logits
        sampled_logits = tf.matmul(example_emb,
                                  sampled_emb,
                                  transpose_b = True)

        return true_logits, sampled_logits

    def nce_loss(self, true_logits, sampled_logits):
        '''build  the graph for the NCE loss.'''

        #cross-entropy(logits, labels)
        opts = self._options
        true_xent = tf.nn.sigmoid_cross_entropy_with_logits(
            true_logits, tf.ones_like(true_logits))
        sampled_xent = tf.nn.sigmoid_cross_entropy_with_logits(
            sampled_logits, tf.zeros_like(sampled_logits))

        nce_loss_tensor = (tf.reduce_sum(true_xent) +
                          tf.reduce_sum(sampled_xent)) / opts.batch_size
        return nce_loss_tensor

    def optimize(self, loss):
        '''build the graph to optimize the loss function.'''
        opts = self._options
        #update learning rate.
        #self._lr = tf.train.exponential_decay(opts.learning_rate, self.global_step, 10000, 0.96, staircase=True)
        self._lr = opts.learning_rate * (1.0 - tf.cast(self.global_step, tf.float32) / float(opts.samples_to_train))
        optimizer = tf.train.GradientDescentOptimizer(self._lr)
        train = optimizer.minimize(loss,
                                   global_step = self.global_step,
                                   gate_gradients = optimizer.GATE_NONE
                                  )
        self._train = train

    def build_graph(self):
        '''build the graph for the full model.'''
        opts = self._options
        sources = tf.placeholder(tf.int32, shape = [opts.batch_size])
        self._sources = sources
        targets = tf.placeholder(tf.int32, shape = [opts.batch_size])
        self._targets = targets
        true_logits, sampled_logits = self.forward(sources, targets)
        loss = self.nce_loss(true_logits, sampled_logits)
        self._loss = loss
        self.optimize(loss)

        #Initialize all variables.
        tf.initialize_all_variables().run()

        #create a saver.
        self.saver = tf.train.Saver([self._emb_vertex])

    def _train_thread_body(self):
        opts = self._options
        while True:
            _sources, _targets = self.SampleAnEdge()
            feed_dict = {self._sources: _sources, self._targets: _targets}
            self._session.run([self._train], feed_dict=feed_dict)
            if self._edge_count >= opts.samples_to_train:
                break

    def train(self):
        '''trian the model.'''
        opts = self._options
        workers = []
        for _ in xrange(opts.num_threads):
            t = threading.Thread(target=self._train_thread_body)
            t.start()
            workers.append(t)

        #print training info.
        loss_list = []
        last_count, last_time = self._edge_count, time.time()
        while True:
            time.sleep(0.5)
            _sources, _targets = self.SampleAnEdge()
            feed_dict = {self._sources: _sources, self._targets: _targets}
            (lr, loss, _) = self._session.run([self._lr, self._loss, self._train],feed_dict=feed_dict)
            now = time.time()
            rate = (self._edge_count - last_count) / (now - last_time)
            progress = 100 * (self._edge_count) / float(opts.samples_to_train)
            last_time = now
            last_count = self._edge_count
            loss_list.append(loss)
            average_loss = np.mean(np.array(loss_list))
            print ("Learning rate:%5.3f loss:%6.2f average loss: %f edges/sec:%8.0f progress:%f%%\r" % (
                lr, loss, average_loss, rate, progress
            ), end = "")
            sys.stdout.flush()
            if self._edge_count >= opts.samples_to_train:
                break
        print  ("")
        for t in workers:
            t.join()

def main(_):
    logging.basicConfig(level = logging.INFO)
    if not FLAGS.train_data:
        logging.error('no train file.')
        sys.exit(1)
    opts = Options()
    with tf.Graph().as_default(), tf.Session() as session:
        with tf.device("/cpu:0"):
            model = LINE(opts, session)
        model.train()
        model.saver.save(session,
                        os.path.join(opts.save_path,"emb.txt"),global_step=model.global_step)

if __name__ == '__main__':
    '''This is for test.'''
    tf.app.run()


from collections import defaultdict
from math import inf
from math import sqrt
import random
import csv

def point_avg(points):
    """
    Accepts a list of points, each with the same number of dimensions.
    (points can have more dimensions than 2)

    Returns a new point which is the center of all the points.
    """

    new_p = []

    p_len = len(points)
    d_len = len(points[0])

    for d in range(d_len):
        sum = 0
        for p in range(p_len):
            sum = sum + points[p][d]

        new_p.append((float(sum))/(float(p_len)))

    return new_p

def update_centers(data_set, assignments):
    """
    Accepts a dataset and a list of assignments; the indexes
    of both lists correspond to each other.
    Compute the center for each of the assigned groups.
    Return `k` centers in a list
    """

    new_set = defaultdict(list)
    center = []

    for (assignment,point)in zip(assignments,data_set):
        new_set[assignment].append(point)

    for i in new_set.keys():
        center.append(point_avg(new_set[i]))

    return center

def assign_points(data_points, centers):
    """
    """
    assignments = []
    for point in data_points:
        shortest = inf  # positive infinity
        shortest_index = 0
        for i in range(len(centers)):
            val = distance(point, centers[i])
            if val < shortest:
                shortest = val
                shortest_index = i
        assignments.append(shortest_index)
    return assignments

def distance(a, b):
    """
    Returns the Euclidean distance between a and b
    """
    dim = len(a)

    sum = 0

    for d in range(dim):
        elem = (a[d]-b[d])**2
        sum = sum + elem

    return sqrt(sum)

def generate_k(data_set, k):
    """
    Given `data_set`, which is an array of arrays,
    return a random set of k points from the data_set
    """
    if k<= 0 or k > len(data_set):
        raise ValueError("k is not valid")
    return random.sample(data_set,k)

def get_list_from_dataset_file(dataset_file):
    data = []

    with open(dataset_file) as f:
        datas = csv.reader(f)
        for l in datas:
            row = []
            for n in l:
                elem = int(n)
                row.append(elem)
            data.append(row)
    return data

def cost_function(clustering):
    c = 0

    for k in clustering.keys():
        lst = clustering[k]
        center_point = point_avg(lst)

        for p in lst:
            c = c + distance(center_point,p)

    return c

def k_means(dataset_file, k):
    dataset = get_list_from_dataset_file(dataset_file)
    k_points = generate_k(dataset, k)
    assignments = assign_points(dataset, k_points)
    old_assignments = None
    while assignments != old_assignments:
        new_centers = update_centers(dataset, assignments)
        old_assignments = assignments
        assignments = assign_points(dataset, new_centers)
    clustering = defaultdict(list)
    for assignment, point in zip(assignments, dataset):
        clustering[assignment].append(point)
    print("hi")
    return clustering


def hammingDistance(s1, s2):
    dist = 0
    for i in range(len(s1)):
        if s1[i] != s2[i]:
            dist += 1
    return dist

def approxPatternMatching(pattern, text, d):
    indices = []
    for i in range(len(text) - len(pattern)):
        currText = text[i: i + len(pattern)]
        if hammingDistance(currText, pattern) <= d:
            indices.append(str(i))
    return indices

if __name__ == '__main__':
    with open('rosalind_ba1h.txt', 'r+') as f:
        pattern = f.readline().rstrip()
        text = f.readline().rstrip()
        d = int(f.readline())

        indices = approxPatternMatching(pattern, text, d)

    print(' '.join(indices))


# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------
from traffic import Traffic, TrafficMultiClass, GTSDBMultiClass

"""Factory method for easily getting imdbs by name."""

__sets = {}

# Set up traffic
# path to devkit example '/home/szy/INRIA'
traffic_devkit_path = "/mnt/nvme/traffic-rcnn/"
traffic_multi_class_devkit_path = "/mnt/nvme/traffic-multiclass/"
traffic_dual_devkit_path = "/mnt/nvme/traffic-dual-purpose/"
gtsrb_devkit_path = "/mnt/nvme/gtsrb-rcnn/"
gtsdb_devkit_path = "/mnt/nvme/gtsdb-rcnn/"
gtsdb_multi_class_devkit_path = "/mnt/nvme/gtsdb-rcnn-multi/"

for split in ['train', 'test', 'test2']:
    name = '{}_{}'.format('traffic', split)
    __sets[name] = (
        lambda split=split: Traffic(split, traffic_devkit_path))

for split in ['train', 'test']:
    name = '{}_{}'.format('traffic_multi_class', split)
    __sets[name] = (
        lambda split=split: TrafficMultiClass(
            split, traffic_multi_class_devkit_path))

for split in ['train', 'test', 'test2']:
    name = '{}_{}'.format('traffic_dual', split)
    __sets[name] = (
        lambda split=split: Traffic(
            split, traffic_dual_devkit_path))

for split in ['train', 'test']:
    name = '{}_{}'.format('gtsrb', split)
    __sets[name] = (
        lambda split=split: Traffic(split, gtsrb_devkit_path))

for split in ['train', 'test', 'full']:
    name = '{}_{}'.format('gtsdb', split)
    __sets[name] = (
        lambda split=split: Traffic(split, gtsdb_devkit_path))

for split in ['train', 'test', 'full']:
    name = '{}_{}'.format('gtsdb_multi_class', split)
    __sets[name] = (
        lambda split=split: GTSDBMultiClass(
            split, gtsdb_multi_class_devkit_path))

def get_imdb(name):
    """Get an imdb (image database) by name."""
    if name not in __sets:
        raise KeyError('Unknown dataset: {}'.format(name))
    return __sets[name]()

def list_imdbs():
    """List all registered imdbs."""
    return __sets.keys()


from django.utils.deprecation import MiddlewareMixin
import re
from django.shortcuts import render,HttpResponse
from rbac import models

class Permisson(MiddlewareMixin):

    def process_request(self,request):

        current_path = request.path

        urls=['/','/login/','/reg/','/admin.*/',]
        for i in urls:
            i = '^' + i + '$'
            re_result=re.match(i,current_path)
            if re_result:
                return None

        permisson=request.session.get('permisson_dict')
        if permisson:
            for i in permisson.values():
                for j in i['url']:
                    url = '^' + j + '$'
                    re_result=re.match(url,current_path)

                    if re_result:
                        request.action = i['action']
                        return None
            else:
                return HttpResponse('没有访问权限！！')

        else:
            return HttpResponse('请登录！！')


from random import randint

errate = randint(1, 10)
versuche = 5

container = [1,2,3,4,5,6,7,8,9,10]

for i in range(versuche):
	rate = input("Geben Sie eine Zahl zwischen 1 und 10 ein: ")
	print(rate)
	while int(rate) not in container:
		rate = input("Ihr Input war nicht zwischen 1 und 10. Geben Sie eine Zahl zwischen 1 und 10 ein: ")
		print(rate)

	if rate == str(errate):
		print("Super! Sie haben die Zahl erraten. ")
		break

	if i == 4:
		print("Die gesuchte Zahl wäre gewesen: " + str(errate))
	else:
		continue


# 自定义异常处理
from rest_framework.views import exception_handler
from rest_framework.views import Response
from rest_framework import status

# 将仅针对由引发的异常生成的响应调用异常处理程序。它不会用于视图直接返回的任何响应
def custom_exception_handler(exc, context):
    response = exception_handler(exc, context)

    if response is None:
        return Response({
            'message': '服务器错误'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)

    else:
        # 这个循环是取第一个错误的提示用于渲染
        for index, value in enumerate(response.data):
            if index == 0:
                key = value
                value = response.data[key]

                if isinstance(value, str):
                    message = value
                else:
                    message = key + value[0]
        # print('123 = %s - %s - %s' % (context['view'], context['request'].method, exc))
        return Response({
            'message': message
        }, status=response.status_code, exception=True)

    return response


from __future__ import annotations

import random
from fractions import Fraction
from typing import Any, Callable, Union

import aiger_discrete
import attr
from aiger_discrete import FiniteFunc
from aiger_discrete.discrete import project, TIMED_NAME
from pyrsistent import pmap
from pyrsistent.typing import PMap

Probability = Union[float, Fraction]
Distribution = Callable[[Any], Union[float, Fraction]]

def rejection_sample(name: str, func: FiniteFunc, dist: Distribution) -> Any:
    size = func.imap[name].size
    encoding = func.input_encodings.get(name, aiger_discrete.Encoding())
    while True:
        val = encoding.decode(random.getrandbits(size))
        prob = dist(val)

        if prob == 1:
            return val
        elif prob == 0:
            continue
        elif random.random() <= dist(val):
            return val

def to_finite_func(circ) -> FiniteFunc:
    if isinstance(circ, FiniteFunc):
        return circ
    return aiger_discrete.from_aigbv(circ.aigbv)

@attr.s(frozen=True, auto_attribs=True)
class PCirc:
    """Wrapper around AIG representing a function with some random inputs."""
    circ: FiniteFunc = attr.ib(converter=to_finite_func)
    dist_map: PMap[str, Probability] = attr.ib(converter=pmap, default=pmap())

    def __attrs_post_init__(self):
        """Make sure unneeded distributions are forgotten."""
        dist_map = project(self.dist_map, self.circ.inputs)
        object.__setattr__(self, "dist_map", dist_map)

    @property
    def inputs(self): return self.circ.inputs - set(self.dist_map.keys())

    @property
    def outputs(self): return self.circ.outputs

    @property
    def latches(self): return self.circ.latches

    @property
    def latch2init(self): return self.circ.latch2init

    @property
    def aig(self): return self.circ.aig

    @property
    def aigbv(self): return self.circ.aigbv

    def assume(self, aigbv_like) -> PCirc:
        """Return Probabilistic Circuit with new assumption over the inputs."""
        return attr.evolve(self, circ=self.circ.assume(aigbv_like))

    def __rshift__(self, other) -> PCirc:
        circ = self.circ >> canon(other).circ
        return PCirc(circ, other.dist_map + self.dist_map)

    def __lshift__(self, other) -> PCirc:
        return canon(other) >> self

    def __or__(self, other) -> PCirc:
        if set(self.dist_map.keys()) & set(self.dist_map.keys()):
            raise ValueError("Circuits have conflicting dist_maps.")
        circ = self.circ | canon(other).circ
        return PCirc(circ, self.dist_map + other.dist_map)

    def __call__(self, inputs, latches=None, max_tries=1_000):
        inputs = dict(inputs)
        for count in range(max_tries + 1):
            inputs.update({
                k: rejection_sample(k, self.circ, dist)
                for k, dist in self.dist_map.items()
            })

            try:
                return self.circ(inputs=inputs, latches=latches)
            except ValueError:  # Invalid input selected.
                # TODO: build BDD to uniformly sample.
                if count <= max_tries:
                    continue
                raise RuntimeError("Rejection Sampling failed!")

    def __getitem__(self, others) -> PCirc:
        circ = self.circ[others]
        kind, relabels = others

        kwargs = {}
        if kind == 'i':
            evolver = self.dist_map.evolver()
            for old, new in relabels.items():
                if old not in self.dist_map:
                    continue
                evolver[new] = self.dist_map[old]
                del evolver[old]
            kwargs['dist_map'] = evolver.persistent()

        return attr.evolve(self, circ=circ, **kwargs)

    def loopback(self, *wirings) -> PCirc:
        inputs = self.inputs
        assert all(w['input'] in inputs for w in wirings)
        circ = self.circ.loopback(*wirings)
        return attr.evolve(self, circ=circ)

    def unroll(self,
               horizon, *,
               init=True,
               omit_latches=True,
               only_last_outputs=False) -> PCirc:
        circ = self.circ.unroll(
            horizon=horizon,
            init=init,
            omit_latches=omit_latches,
            only_last_outputs=only_last_outputs,
        )
        dist_map = {}
        for timed_name in circ.inputs:
            # Should always match because of unrolling.
            name = TIMED_NAME.match(timed_name).groups()[0]
            if name not in self.dist_map:
                continue
            dist_map[timed_name] = self.dist_map[name]

        return attr.evolve(self, circ=circ, dist_map=dist_map)

    simulator = aiger_discrete.FiniteFunc.simulator
    simulate = aiger_discrete.FiniteFunc.simulate

    def use_faircoins(self) -> PCirc:
        # TODO: return PCirc where
        # 1. every random variable's encoding is i.d.
        # 2. every random distribution is over fair coins.
        pass

    def with_distmap(self, dist_map) -> PCirc:
        """Update the distributions over the inputs."""
        return attr.evolve(self, dist_map=self.dist_map + pmap(dist_map))

def canon(circ) -> PCirc:
    if isinstance(circ, PCirc):
        return circ
    return PCirc(circ)  # Assume aigbv like.

__all__ = ['PCirc']


import Orange
import numpy as np

#TEST DATA TO NUMPY
tab = Orange.data.Table("Test_Data_With_Domain_Data.tab")
U, _, _ = tab.to_numpy()

np.save("TestWithoutZipData", U)

#TRAIN DATA TO NUMPY
tab = Orange.data.Table("Train_Data_With_Domain_Data.tab")
U, _, _ = tab.to_numpy()

np.save("TrainWithoutZipData", U)

Clustering and atribute chosing/numpyData/final_Clusters/Final Prediction Test Set/Preparing Train and Test data/DataToNumpy.py


#calss header
class _PETITION():
	def __init__(self,):
		self.name = "PETITION"
		self.definitions = [u'a document signed by a large number of people demanding or asking for some action from the government or another authority: ', u'a formal letter to a law court asking for a particular legal action: ']

		self.parents = []
		self.childen = []
		self.properties = []
		self.jsondata = {}

		self.specie = 'nouns'

	def run(self, obj1 = [], obj2 = []):
		return self.jsondata


"""Tests for cement.ext.ext_argparse."""

import sys
import re
from argparse import ArgumentError
from cement.ext.ext_argparse import ArgparseArgumentHandler
from cement.ext.ext_argparse import ArgparseController, expose
from cement.ext.ext_argparse import _clean_label, _clean_func
from cement.utils import test
from cement.utils.misc import rando
from cement.core.exc import InterfaceError, FrameworkError

APP = rando()[:12]

if (sys.version_info[0] > 3 and sys.version_info[1] >= 4):
    ARGPARSE_SUPPORTS_DEFAULTS = True
else:
    ARGPARSE_SUPPORTS_DEFAULTS = False

class Base(ArgparseController):

    class Meta:
        label = 'base'
        arguments = [
            (['--foo'], dict(dest='foo')),
        ]

    @expose(hide=True, help="this help doesn't get seen")
    def default(self):
        return "Inside Base.default"

    @expose()
    def cmd1(self):
        return "Inside Base.cmd1"

    @expose()
    def command_with_dashes(self):
        return "Inside Base.command_with_dashes"

class Second(ArgparseController):

    class Meta:
        label = 'second'
        stacked_on = 'base'
        stacked_type = 'embedded'
        arguments = [
            (['--foo2'], dict(dest='foo2')),
        ]

    @expose(
        arguments=[
            (['--cmd2-foo'],
             dict(help='cmd2 sub-command only options', dest='cmd2_foo')),
        ]
    )
    def cmd2(self):
        if self.app.pargs.cmd2_foo:
            return "Inside Second.cmd2 : Foo > %s" % self.app.pargs.cmd2_foo
        else:
            return "Inside Second.cmd2"

class Third(ArgparseController):

    class Meta:
        label = 'third'
        stacked_on = 'base'
        stacked_type = 'nested'
        arguments = [
            (['--foo3'], dict(dest='foo3')),
        ]

    @expose(hide=True)
    def default(self):
        return "Inside Third.default"

    @expose()
    def cmd3(self):
        return "Inside Third.cmd3"

class Fourth(ArgparseController):

    class Meta:
        label = 'fourth'
        stacked_on = 'third'
        stacked_type = 'embedded'
        hide = True
        help = "this help doesn't get seen cause we're hiding"
        arguments = [
            (['--foo4'], dict(dest='foo4')),
        ]

    @expose()
    def cmd4(self):
        return "Inside Fourth.cmd4"

class Fifth(ArgparseController):

    class Meta:
        label = 'fifth'
        stacked_on = 'third'
        stacked_type = 'nested'
        hide = True
        help = "this help isn't seen... i'm hiding"
        arguments = [
            (['--foo5'], dict(dest='foo5')),
        ]

    @expose(hide=True)
    def default(self):
        return "Inside Fifth.default"

    @expose()
    def cmd5(self):
        return "Inside Fifth.cmd5"

class Sixth(ArgparseController):

    class Meta:
        label = 'sixth'
        stacked_on = 'fifth'
        stacked_type = 'nested'
        arguments = [
            (['--foo6'], dict(dest='foo6')),
        ]

    @expose(hide=True)
    def default(self):
        return "Inside Sixth.default"

    @expose()
    def cmd6(self):
        return "Inside Sixth.cmd6"

class Seventh(ArgparseController):

    class Meta:
        label = 'seventh'
        stacked_on = 'fourth'
        stacked_type = 'embedded'
        arguments = [
            (['--foo7'], dict(dest='foo7')),
        ]

    @expose()
    def cmd7(self):
        return "Inside Seventh.cmd7"

class Unstacked(ArgparseController):

    class Meta:
        label = 'unstacked'
        stacked_on = None
        arguments = [
            (['--foo6'], dict(dest='foo6')),
        ]

class BadStackType(ArgparseController):

    class Meta:
        label = 'bad_stack_type'
        stacked_on = 'base'
        stacked_type = 'bogus_stacked_type'
        arguments = [
            (['--foo6'], dict(dest='foo6')),
        ]

class DuplicateArguments(ArgparseController):

    class Meta:
        label = 'duplicate_arguments'
        arguments = [
            (['--foo'], dict(dest='foo')),
        ]

class ControllerCommandDuplicateArguments(ArgparseController):

    class Meta:
        label = 'controller_command_duplicate_arguments'

    @expose(
        arguments=[
            (['--foo'], dict(dest='foo')),
            (['--foo'], dict(dest='foo')),
        ]
    )
    def sub_command(self):
        pass

class AlternativeDefault(ArgparseController):

    class Meta:
        label = 'alternative_default'
        default_func = 'alternative_default'
        stacked_on = 'base'
        stacked_type = 'nested'

    @expose(hide=True)
    def alternative_default(self):
        return "Inside AlternativeDefault.alternative_default"

class BadAlternativeDefault(ArgparseController):

    class Meta:
        label = 'bad_alternative_default'
        default_func = 'bogus_default'
        stacked_on = 'base'
        stacked_type = 'nested'

class Aliases(ArgparseController):

    class Meta:
        label = 'aliases'
        aliases = ['aliases-controller', 'ac']
        stacked_on = 'base'
        stacked_type = 'nested'

    @expose(aliases=['aliases-cmd-1', 'ac1'])
    def aliases_cmd1(self):
        return "Inside Aliases.aliases_cmd1"

class ArgparseExtTestCase(test.CementExtTestCase):

    def setUp(self):
        super(ArgparseExtTestCase, self).setUp()
        self.app = self.make_app(APP,
                                 argument_handler=ArgparseArgumentHandler,
                                 handlers=[
                                     Sixth,
                                     Base,
                                     Second,
                                     Third,
                                     Fourth,
                                     Fifth,
                                     Seventh,
                                 ],
                                 )

    def test_clean_label(self):
        self.eq(_clean_label('some_cmd_name'), 'some-cmd-name')

    def test_clean_func(self):
        self.eq(_clean_func('some-cmd-name'), 'some_cmd_name')

    def test_base_default(self):
        if not ARGPARSE_SUPPORTS_DEFAULTS:
            raise test.SkipTest(
                'Argparse does not support default commands in Python < 3.4'
            )

        with self.app as app:
            res = app.run()
            self.eq(res, "Inside Base.default")

    def test_base_cmd1(self):
        with self.app as app:
            app._meta.argv = ['cmd1']
            res = app.run()
            self.eq(res, "Inside Base.cmd1")

    def test_base_command_with_dashes(self):
        with self.app as app:
            app._meta.argv = ['command-with-dashes']
            res = app.run()
            self.eq(res, "Inside Base.command_with_dashes")

    def test_controller_commands(self):
        with self.app as app:
            app._meta.argv = ['cmd2']
            res = app.run()
            self.eq(res, "Inside Second.cmd2")
        self.tearDown()

        self.setUp()
        with self.app as app:
            app._meta.argv = ['third', 'cmd3']
            res = app.run()
            self.eq(res, "Inside Third.cmd3")
        self.tearDown()

        self.setUp()
        with self.app as app:
            app._meta.argv = ['third', 'cmd4']
            res = app.run()
            self.eq(res, "Inside Fourth.cmd4")
        self.tearDown()

        self.setUp()
        with self.app as app:
            app._meta.argv = ['third', 'fifth', 'cmd5']
            res = app.run()
            self.eq(res, "Inside Fifth.cmd5")
        self.tearDown()

        self.setUp()
        with self.app as app:
            app._meta.argv = ['third', 'fifth', 'sixth', 'cmd6']
            res = app.run()
            self.eq(res, "Inside Sixth.cmd6")
        self.tearDown()

        self.setUp()
        with self.app as app:
            app._meta.argv = ['third', 'cmd7']
            res = app.run()
            self.eq(res, "Inside Seventh.cmd7")
        self.tearDown()

    def test_base_cmd1_parsing(self):
        with self.app as app:
            app._meta.argv = ['--foo=bar', 'cmd1']
            res = app.run()
            self.eq(res, "Inside Base.cmd1")
            self.eq(app.pargs.foo, 'bar')

    def test_second_cmd2(self):
        with self.app as app:
            app._meta.argv = ['--foo=bar', '--foo2=bar2', 'cmd2']
            res = app.run()
            self.eq(res, "Inside Second.cmd2")
            self.eq(app.pargs.foo, 'bar')
            self.eq(app.pargs.foo2, 'bar2')

    def test_third_cmd3(self):
        with self.app as app:
            app._meta.argv = [
                '--foo=bar', '--foo2=bar2',
                'third', '--foo3=bar3', '--foo4=bar4', '--foo7=bar7', 'cmd3',
            ]
            res = app.run()
            self.eq(res, "Inside Third.cmd3")
            self.eq(app.pargs.foo, 'bar')
            self.eq(app.pargs.foo2, 'bar2')
            self.eq(app.pargs.foo3, 'bar3')
            self.eq(app.pargs.foo4, 'bar4')
            self.eq(app.pargs.foo7, 'bar7')

    def test_fifth_cmd5(self):
        with self.app as app:
            app._meta.argv = [
                '--foo=bar', '--foo2=bar2',
                'third', '--foo3=bar3', '--foo4=bar4',
                'fifth', '--foo5=bar5', 'cmd5'
            ]
            res = app.run()
            self.eq(res, "Inside Fifth.cmd5")
            self.eq(app.pargs.foo, 'bar')
            self.eq(app.pargs.foo2, 'bar2')
            self.eq(app.pargs.foo3, 'bar3')
            self.eq(app.pargs.foo4, 'bar4')
            self.eq(app.pargs.foo5, 'bar5')

    def test_sixth_cmd6(self):
        with self.app as app:
            app._meta.argv = [
                '--foo=bar', '--foo2=bar2',
                'third', '--foo3=bar3', '--foo4=bar4',
                'fifth', '--foo5=bar5', 'sixth', '--foo6=bar6', 'cmd6',
            ]
            res = app.run()
            self.eq(res, "Inside Sixth.cmd6")
            self.eq(app.pargs.foo, 'bar')
            self.eq(app.pargs.foo2, 'bar2')
            self.eq(app.pargs.foo3, 'bar3')
            self.eq(app.pargs.foo4, 'bar4')
            self.eq(app.pargs.foo5, 'bar5')
            self.eq(app.pargs.foo6, 'bar6')

    def test_seventh_cmd7(self):
        with self.app as app:
            app._meta.argv = [
                '--foo=bar', '--foo2=bar2',
                'third', '--foo3=bar3', '--foo4=bar4', '--foo7=bar7', 'cmd7',
            ]
            res = app.run()
            self.eq(res, "Inside Seventh.cmd7")
            self.eq(app.pargs.foo, 'bar')
            self.eq(app.pargs.foo2, 'bar2')
            self.eq(app.pargs.foo3, 'bar3')
            self.eq(app.pargs.foo4, 'bar4')
            self.eq(app.pargs.foo7, 'bar7')

    def test_collect(self):
        with self.app as app:
            args = app.controller._collect_arguments()
            cmds = app.controller._collect_commands()
            args2, cmds2 = app.controller._collect()
            self.eq((args, cmds), (args2, cmds2))

    def test_controller_embedded_on_base(self):
        self.app._meta.argv = ['cmd2']
        with self.app as app:
            res = app.run()
            self.eq(res, "Inside Second.cmd2")

    def test_controller_command_arguments(self):
        self.app._meta.argv = ['cmd2', '--cmd2-foo=bar2']
        with self.app as app:
            res = app.run()
            self.eq(res, "Inside Second.cmd2 : Foo > bar2")

    def test_controller_default_nested_on_base(self):
        if not ARGPARSE_SUPPORTS_DEFAULTS:
            raise test.SkipTest(
                'Argparse does not support default commands in Python < 3.4'
            )

        self.app._meta.argv = ['third']
        with self.app as app:
            res = app.run()
            self.eq(res, "Inside Third.default")

    def test_controller_command_nested_on_base(self):
        self.app._meta.argv = ['third', 'cmd3']
        with self.app as app:
            res = app.run()
            self.eq(res, "Inside Third.cmd3")

    def test_controller_doubled_embedded(self):
        self.app._meta.argv = ['third', 'cmd4']
        with self.app as app:
            res = app.run()
            self.eq(res, "Inside Fourth.cmd4")

    def test_controller_default_double_nested(self):
        if not ARGPARSE_SUPPORTS_DEFAULTS:
            raise test.SkipTest(
                'Argparse does not support default commands in Python < 3.4'
            )
        self.app._meta.argv = ['third', 'fifth']
        with self.app as app:
            res = app.run()
            self.eq(res, "Inside Fifth.default")

    def test_controller_command_double_nested(self):
        self.app._meta.argv = ['third', 'fifth', 'cmd5']
        with self.app as app:
            res = app.run()
            self.eq(res, "Inside Fifth.cmd5")

    def test_alternative_default(self):
        if not ARGPARSE_SUPPORTS_DEFAULTS:
            raise test.SkipTest(
                'Argparse does not support default commands in Python < 3.4'
            )

        self.reset_backend()
        self.app = self.make_app(APP,
                                 argv=['alternative_default'],
                                 argument_handler=ArgparseArgumentHandler,
                                 handlers=[
                                     Base,
                                     AlternativeDefault,
                                 ],
                                 )
        with self.app as app:
            res = app.run()
            self.eq(res,
                    "Inside AlternativeDefault.alternative_default")

    @test.raises(FrameworkError)
    def test_bad_alternative_default_command(self):
        if not ARGPARSE_SUPPORTS_DEFAULTS:
            raise test.SkipTest(
                'Argparse does not support default commands in Python < 3.4'
            )

        self.reset_backend()
        self.app = self.make_app(APP,
                                 argv=['bad_alternative_default'],
                                 argument_handler=ArgparseArgumentHandler,
                                 handlers=[
                                     Base,
                                     BadAlternativeDefault,
                                 ],
                                 )
        try:
            with self.app as app:
                res = app.run()

        except FrameworkError as e:
            res = re.match("(.*)does not exist(.*)bogus_default(.*)",
                           e.__str__())
            self.ok(res)
            raise

    @test.raises(InterfaceError)
    def test_invalid_stacked_on(self):
        self.reset_backend()
        try:
            self.app = self.make_app(APP,
                                     argument_handler=ArgparseArgumentHandler,
                                     handlers=[
                                         Base,
                                         Unstacked,
                                     ],
                                     )
            with self.app as app:
                app.run()
        except InterfaceError as e:
            self.ok(re.match("(.*)is not stacked anywhere!(.*)", e.msg))
            raise

    @test.raises(InterfaceError)
    def test_invalid_stacked_type(self):
        self.reset_backend()
        try:
            self.app = self.make_app(APP,
                                     argument_handler=ArgparseArgumentHandler,
                                     handlers=[
                                         Base,
                                         BadStackType,
                                     ],
                                     )
            with self.app as app:
                app.run()
        except InterfaceError as e:
            self.ok(re.match("(.*)has an unknown stacked type(.*)", e.msg))
            raise

    @test.raises(ArgumentError)
    def test_duplicate_arguments(self):
        self.reset_backend()
        try:
            self.app = self.make_app(APP,
                                     argument_handler=ArgparseArgumentHandler,
                                     handlers=[
                                         Base,
                                         DuplicateArguments,
                                     ],
                                     )
            with self.app as app:
                app.run()
        except ArgumentError as e:
            self.ok(re.match("(.*)conflicting option string(.*)",
                             e.__str__()))
            raise

    @test.raises(ArgumentError)
    def test_controller_command_duplicate_arguments(self):
        self.reset_backend()
        try:
            self.app = self.make_app(APP,
                                     argument_handler=ArgparseArgumentHandler,
                                     handlers=[
                                         Base,
                                         ControllerCommandDuplicateArguments,
                                     ],
                                     )
            with self.app as app:
                app.run()
        except ArgumentError as e:
            self.ok(re.match("(.*)conflicting option string(.*)",
                             e.__str__()))
            raise

    def test_aliases(self):
        if sys.version_info[0] < 3:
            raise test.SkipTest(
                'Argparse does not support aliases in Python < 3'
            )
        self.reset_backend()

        self.app = self.make_app(APP,
                                 argument_handler=ArgparseArgumentHandler,
                                 handlers=[
                                     Base,
                                     Aliases,
                                 ],
                                 )
        with self.app as app:
            app._meta.argv = ['aliases', 'aliases-cmd1']
            res = app.run()
            self.eq(res, "Inside Aliases.aliases_cmd1")

            app._meta.argv = ['aliases', 'aliases-cmd-1']
            app._setup_arg_handler()
            res = app.run()
            self.eq(res, "Inside Aliases.aliases_cmd1")

            app._meta.argv = ['aliases-controller', 'aliases-cmd1']
            app._setup_arg_handler()
            res = app.run()
            self.eq(res, "Inside Aliases.aliases_cmd1")

            app._meta.argv = ['ac', 'ac1']
            app._setup_arg_handler()
            res = app.run()
            self.eq(res, "Inside Aliases.aliases_cmd1")

    def test_unknown_arguments(self):
        self.reset_backend()

        class MyArgumentHandler(ArgparseArgumentHandler):
            class Meta:
                label = 'my_argument_handler'
                ignore_unknown_arguments = True
        self.app = self.make_app(APP,
                                 argument_handler=MyArgumentHandler,
                                 )
        with self.app as app:
            app._meta.argv = ['-l', 'some-other-argument']
            app.run()
            res = '-l' in app.args.unknown_args
            self.ok(res)
            res = 'some-other-argument' in app.args.unknown_args
            self.ok(res)


# Create your views here.

from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.shortcuts import redirect, render_to_response, get_object_or_404
from django.template import RequestContext
from django.views.generic.list_detail import object_list

from models import Article, Edit
from forms import ArticleForm, EditForm

@login_required
def add_article(request):
    form = ArticleForm(request.POST or None)
    if form.is_valid():
        article = form.save(commit=False)
        article.author = request.user
        article.save()
        msg = "Article saved successfully"
        messages.success(request, msg, fail_silently=True)
        return redirect(article)
    return render_to_response('wiki/article_form.html',
                              { 'form': form },
                              context_instance=RequestContext(request))

@login_required
def edit_article(request, slug):
    article = get_object_or_404(Article, slug=slug)
    form = ArticleForm(request.POST or None, instance=article)
    edit_form = EditForm(request.POST or None)
    if form.is_valid():
        article = form.save()
        if edit_form.is_valid():
            edit = edit_form.save(commit=False)
            edit.article = article
            edit.editor = request.user
            edit.save()
            msg = "Article updated successfully"
            messages.success(request, msg, fail_silently=True)
            return redirect(article)
    return render_to_response('wiki/article_form.html',
                              {
                                  'form': form,
                                  'edit_form': edit_form,
                                  'article': article,
                              },
                              context_instance=RequestContext(request))

def article_history(request, slug):
    article = get_object_or_404(Article, slug=slug)
    return  object_list(request,
                        queryset=Edit.objects.filter(article__slug=slug),
                        extra_context={'article': article})


import subprocess
import json
from poodle import Object
from kalc.model.full import kinds_collection
from kalc.misc.kind_filter import FilterByLabelKey, FilterByName, KindPlaceholder
from kalc.model.kubernetes import KubernetesCluster
import kalc.policy
from kalc.model.search import KubernetesModel
from kalc.model.kinds.Deployment import YAMLable, Deployment
from pygments import highlight
from pygments.lexers.diff import DiffLexer
from pygments.formatters.terminal import TerminalFormatter
import random
import io
import kalc.misc.util
import pkg_resources
import yaml
import kalc.misc.support_check
from kalc.misc.metrics import Metric
from logzero import logger

__version__ = pkg_resources.get_distribution("kalc").version

ALL_RESOURCES = [ "all", "node", "pc", "limitranges", "resourcequotas", "poddisruptionbudgets", "hpa"]

cluster_md5_sh = 'kubectl get pods -o wide --all-namespaces -o=custom-columns=NAME:.metadata.name,NODE:.spec.nodeName --sort-by="{.metadata.name}" | md5sum'

kalc_state_objects = []
kind = KindPlaceholder
cluster = None

md5_cluster = ""

kalc.policy.policy_engine.register_state_objects(kalc_state_objects)

for k, v in kinds_collection.items():
    v.by_name = FilterByName(k, kalc_state_objects)
    v.by_label = FilterByLabelKey(k, kalc_state_objects)
    globals()[k] = v
    setattr(kind, k, v)

def update(data=None):
    "Fetch information from currently selected cluster"
    if isinstance(data, io.IOBase):
        data = data.read()
    k = KubernetesCluster()
    all_data = []
    all_support_checks = []
    if not data:
        global md5_cluster
        result = subprocess.Popen(cluster_md5_sh, shell=True, stdout=subprocess.PIPE, executable='/bin/bash')
        md5_cluster = result.stdout.read().decode('ascii').split()[0]
        assert len(md5_cluster) == 32, "md5_cluster sum wrong len({0}) not is 32".format(md5_cluster)

        for res in ALL_RESOURCES:
            result = subprocess.run(['kubectl', 'get', res, '--all-namespaces', '-o=json'], stdout=subprocess.PIPE)
            if len(result.stdout) < 100:
                print(result.stdout)
                raise SystemError("Error using kubectl. Make sure `kubectl get pods` is working.")
            data = json.loads(result.stdout.decode("utf-8"))
            y_data = yaml.dump(data, default_flow_style=False)
            sc = kalc.misc.support_check.YAMLStrSupportChecker(yaml_str=y_data)
            all_support_checks.extend(sc.check())
            all_data.append(data)

        for result in all_support_checks:
            if not result.isOK(): logger.warning("Unsupported feature: %s" % str(result))
            else: logger.debug(str(result))

        for d in all_data:
            for item in d["items"]:
                k.load_item(item)

    else:
        # TODO: make sure "data" is in YAML format
        sc = kalc.misc.support_check.YAMLStrSupportChecker(yaml_str=data)
        for result in sc.check():
            if not result.isOK(): logger.warning("Unsupported feature: %s" % str(result))
            else: logger.debug(str(result))

        for ys in kalc.misc.util.split_yamldumps(data):
            k.load(ys)

    k._build_state()
    global kalc_state_objects
    kalc_state_objects.clear()
    kalc_state_objects.extend(k.state_objects)
    global cluster
    cluster = next(filter(lambda x: isinstance(x, GlobalVar), k.state_objects)) # pylint: disable=undefined-variable

def run():
    # TODO HERE: copy state_objects!
    # as we will be running multiple times, we need to store original state
    # or we actually don't! we can continue computing on top of previous...?
    # for now it is ok..
    kube = KubernetesModel(kalc_state_objects)
    policy_added = False
    hypotheses = []
    for ob in kalc_state_objects:
        if isinstance(ob.policy, str): continue # STUB. find and fix
        hypotheses.append(ob.policy.apply(kube))
    # TODO HERE: generate different combinations of hypotheses
    kube.run(timeout=999000, sessionName="kalc")
    # TODO. STUB
    # TODO example hanlers and patches
    for obj in kalc_state_objects:
        if isinstance(obj, Deployment):
            if "redis-slave" in str(obj.metadata_name):
                obj.affinity_required_handler()
                # obj.scale_replicas_handler(random.randint(4,10))

    if policy_added: patch()
    for a in kube.plan:
        print(a)
        r = a()
        if isinstance(r, dict) and "kubectl" in r:
            print(">>", r["kubectl"])
    # print summary

def patch():
    for obj in kalc_state_objects:
        if isinstance(obj, Deployment):
            # print("patch for ", obj.metadata_name)
            print(highlight(obj.get_patch(), DiffLexer(), TerminalFormatter()))

def apply():
    pass

def print_objects(objectList):
    print("<==== Domain Object List =====>")

    pod_loaded_list = filter(lambda x: isinstance(x, Pod), objectList) # pylint: disable=undefined-variable
    print("----------Pods---------------")
    for poditem in pod_loaded_list:
        print("## Pod:"+ str(poditem.metadata_name._get_value()) + \
        ", Status: " + str(poditem.status._get_value()) + \
        ", Priority_class: " + str(poditem.priorityClass._property_value.metadata_name) + \
        ", CpuRequest: " + str(poditem.cpuRequest._get_value()) + \
        ", MemRequest: " + str(poditem.memRequest._get_value()) + \
        ", CpuLimit: " + str(poditem.cpuLimit._get_value()) + \
        ", MemLimit: " + str(poditem.memLimit._get_value()) + \
        ", ToNode: " + str(poditem.toNode._property_value) + \
        ", AtNode: " + str(poditem.atNode._property_value) + \
        ", Metadata_labels:" + str([str(x) for x in poditem.metadata_labels._property_value]) + \
        ", hasService: " + str(poditem.hasService._get_value()) + \
        ", hasDeployment: " + str(poditem.hasDeployment._get_value()) + \
        ", hasDaemonset: " + str(poditem.hasDaemonset._get_value()))

    node_loaded_list = filter(lambda x: isinstance(x, Node), objectList) # pylint: disable=undefined-variable
    print("----------Nodes---------------")
    for nodeitem in node_loaded_list:
        print("## Node:"+ str(nodeitem.metadata_name._get_value()) + \
        ", cpuCapacity: " + str(nodeitem.cpuCapacity._get_value()) + \
        ", memCapacity: " + str(nodeitem.memCapacity._get_value()) + \
        ", CurrentFormalCpuConsumption: "  + str(nodeitem.currentFormalCpuConsumption._get_value()) + \
        ", CurrentFormalMemConsumption: " + str(nodeitem.currentFormalMemConsumption._get_value()) + \
        ", AmountOfPodsOverwhelmingMemLimits: " + str(nodeitem.AmountOfPodsOverwhelmingMemLimits._get_value()) + \
        ", PodAmount: "  + str(nodeitem.podAmount._get_value()) + \
        ", IsNull:"  + str(nodeitem.isNull._get_value()) + \
        ", Status:"  + str(nodeitem.status._get_value()) +\
        ", AmountOfActivePods: " + str(nodeitem.amountOfActivePods._get_value()) +\
        ", Searchable: " + str(nodeitem.searchable._get_value())+\
        ", IsSearched: ", str(nodeitem.isSearched._get_value())+\
        ", different_than: ", str([str(x) for x in nodeitem.different_than._get_value()]))
    services = filter(lambda x: isinstance(x, Service), objectList) # pylint: disable=undefined-variable
    print("----------Services---------------")
    for service in services:
        print("## Service: "+str(service.metadata_name)+\
        ", AmountOfActivePods: "+str(service.amountOfActivePods._get_value())+\
        ", Status: " + str(service.status._get_value()) +
        ", Spec_selector: "+str([str(x) for x in service.spec_selector._property_value])+\
        ", Pod_List: "+str([str(x) for x in service.podList._get_value()])+\
        ", IsSearched: ", str(service.isSearched._get_value()))

    prios = filter(lambda x: isinstance(x, PriorityClass), objectList) # pylint: disable=undefined-variable
    print("----------PriorityClasses---------------")
    for prio in prios:
        print("## PriorityClass: "+str(prio.metadata_name) +" " + str(prio.priority._get_value()))

    scheduler = next(filter(lambda x: isinstance(x, Scheduler), objectList)) # pylint: disable=undefined-variable
    print("----------Shedulers---------------")
    print("## Sheduler: "+str(scheduler.status._get_value()) +\
        " PodList: "+str([str(x) for x in scheduler.podQueue._get_value()]) +\
        " QueueLength: "+str(scheduler.queueLength._get_value()))

    deployments_loaded_list = filter(lambda x: isinstance(x, Deployment), objectList)
    print("----------Deployments------------")
    for deployment in deployments_loaded_list:
        print("## Deployment: "+str(deployment.metadata_name._get_value()) +\
        " Spec_replicas: "+ str(deployment.spec_replicas._get_value()) +\
        " Namespace: " + str(deployment.metadata_namespace._get_value())+\
        " AmountOfActivePods: " + str(deployment.amountOfActivePods._get_value())+\
        " Status: " + str(deployment.status._get_value())+\
        " PodList: " + str([str(x) for x in deployment.podList._get_value()])+\
        " PriorityClassName: " + str(deployment.spec_template_spec_priorityClassName._property_value) + \
        " Searchable:" + str(deployment.searchable))
        # " Metadata_labels: " + str([str(x) for x in deployment.template_metadata_labels._property_value]))

    daemonsets_loaded_list = filter(lambda x: isinstance(x, DaemonSet), objectList) # pylint: disable=undefined-variable
    print("----------DaemonSets------------")
    for daemonset in daemonsets_loaded_list:
        print("## DaemonSet: "+str(daemonset.metadata_name._get_value()) +\
        " AmountOfActivePods: " + str(daemonset.amountOfActivePods._get_value())+\
        " Status: " + str(daemonset.status._get_value())+\
        " PodList: " + str([str(x) for x in daemonset.podList._get_value()])+\
        " PriorityClassName: " + str(daemonset.spec_template_spec_priorityClassName._property_value) + \
        " Searchable:" + str(daemonset.searchable))
        # " Metadata_labels: " + str([str(x) for x in deployment.template_metadata_labels._property_value]))

    replicasets_loaded_list = filter(lambda x: isinstance(x, ReplicaSet), objectList) # pylint: disable=undefined-variable
    print("----------ReplicaSets------------")
    for replicaset in replicasets_loaded_list:
        print("## Replicaset: "+str(replicaset.metadata_name._get_value()) +\
        " hash: " + str(replicaset.hash)+\
        " spec_replicas: " + str(replicaset.spec_replicas._get_value())+\
        " metadata_ownerReferences__kind: " + str(replicaset.metadata_ownerReferences__name._property_value)+\
        " metadata_ownerReferences__name: " + str(replicaset.metadata_ownerReferences__name._property_value))

    globalvar_loaded_list = filter(lambda x: isinstance(x, GlobalVar), objectList) # pylint: disable=undefined-variable
    print("----------GlobalVar------------")
    list_of_objects_output =['']
    for globalvar_item in globalvar_loaded_list:
        list_of_objects_output.extend(['is_service_disrupted',str(globalvar_item.is_service_disrupted._get_value())])
        list_of_objects_output.extend(['is_deployment_disrupted',str(globalvar_item.is_deployment_disrupted._get_value())])
        list_of_objects_output.extend(['is_daemonset_disrupted',str(globalvar_item.is_daemonset_disrupted._get_value())])
        list_of_objects_output.extend(['is_node_disrupted',str(globalvar_item.is_node_disrupted._get_value())])
    print(list_of_objects_output)


from flask_restful import Resource, reqparse, fields, marshal_with
from api.db import crawl_db, CrawlCollections

parser = reqparse.RequestParser()
parser.add_argument('type', type=str, required=True, location='args')
parser.add_argument('project_id', type=int, required=True, location='args')

class GithubStat(Resource):
    def get(self):
        args = parser.parse_args()
        stat_type = args['type']
        project_id = args['project_id']
        stat = crawl_db[CrawlCollections.GIT_STAT].find_one({'project_id': project_id, 'type': stat_type})
        if stat is not None:
            return stat['data']


"""
OpenVisus conversion module
"""
import os
import rasterio
import argparse
import subprocess
import pathlib
import shutil
from glob import glob
from PIL import Image,ImageOps

from OpenVisus import *
DbModule.attach()

import dask
import distributed
import pandas as pd
from crown_maps.verify import get_site, get_year
import numpy as np
from numba import njit, prange

from OpenVisus.__main__ import MidxToIdx

def match_name(x):
  x = os.path.basename(x)
  return x.replace("image.tif","image_rasterized.tif")

@njit(parallel=True)
def blend_rgb_ann(a, b):
  #a[b[b>0]] = [255,0,0]
  for i in prange(a[0].shape[0]):
    for j in prange(a[0].shape[1]):
      if(b[i][j] > 0):
        a[0][i][j]=255
        a[1][i][j]=0
        a[2][i][j]=0

def blend(rgb_path, annotation_dir, outdir):
  basename = os.path.basename(rgb_path)
  ann_path=annotation_dir+"/"+basename.replace("image.tif", "image_rasterized.tif")
  ageo = rasterio.open(rgb_path)
  a = ageo.read()
  bgeo = rasterio.open(ann_path)
  b = bgeo.read()
  print("Blending ", rgb_path, "and", ann_path, "...")
  blend_rgb_ann(a, b[0])
  out_name = outdir+"/"+basename
  with rasterio.open(
        out_name,
        'w',
        driver='GTiff',
        height=ageo.height,
        width=ageo.width,
        count=3,
        dtype=a.dtype,
        crs='+proj=latlong',
        transform=ageo.transform,
    ) as dst:
        dst.write(a)

  return out_name

def run(rgb_images, dst_directory, annotation_dir):

  #Construct outdir variable from top level savedir and site
  site = get_site(rgb_images[0])
  outdir = os.path.join(dst_directory,site)
  pathlib.Path(outdir+"/temp").mkdir(parents=True, exist_ok=True)

  outname = outdir.split("/")[-1]
  if(outname==""):
    outname = outdir.split("/")[-2]

  # Blend rgb and annotations
  images = []
  for rgb_path in rgb_images:
    images.append(blend(rgb_path, annotation_dir, outdir))

  # find images
  # convert to idx
  sx,sy=1.0, 1.0
  tiles=[]
  for I,filename in enumerate(images):
    metadata =rasterio.open(filename)
    name=os.path.splitext(os.path.basename(filename))[0]
    width,height=metadata.width,metadata.height
    x1,y1,x2,y2=metadata.bounds.left,metadata.bounds.bottom, metadata.bounds.right, metadata.bounds.top

    # compute scaling to keep all pixels
    if I==0:
      sx=width /(x2-x1)
      sy=height/(y2-y1)

    x1,y1,x2,y2=sx*x1,sy*y1,sx*x2,sy*y2
    tile={"name": name, "size" : (width,height), "bounds" : (x1,y1,x2,y2)}
    print("Converting tile...",tile,I,"/",len(images))
    tiles.append(tile)

    # avoid creation multiple times
    if not os.path.isfile(os.path.join(dst_directory,name,"visus.idx")):
      data=Image.open(filename)
      data=ImageOps.flip(data)
      CreateIdx(url=os.path.join(dst_directory,name,"visus.idx"), rmtree=True, dim=2,data=numpy.asarray(data))

  # create midx
  X1=min([tile["bounds"][0] for tile in tiles])
  Y1=min([tile["bounds"][1] for tile in tiles])
  midx_filename=os.path.join(dst_directory,"visus.midx")
  with open(midx_filename,"wt") as file:
    file.writelines([
            "<dataset typename='IdxMultipleDataset'>\n",
                  "\t<field name='voronoi'>output=voronoi()</field>\n",
                  *["\t<dataset url='./{}/visus.idx' name='{}' offset='{} {}'/>\n".format(tile["name"],tile["name"],tile["bounds"][0]-X1,tile["bounds"][1]-Y1) for tile in tiles],
                  "</dataset>\n"
          ])

  # to see automatically computed idx file
  db=LoadDataset(midx_filename)
  print(db.getDatasetBody().toString())
  idx_filename=os.path.join(dst_directory,"visus.idx")
  MidxToIdx(["--midx", midx_filename, "--field","output=voronoi()", "--tile-size","4*1024", "--idx", idx_filename])

if __name__=="__main__":
  #Create dask cluster
  from crown_maps import start_cluster
  client = start_cluster.start(cpus=20,mem_size="40GB")
  client.wait_for_workers(1)

  #Pool of rasterized predictions
  rgb_list = glob.glob("/orange/ewhite/NeonData/**/Mosaic/*image.tif",recursive=True)
  annotation_dir = "/orange/idtrees-collab/rasterized/"
  outdir = "/orange/idtrees-collab/OpenVisus/"
  annotation_list = glob.glob(annotation_dir + "*.tif")

  annotation_names = [os.path.basename(x) for x in annotation_list]
  rgb_list = [x for x in rgb_list if match_name(x) in annotation_names]

  df = pd.DataFrame({"path":rgb_list})
  df["site"] = df.path.apply(lambda x: get_site(x))
  df["year"] = df.path.apply(lambda x: get_year(x))

  #just run
  #df = df[df.site.isin(["ABBY"])]

  #order by site  using only the most recent year
  site_lists = df.groupby('site').apply(lambda x: x[x.year==x.year.max()]).reset_index(drop=True).groupby('site').path.apply(list).values

  ####Scatter and run in parallel
  futures = []
  for site in site_lists:
    site = np.sort(site)
    siteID = get_site(site[0])
    site_dir = "{}/{}".format(outdir, siteID)

    try:
      shutil.rmtree(site_dir)
      os.mkdir(site_dir)
    except:
      os.mkdir(site_dir)

    #run(rgb_images=site[0:20], dst_directory=site_dir, annotation_dir=annotation_dir)
    future = dask.delayed(run)(rgb_images=site[0:20], dst_directory=site_dir, annotation_dir=annotation_dir)
    futures.append(future)

  persisted_values = dask.persist(*futures)
  distributed.wait(persisted_values)
  for pv in persisted_values:
    try:
      print(pv)
    except Exception as e:
      print(e)
      continue


# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /Users/svpino/dev/tensorflow-object-detection-sagemaker/todl/tensorflow-object-detection/research/object_detection/builders/losses_builder.py
# Compiled at: 2020-04-05 19:50:57
# Size of source mod 2**32: 9187 bytes
"""A function to build localization and classification losses from config."""
import functools
import object_detection.core as sampler
from object_detection.core import losses
from object_detection.protos import losses_pb2
from object_detection.utils import ops

def build(loss_config):
    """Build losses based on the config.

  Builds classification, localization losses and optionally a hard example miner
  based on the config.

  Args:
    loss_config: A losses_pb2.Loss object.

  Returns:
    classification_loss: Classification loss object.
    localization_loss: Localization loss object.
    classification_weight: Classification loss weight.
    localization_weight: Localization loss weight.
    hard_example_miner: Hard example miner object.
    random_example_sampler: BalancedPositiveNegativeSampler object.

  Raises:
    ValueError: If hard_example_miner is used with sigmoid_focal_loss.
    ValueError: If random_example_sampler is getting non-positive value as
      desired positive example fraction.
  """
    classification_loss = _build_classification_loss(loss_config.classification_loss)
    localization_loss = _build_localization_loss(loss_config.localization_loss)
    classification_weight = loss_config.classification_weight
    localization_weight = loss_config.localization_weight
    hard_example_miner = None
    if loss_config.HasField('hard_example_miner'):
        if loss_config.classification_loss.WhichOneof('classification_loss') == 'weighted_sigmoid_focal':
            raise ValueError('HardExampleMiner should not be used with sigmoid focal loss')
        hard_example_miner = build_hard_example_miner(loss_config.hard_example_miner, classification_weight, localization_weight)
    else:
        random_example_sampler = None
        if loss_config.HasField('random_example_sampler'):
            if loss_config.random_example_sampler.positive_sample_fraction <= 0:
                raise ValueError('RandomExampleSampler should not use non-positivevalue as positive sample fraction.')
            random_example_sampler = sampler.BalancedPositiveNegativeSampler(positive_fraction=(loss_config.random_example_sampler.positive_sample_fraction))
        elif loss_config.expected_loss_weights == loss_config.NONE:
            expected_loss_weights_fn = None
        else:
            if loss_config.expected_loss_weights == loss_config.EXPECTED_SAMPLING:
                expected_loss_weights_fn = functools.partial((ops.expected_classification_loss_by_expected_sampling),
                  min_num_negative_samples=(loss_config.min_num_negative_samples),
                  desired_negative_sampling_ratio=(loss_config.desired_negative_sampling_ratio))
            else:
                if loss_config.expected_loss_weights == loss_config.REWEIGHTING_UNMATCHED_ANCHORS:
                    expected_loss_weights_fn = functools.partial((ops.expected_classification_loss_by_reweighting_unmatched_anchors),
                      min_num_negative_samples=(loss_config.min_num_negative_samples),
                      desired_negative_sampling_ratio=(loss_config.desired_negative_sampling_ratio))
                else:
                    raise ValueError('Not a valid value for expected_classification_loss.')
    return (
     classification_loss, localization_loss, classification_weight,
     localization_weight, hard_example_miner, random_example_sampler,
     expected_loss_weights_fn)

def build_hard_example_miner(config, classification_weight, localization_weight):
    """Builds hard example miner based on the config.

  Args:
    config: A losses_pb2.HardExampleMiner object.
    classification_weight: Classification loss weight.
    localization_weight: Localization loss weight.

  Returns:
    Hard example miner.

  """
    loss_type = None
    if config.loss_type == losses_pb2.HardExampleMiner.BOTH:
        loss_type = 'both'
    if config.loss_type == losses_pb2.HardExampleMiner.CLASSIFICATION:
        loss_type = 'cls'
    if config.loss_type == losses_pb2.HardExampleMiner.LOCALIZATION:
        loss_type = 'loc'
    max_negatives_per_positive = None
    num_hard_examples = None
    if config.max_negatives_per_positive > 0:
        max_negatives_per_positive = config.max_negatives_per_positive
    if config.num_hard_examples > 0:
        num_hard_examples = config.num_hard_examples
    hard_example_miner = losses.HardExampleMiner(num_hard_examples=num_hard_examples,
      iou_threshold=(config.iou_threshold),
      loss_type=loss_type,
      cls_loss_weight=classification_weight,
      loc_loss_weight=localization_weight,
      max_negatives_per_positive=max_negatives_per_positive,
      min_negatives_per_image=(config.min_negatives_per_image))
    return hard_example_miner

def build_faster_rcnn_classification_loss(loss_config):
    """Builds a classification loss for Faster RCNN based on the loss config.

  Args:
    loss_config: A losses_pb2.ClassificationLoss object.

  Returns:
    Loss based on the config.

  Raises:
    ValueError: On invalid loss_config.
  """
    if not isinstance(loss_config, losses_pb2.ClassificationLoss):
        raise ValueError('loss_config not of type losses_pb2.ClassificationLoss.')
    loss_type = loss_config.WhichOneof('classification_loss')
    if loss_type == 'weighted_sigmoid':
        return losses.WeightedSigmoidClassificationLoss()
    if loss_type == 'weighted_softmax':
        config = loss_config.weighted_softmax
        return losses.WeightedSoftmaxClassificationLoss(logit_scale=(config.logit_scale))
    if loss_type == 'weighted_logits_softmax':
        config = loss_config.weighted_logits_softmax
        return losses.WeightedSoftmaxClassificationAgainstLogitsLoss(logit_scale=(config.logit_scale))
    if loss_type == 'weighted_sigmoid_focal':
        config = loss_config.weighted_sigmoid_focal
        alpha = None
        if config.HasField('alpha'):
            alpha = config.alpha
        return losses.SigmoidFocalClassificationLoss(gamma=(config.gamma),
          alpha=alpha)
    config = loss_config.weighted_softmax
    return losses.WeightedSoftmaxClassificationLoss(logit_scale=(config.logit_scale))

def _build_localization_loss(loss_config):
    """Builds a localization loss based on the loss config.

  Args:
    loss_config: A losses_pb2.LocalizationLoss object.

  Returns:
    Loss based on the config.

  Raises:
    ValueError: On invalid loss_config.
  """
    if not isinstance(loss_config, losses_pb2.LocalizationLoss):
        raise ValueError('loss_config not of type losses_pb2.LocalizationLoss.')
    loss_type = loss_config.WhichOneof('localization_loss')
    if loss_type == 'weighted_l2':
        return losses.WeightedL2LocalizationLoss()
    if loss_type == 'weighted_smooth_l1':
        return losses.WeightedSmoothL1LocalizationLoss(loss_config.weighted_smooth_l1.delta)
    if loss_type == 'weighted_iou':
        return losses.WeightedIOULocalizationLoss()
    raise ValueError('Empty loss config.')

def _build_classification_loss(loss_config):
    """Builds a classification loss based on the loss config.

  Args:
    loss_config: A losses_pb2.ClassificationLoss object.

  Returns:
    Loss based on the config.

  Raises:
    ValueError: On invalid loss_config.
  """
    if not isinstance(loss_config, losses_pb2.ClassificationLoss):
        raise ValueError('loss_config not of type losses_pb2.ClassificationLoss.')
    loss_type = loss_config.WhichOneof('classification_loss')
    if loss_type == 'weighted_sigmoid':
        return losses.WeightedSigmoidClassificationLoss()
    if loss_type == 'weighted_sigmoid_focal':
        config = loss_config.weighted_sigmoid_focal
        alpha = None
        if config.HasField('alpha'):
            alpha = config.alpha
        return losses.SigmoidFocalClassificationLoss(gamma=(config.gamma),
          alpha=alpha)
    if loss_type == 'weighted_softmax':
        config = loss_config.weighted_softmax
        return losses.WeightedSoftmaxClassificationLoss(logit_scale=(config.logit_scale))
    if loss_type == 'weighted_logits_softmax':
        config = loss_config.weighted_logits_softmax
        return losses.WeightedSoftmaxClassificationAgainstLogitsLoss(logit_scale=(config.logit_scale))
    if loss_type == 'bootstrapped_sigmoid':
        config = loss_config.bootstrapped_sigmoid
        return losses.BootstrappedSigmoidClassificationLoss(alpha=(config.alpha),
          bootstrap_type=('hard' if config.hard_bootstrap else 'soft'))
    raise ValueError('Empty loss config.')


from mgmt import connection
import json
import requests

__all__ = [
    'AddSubnetLib'
]

class AddSubnetLib():
    def __init__(self):
        self.f = requests.Session()

    def run(self, mgmt_ip, sid, subnet, host_suffix, mask_length):
        '''
        Function used to Add new Network(s) to CheckPoint.
        :param mgmt_ip: IP address of the CheckPoint Management Server.
        :param sid: Session ID provided from the Login Action.
        :param subnet: Network address of the subnet that will be added to CheckPoint.
        :param host_suffix: used to create the hostname (first half) after combining it with the Network address (i.e: Network_, MaliciousNet_, N_..etc)))
        :param mask_length: mask length of the subnet that will be added to CheckPoint.
        :return: the http return status code of the api request to Add a new subnet.
        '''
        t = connection(mgmt_ip)
        url = t.create_api_url("add-network")
        print("API url used in this action: " + url)
        hostname = host_suffix+subnet+"_"+mask_length
        request_headers = {'Content-Type':'application/json', 'X-chkp-sid' : sid}
        my_data = {"name": hostname, "subnet": subnet, "mask-length":mask_length}
        r = self.f.post(url, data=json.dumps(my_data), headers=request_headers, verify=False)
        try:
            '''
            #Un-hash the following 2 lines to see the full response of the API request
            #a = json.loads(r.content)
            #print(a)'''
            return_code = r.status_code
            if return_code == 200:
                print("Subnet add for {}/{} is OK ".format(subnet, mask_length))
                return r.status_code
            else:
                print("Subnet {}/{} add is NOK ".format(subnet, mask_length))
                a = json.loads(r.content)
                print(a)
                return return_code
                '''
                #Un-hash the following 2 lines, if you want to use embedded discard to discard the changes in case of errors instead of using the Stackstorm DiscardSession action in the workflow.
                y = DiscardSessionLib()
                print(y.run(mgmt_ip, sid))
                return return_code, a['errors']'''

        except Exception as e:
            print("Error is :",e)
            '''
            #Un-hash the following 2 lines, if you want to use embedded discard to discard the changes in case of errors instead of using the Stackstorm DiscardSession action in the workflow.
            y = DiscardSessionLib()
            print(y.run(mgmt_ip, sid))
            return return_code, a['errors']'''


# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from collections import defaultdict
from dateutil.relativedelta import relativedelta

from odoo import api, fields, models, SUPERUSER_ID, _
from odoo.osv import expression
from odoo.addons.stock.models.stock_rule import ProcurementException

class StockRule(models.Model):
    _inherit = 'stock.rule'

    @api.model
    def _run_manufacture(self, procurements):
        productions_values_by_company = defaultdict(list)
        errors = []
        for procurement, rule in procurements:
            bom = rule._get_matching_bom(procurement.product_id,
                                         procurement.company_id, procurement.values)
            if not bom:
                msg = _('There is no Bill of Material of type manufacture or kit found for the product %s. Please define a Bill of Material for this product.') % (
                    procurement.product_id.display_name,)
                errors.append((procurement, msg))

            productions_values_by_company[procurement.company_id.id].append(
                rule._prepare_mo_vals(*procurement, bom))

        if errors:
            raise ProcurementException(errors)

        for company_id, productions_values in productions_values_by_company.items():
            # creck if already exists someone mrp production order with the same production
            productions_values_check = []
            for p in productions_values:
                print(">>>>>>>>>>>>>>>>>>>>> p:", p)
                current_qty = p['product_qty']
                mrp_production_ids = self.env['mrp.production'].search([
                    ('product_id', '=', p['product_id']),
                    ('origin', '=', p['origin']),
                    ('state', 'not in', ('cancel', 'done', 'draft'))], order='id')
                if mrp_production_ids:
                    mrp_qty = sum(m.product_qty for m in mrp_production_ids)
                    diff_qty = current_qty-mrp_qty
                    if diff_qty > 0:
                        p['product_qty'] = diff_qty
                        productions_values_check.append(p)
                    else:
                        break
                else:
                    productions_values_check.append(p)

            productions_values = productions_values_check
            print(">>>>>>>>>>>>>>>>>>>>> productions_values_check:", productions_values_check)

            # create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
            productions = self.env['mrp.production'].with_user(
                SUPERUSER_ID).sudo().with_company(company_id).create(productions_values)
            self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
            self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
            productions._create_workorder()
            productions.filtered(lambda p: p.move_raw_ids).action_confirm()

            for production in productions:
                origin_production = production.move_dest_ids and production.move_dest_ids[
                    0].raw_material_production_id or False
                orderpoint = production.orderpoint_id
                if orderpoint:
                    production.message_post_with_view('mail.message_origin_link',
                                                      values={'self': production,
                                                              'origin': orderpoint},
                                                      subtype_id=self.env.ref('mail.mt_note').id)
                if origin_production:
                    production.message_post_with_view('mail.message_origin_link',
                                                      values={'self': production,
                                                              'origin': origin_production},
                                                      subtype_id=self.env.ref('mail.mt_note').id)
        return True
        # res = super(StockRule, self)._run_manufacture(procurements)
        # print res


#!/usr/bin/env python3
# Copyright (c) 2014 The Caroline authors. All rights reserved.
# Use of this source file is governed by a MIT license that can be found in the
# LICENSE file.
# Author: Aleksandr Derbenev <alex@technoworks.ru>

import json
from optparse import OptionParser
import os
import shutil
import random
import math

import bpy

class Bounds(object):
  def __init__(self, camera):
    self.angle_x = camera.angle_x
    self.angle_y = camera.angle_y
    self.angle = camera.angle
    self.clip_near = camera.clip_start
    self.clip_far = camera.clip_end

def random_mesh_origin(angle_x, angle_y, clip_near, clip_far):
  """Create random origin point for mesh. Assume that object will be visible if
     it's origin is in the truncated pyramid."""
  # Get z coordinate first because x and y ranges depends from it.
  z = random.uniform(clip_near + 2, clip_far - 2)
  x = random.uniform(-math.tan(angle_x / 2) * z,
      math.tan(angle_x / 2) * z / 2)
  y = random.uniform(-math.tan(angle_y / 2) * z,
      math.tan(angle_y / 2) * z / 2)
  return [x, y, -z]

def random_mesh_rotation():
  """Generate random angles for initial mesh rotation."""
  return [random.random(), random.random(), random.random()];

def random_mesh_constructor():
  """Returs lambda for creating a random mesh with given origin point and
     rotation."""
  def dimension(max_size):
    """Return random value for dimension."""
    return random.uniform(max_size / 10, max_size)

  return random.choice((
      lambda origin, rotation, max_size:
       bpy.ops.mesh.primitive_cone_add(radius1 = dimension(max_size) / 2,
           radius2 = dimension(max_size) / 2, depth = dimension(max_size),
           end_fill_type='TRIFAN',
           location=origin, rotation=rotation),
      lambda origin, rotation, max_size:
       bpy.ops.mesh.primitive_cube_add(radius = dimension(max_size) / 2,
           location = origin, rotation = rotation),
      lambda origin, rotation, max_size:
       bpy.ops.mesh.primitive_cylinder_add(radius = dimension(max_size) / 2,
           depth = dimension(max_size),
           location = origin, rotation = rotation),
      lambda origin, rotation, max_size:
       bpy.ops.mesh.primitive_ico_sphere_add(size = dimension(max_size) / 2,
           location = origin, rotation = rotation),
      lambda origin, rotation, max_size:
       bpy.ops.mesh.primitive_monkey_add(radius = dimension(max_size) / 2,
           location = origin, rotation = rotation),
      lambda origin, rotation, max_size:
       bpy.ops.mesh.primitive_plane_add(radius = dimension(max_size) / 2,
           location = origin, rotation = rotation),
      lambda origin, rotation, max_size:
       bpy.ops.mesh.primitive_torus_add(
           major_radius = random.uniform(max_size / 4, max_size) / 2,
           minor_radius = dimension(max_size / 5) / 2,
           location = origin, rotation = rotation),
      lambda origin, rotation, max_size:
       bpy.ops.mesh.primitive_uv_sphere_add(size = dimension(max_size) / 2,
           location = origin, rotation = rotation)
    ))

def override_context(options):
  """Copy bpy.context and replace some values by provided in dictionary."""
  context = bpy.context.copy()
  for key in options.keys():
    context[key] = options[key]
  return context

def parse_options():
  """Configure and run command line arguments parser."""
  parser = OptionParser()
  parser.add_option('-f', '--fixtures', dest = 'count', type = 'int',
      default = 1, action = 'store',
      help = 'Number of test fixtures to generate.')
  parser.add_option('-m', '--meshes', dest = 'meshes', type = 'int',
      default = 1, action = 'store',
      help = 'Maximum number of meshes in the scene.')
  parser.add_option('-o', '--output', dest = 'output', type = 'string',
      default = 'fixture', action = 'store',
      help = 'Name of the output directory. You can use %n for fixture number.'),
  parser.add_option('-d', '--distance', dest = 'distance', type = 'float',
      default = 0.08, action = 'store',
      help = 'Distantion between cameras in meters.')
  (options, args) = parser.parse_args()
  if options.count < 1:
    parser.error('Count of fixtures must be positive integer number.')
  if options.meshes < 1:
    parser.error('Maximum count of meshes must be positive integer number.')
  if options.count > 1 and '%n' not in options.output:
    options.output += '.%n'
  if options.distance <= 0:
    parser.error('Distance must be greater that 0.')
  options.output = options.output.replace('%n', '{number}')
  return (options, args);

def get_camera():
  camera = None
  for cam in bpy.data.cameras:
    if cam.name in bpy.context.scene.objects.keys():
      camera = cam
      break
  camera_object = bpy.data.objects[camera.name]
  return (camera, camera_object)

def cleanup_scene():
  """Cleanup current scene"""
  for item in bpy.data.meshes:
    if item.name in bpy.context.scene.objects.keys():
      bpy.context.scene.objects.unlink(bpy.data.objects[item.name])

def generate_mesh(bounds):
  """Count location and rotation for mesh, get and call constructor."""
  origin = random_mesh_origin(bounds.angle_x, bounds.angle_y,
      bounds.clip_near, bounds.clip_far)
  rotation = random_mesh_rotation()
  max_size = - origin[2] * math.tan(bounds.angle / 2)
  random_mesh_constructor()(origin=origin, rotation=rotation,
      max_size=max_size)

def generate_meshes(count, bounds):
  """Generate meshes on the scene."""
  for i in range(count):
    generate_mesh(bounds = bounds)

def setup_light(bounds):
  """Find and set lamp to the appropriate location."""
  lamp = bpy.data.lamps[0]
  if not lamp:
    lamp = bpy.data.lamps.new(name='lamp', type='SUN')
  lamp_object = bpy.data.objects[lamp.name]
  if lamp.name not in bpy.context.scene.objects:
    bpy.context.scene.objects.link(lamp_object)

  lamp_location = [
      0.0,
      math.tan(bounds.angle) * bounds.clip_far,
      -(bounds.clip_far - bounds.clip_near) / 2
    ]
  lamp.type = 'SUN'
  lamp_object.location = lamp_location
  lamp_object.rotation_mode = 'XYZ'
  lamp_object.rotation_euler = [0, - math.pi / 2, 0]

def prepare_dir(name):
  """Remove fixture directory if it exists. Create new one."""
  if os.path.exists(name):
    shutil.rmtree(name)

  os.mkdir(name)

def save_models(name):
  """Save each mesh to the Standford ply file. Return scene dictionary for
     config."""
  scene = {}
  for mesh in bpy.data.meshes:
    if mesh.name in bpy.context.scene.objects.keys():
      mesh_ply = mesh.name + '.ply'
      bpy.ops.export_mesh.ply(override_context({'selected_objects': mesh}),
          filepath=os.path.join(name, mesh_ply), check_existing=False,
          use_mesh_modifiers=False, use_normals=False, use_uv_coords=False,
          use_colors=False)
      scene[mesh.name] = mesh_ply
  return scene

def render_frames(name, distance, camera, camera_object, bounds):
  """Setup camera and render two frames."""
  cameras = []
  for i, location in enumerate([
    [-distance / 2, 0, 0],
    [distance / 2, 0, 0]
  ]):
    render = bpy.context.scene.render
    width = render.resolution_x
    height = render.resolution_y
    cam_name = 'camera_' + str(i)
    render.filepath = os.path.join(name, cam_name + '.png')
    camera_object.location = location
    camera_object.rotation_mode = 'XYZ'
    camera_object.rotation_euler = [0, 0, 0]
    bpy.ops.render.render(animation=False, write_still=True)
    cam = {
      'focus': camera.lens / 1000.0,
      'pixel_size': camera.sensor_width / width / 1000.0,
      'width': width,
      'height': height,
      'position': camera_object.location[:],
      'rotation': camera_object.rotation_euler[:],
      'type': 'image',
      'source': camera.name + '.png'
    }
    cameras.append(cam)
  return cameras

def save_config(name, config):
  """Generate config.json for given fixture."""
  config_file = open(os.path.join(name, 'config.json'), 'w')
  json.dump(config, config_file, skipkeys=True, ensure_ascii=False,
      allow_nan=False, indent=2, sort_keys=True)
  config_file.write('\n')

def save_fixture(name, distance, camera, camera_object, bounds):
  prepare_dir(name = name)

  config = {}
  config['scene'] = save_models(name = name)

  config['cameras'] = render_frames(name = name, distance = distance,
      camera = camera, camera_object = camera_object, bounds = bounds)

  save_config(name = name, config = config)

def generate_fixture(name, meshes, distance):
  """Generate and save a fixture."""

  name = os.path.normpath(name)

  (camera, camera_object) = get_camera()
  bounds = Bounds(camera)

  cleanup_scene()

  generate_meshes(count = meshes, bounds = bounds)
  setup_light(bounds = bounds)

  save_fixture(name = name, distance = distance, camera=camera,
      camera_object=camera_object, bounds=bounds)

def generate_fixtures(count, output, meshes, distance):
  """Generate all fixtures."""
  for i in range(count):
    generate_fixture(name = output.format(number = i),
        meshes = random.randrange(meshes) + 1, distance = distance)

def main():
  """Entry point."""
  (options, args) = parse_options()
  generate_fixtures(count = options.count, output = options.output,
      meshes = options.meshes, distance = options.distance)

if __name__ == '__main__':
  main()