import tensorflow as tf
from tensorflow.contrib.framework.python.ops import add_arg_scope, arg_scope
import warnings
import tensorflow_probability as tfp
import numpy as np
tfb = tfp.bijectors

def dynamic_deconv_op3d(x, W, strides=[1,2,2,2,1], padding='SAME'):

    filter_size = tf.shape(W)#list(map(int, W.get_shape()))
    xs = tf.shape(x)
    target_shape = tf.shape(x)
    #channelscale = int(int(W.get_shape()[-1])/int(x.get_shape()[-1]))
    if padding == 'SAME':
        shapescaling = tf.constant([1, strides[1], strides[2], strides[3], 1])
        print(shapescaling)
        target_shape = target_shape*shapescaling
    if padding == 'VALID':
        shapescaling = tf.constant([1, strides[1], strides[2], strides[3], 1])
        shapeoffset =  tf.constant([0, filter_size[0]-1, filter_size[1]-1, filter_size[2]-1, 1])
        #This doesnt seem to be working. Figure out at some point
        target_shape = target_shape*shapescaling
        target_shape = target_shape+shapeoffset
    return tf.nn.conv3d_transpose(x, W, target_shape, strides, padding)

def dynamic_deconv3d(name, x, shape, strides=[1,2,2,2,1], activation=tf.nn.leaky_relu):
    in_dim = x.get_shape()[-1]
    W_shape = [shape[0], shape[1], shape[2], in_dim, shape[3]]
    W = tf.get_variable(name+'_W', W_shape, tf.float32, tf.contrib.layers.xavier_initializer())
    b = tf.get_variable(name+'_b', W_shape[3], tf.float32, tf.zeros_initializer)
    conv = dynamic_deconv_op3d(x, W, strides=strides)
    return activation(tf.add(conv, b))

###Following spectral normed conv3d has been contributed by Francois Lanusse

NO_OPS = 'NO_OPS'
def _l2normalize(v, eps=1e-12):
    return v / (tf.reduce_sum(v ** 2) ** 0.5 + eps)

def spectral_normed_weight(W, u=None, num_iters=1, update_collection=None, with_sigma=False, normwt=0.7):
  # Usually num_iters = 1 will be enough
    W_shape = W.shape.as_list()
    W_reshaped = tf.reshape(W, [-1, W_shape[-1]])

    if u is None:
        u = tf.get_variable("u", [1, W_shape[-1]], initializer=tf.truncated_normal_initializer(), trainable=False)

    def power_iteration(i, u_i, v_i):
        v_ip1 = _l2normalize(tf.matmul(u_i, tf.transpose(W_reshaped)))
        u_ip1 = _l2normalize(tf.matmul(v_ip1, W_reshaped))
        return i + 1, u_ip1, v_ip1

    _, u_final, v_final = tf.while_loop(
        cond=lambda i, _1, _2: i < num_iters,
        body=power_iteration,
        loop_vars=(tf.constant(0, dtype=tf.int32),
                   u, tf.zeros(dtype=tf.float32, shape=[1, W_reshaped.shape.as_list()[0]]))
      )

    if update_collection is None:
        warnings.warn('Setting update_collection to None will make u being updated every W execution. This maybe undesirable'
                  '. Please consider using a update collection instead.')
        sigma = tf.matmul(tf.matmul(v_final, W_reshaped), tf.transpose(u_final))[0, 0]
        # sigma = tf.reduce_sum(tf.matmul(u_final, tf.transpose(W_reshaped)) * v_final)
        scaling = tf.minimum(1., normwt/sigma)
        #scaling = normwt/sigma
        W_bar = W_reshaped *scaling
        with tf.control_dependencies([u.assign(u_final)]):
            W_bar = tf.reshape(W_bar, W_shape)
    else:
        sigma = tf.matmul(tf.matmul(v_final, W_reshaped), tf.transpose(u_final))[0, 0]
        # sigma = tf.reduce_sum(tf.matmul(u_final, tf.transpose(W_reshaped)) * v_final)
        W_bar = W_reshaped / sigma
        W_bar = tf.reshape(W_bar, W_shape)
        # Put NO_OPS to not update any collection. This is useful for the second call of discriminator if the update_op
        # has already been collected on the first call.
        if update_collection != NO_OPS:
            tf.add_to_collection(update_collection, u.assign(u_final))
    if with_sigma:
        return W_bar, sigma
    else:
        return W_bar

@add_arg_scope
def scope_has_variables(scope):
    return len(tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope=scope.name)) > 0

@add_arg_scope
def specnormconv3d(input_, output_dim,
           kernel_size=3, stride=1, stddev=None,
           name="conv3d", spectral_normed=True, update_collection=None, with_w=False,
                   padding="SAME", reuse=tf.AUTO_REUSE, num_iters=1, normwt=1):

    k_h, k_w, k_z = [kernel_size]*3
    d_h, d_w, d_z = [stride]*3
    # Glorot intialization
    # For RELU nonlinearity, it's sqrt(2./(n_in)) instead
    fan_in = k_h * k_w * k_z * input_.get_shape().as_list()[-1]
    fan_out = k_h * k_w * k_z * output_dim
    if stddev is None:
        stddev = tf.sqrt(2. / (fan_in))

    with tf.variable_scope(name) as scope:
        if scope_has_variables(scope):
            scope.reuse_variables()
        w = tf.get_variable("w", [k_h, k_w, k_z, input_.get_shape()[-1], output_dim],
                            initializer=tf.truncated_normal_initializer(stddev=stddev))
        if spectral_normed:
            conv = tf.nn.conv3d(input_, spectral_normed_weight(w, update_collection=update_collection, num_iters=num_iters, normwt=normwt),
                              strides=[1, d_h, d_w, d_z, 1], padding=padding)
        else:
            conv = tf.nn.conv3d(input_, w, strides=[1, d_h, d_w, d_z, 1], padding=padding)

        biases = tf.get_variable("b", [output_dim], initializer=tf.constant_initializer(0.0))
        conv = tf.nn.bias_add(conv, biases)
        if with_w:
            return conv, w, biases
        else:
            return conv

@add_arg_scope
def specnormconv2d(input_, output_dim,
           kernel_size=3, stride=1, stddev=None,
           name="conv2d", spectral_normed=True, update_collection=None, with_w=False,
                   padding="SAME", reuse=tf.AUTO_REUSE, num_iters=1, normwt=1.):

    k_h, k_w = [kernel_size]*2
    d_h, d_w = [stride]*2
    # Glorot intialization
    # For RELU nonlinearity, it's sqrt(2./(n_in)) instead
    fan_in = k_h * k_w * input_.get_shape().as_list()[-1]
    fan_out = k_h * k_w * output_dim
    if stddev is None:
        stddev = tf.sqrt(2. / (fan_in))

    with tf.variable_scope(name) as scope:
        if scope_has_variables(scope):
            scope.reuse_variables()
        w = tf.get_variable("w", [k_h, k_w, input_.get_shape()[-1], output_dim],
                            initializer=tf.truncated_normal_initializer(stddev=stddev))
        if spectral_normed:
            conv = tf.nn.conv2d(input_, spectral_normed_weight(w, update_collection=update_collection,
                                                               num_iters=num_iters, normwt=normwt),
                              strides=[1, d_h, d_w, 1], padding=padding)
        else:
            conv = tf.nn.conv2d(input_, w, strides=[1, d_h, d_w, 1], padding=padding)

        biases = tf.get_variable("b", [output_dim], initializer=tf.constant_initializer(0.0))
        conv = tf.nn.bias_add(conv, biases)
        if with_w:
            return conv, w, biases
        else:
            return conv

@add_arg_scope
def specnormconv1d(input_, output_dim,
           kernel_size=3, stride=1, stddev=None,
           name="conv1d", spectral_normed=True, update_collection=None, with_w=False,
                   padding="SAME", reuse=tf.AUTO_REUSE, num_iters=1):

    k_h = kernel_size
    d_h = stride
    # Glorot intialization
    # For RELU nonlinearity, it's sqrt(2./(n_in)) instead
    fan_in = k_h * input_.get_shape().as_list()[-1]
    fan_out = k_h * output_dim
    if stddev is None:
        stddev = tf.sqrt(2. / (fan_in))

    with tf.variable_scope(name) as scope:
        if scope_has_variables(scope):
            scope.reuse_variables()
        w = tf.get_variable("w", [k_h, input_.get_shape()[-1], output_dim],
                            initializer=tf.truncated_normal_initializer(stddev=stddev))
        #w = tf.get_variable("w", [k_h, input_.get_shape()[-1], output_dim],
        #                    initializer=tf.glorot_uniform_initializer())
        if spectral_normed:
            conv = tf.nn.conv1d(input_, spectral_normed_weight(w, update_collection=update_collection,
                                                               num_iters=num_iters),
                              stride=d_h, padding=padding)
        else:
            conv = tf.nn.conv1d(input_, w, stride=d_h, padding=padding)

        biases = tf.get_variable("b", [output_dim], initializer=tf.constant_initializer(0.0))
        conv = tf.nn.bias_add(conv, biases)
        if with_w:
            return conv, w, biases
        else:
            return conv

###Following have been taken from https://github.com/openai/glow/blob/master/tfops.py
###and modified to 3D. In addition, some variable names have been modified
###and assumptions on shape of input being constant relaxed

def int_shape(x):
    if str(x.get_shape()[0]) != '?':
        return list(map(int, x.get_shape()))
    return [-1]+list(map(int, x.get_shape()[1:]))

# Invertible 1x1 conv
@add_arg_scope
def invertible_1x1_conv(name, z, reverse=False):

    if True:  # Set to "False" to use the LU-decomposed version

        with tf.variable_scope(name, reuse=tf.AUTO_REUSE):

            shape = int_shape(z)
            w_shape = [shape[-1], shape[-1]]

            # Sample a random orthogonal matrix:
            w_init = np.linalg.qr(np.random.randn(
                *w_shape))[0].astype('float32')

            w = tf.get_variable("W", dtype=tf.float32, initializer=w_init)
            # dlogdet = tf.linalg.LinearOperator(w).log_abs_determinant() * shape[1]*shape[2]
            logdet = tf.cast(tf.log(abs(tf.matrix_determinant(
                tf.cast(w, 'float64')))), 'float32') * shape[1]*shape[2]*shape[3]
            if not reverse:

                _w = tf.reshape(w, [1, 1, 1] + w_shape)
                z = tf.nn.conv3d(z, _w, [1, 1, 1, 1, 1],
                                 'SAME', data_format='NDHWC')
                return z, logdet
            else:

                _w = tf.matrix_inverse(w)
                _w = tf.reshape(_w, [1, 1, 1]+w_shape)
                z = tf.nn.conv3d(z, _w, [1, 1, 1, 1, 1],
                                 'SAME', data_format='NDHWC')
                return z, -logdet

    else:

        # LU-decomposed version
        shape = int_shape(z)
        with tf.variable_scope(name, reuse=tf.AUTO_REUSE):

            dtype = 'float64'

            # Random orthogonal matrix:
            import scipy
            np_w = scipy.linalg.qr(np.random.randn(shape[-1], shape[-1]))[
                0].astype('float32')

            np_p, np_l, np_u = scipy.linalg.lu(np_w)
            np_s = np.diag(np_u)
            np_sign_s = np.sign(np_s)
            np_log_s = np.log(abs(np_s))
            np_u = np.triu(np_u, k=1)

            p = tf.get_variable("P", initializer=np_p, trainable=False)
            l = tf.get_variable("L", initializer=np_l)
            sign_s = tf.get_variable(
                "sign_S", initializer=np_sign_s, trainable=False)
            log_s = tf.get_variable("log_S", initializer=np_log_s)
            # S = tf.get_variable("S", initializer=np_s)
            u = tf.get_variable("U", initializer=np_u)

            p = tf.cast(p, dtype)
            l = tf.cast(l, dtype)
            sign_s = tf.cast(sign_s, dtype)
            log_s = tf.cast(log_s, dtype)
            u = tf.cast(u, dtype)

            w_shape = [shape[-1], shape[-1]]

            l_mask = np.tril(np.ones(w_shape, dtype=dtype), -1)
            l = l * l_mask + tf.eye(*w_shape, dtype=dtype)
            u = u * np.transpose(l_mask) + tf.diag(sign_s * tf.exp(log_s))
            w = tf.matmul(p, tf.matmul(l, u))

            if True:
                u_inv = tf.matrix_inverse(u)
                l_inv = tf.matrix_inverse(l)
                p_inv = tf.matrix_inverse(p)
                w_inv = tf.matmul(u_inv, tf.matmul(l_inv, p_inv))
            else:
                w_inv = tf.matrix_inverse(w)

            w = tf.cast(w, tf.float32)
            w_inv = tf.cast(w_inv, tf.float32)
            log_s = tf.cast(log_s, tf.float32)

            if not reverse:

                w = tf.reshape(w, [1, 1, 1] + w_shape)
                z = tf.nn.conv3d(z, w, [1, 1, 1, 1, 1],
                                 'SAME', data_format='NDHWC')
                logdet = tf.reduce_sum(log_s) * (shape[1]*shape[2]*shape[3])

                return z, logdet
            else:

                w_inv = tf.reshape(w_inv, [1, 1, 1]+w_shape)
                z = tf.nn.conv3d(
                    z, w_inv, [1, 1, 1, 1, 1], 'SAME', data_format='NDHWC')
                logdet = -tf.reduce_sum(log_s) * (shape[1]*shape[2]*shape[3])

                return z, logdet

@add_arg_scope
def get_variable_ddi(name, shape, initial_value, dtype=tf.float32, init=False, trainable=True):
    w = tf.get_variable(name, shape, dtype, None, trainable=trainable)
    if init:
        w = w.assign(initial_value)
        with tf.control_dependencies([w]):
            return w
    return w

@add_arg_scope
def actnorm3d(x, scale=1., logscale_factor=3., batch_variance=False,
            reverse=False, init=False, is_training=True, scope='actnorm'):
    """
    Borrowed from https://github.com/openai/glow/blob/master/tfops.py
    """
    name = scope
    if arg_scope([get_variable_ddi], trainable=is_training):
        if not reverse:
            x = actnorm_center3d(name+"_center", x, reverse)
            x, logdet = actnorm_scale3d(name+"_scale", x, scale,
                              logscale_factor, batch_variance, reverse, init)
        else:
            x, logdet = actnorm_scale3d(name + "_scale", x, scale,
                              logscale_factor, batch_variance, reverse, init)

            x = actnorm_center3d(name+"_center", x, reverse)
        return x, logdet

@add_arg_scope
def actnorm_center3d(name, x, reverse=False):
    shape = x.get_shape()
    with tf.variable_scope(name, reuse=tf.AUTO_REUSE):
        assert len(shape) == 5
        x_mean = tf.reduce_mean(x, [0, 1, 2, 3], keepdims=True)
        b = get_variable_ddi(
#             "b", (1, 1, 1, 1, int_shape(x)[4]), initial_value=-x_mean)
            "b", (1, 1, 1, 1, shape[4]), initial_value=-x_mean)

        if not reverse:
            x += b
        else:
            x -= b

        return x

@add_arg_scope
def actnorm_scale3d(name, x, scale=1., logscale_factor=3.,
                  batch_variance=False, reverse=False, init=False, trainable=True):
    shape = x.get_shape()
    with tf.variable_scope(name, reuse=tf.AUTO_REUSE), arg_scope([get_variable_ddi], trainable=trainable):
        assert len(shape) == 5
        x_var = tf.reduce_mean(x**2, [0, 1, 2, 3], keepdims=True)
#         logdet_factor = int(shape[1])*int(shape[2])*int(shape[3])
        logdet_factor = int(shape[1])*int(shape[2])*int(shape[3])
#         _shape = (1, 1, 1, 1, int_shape(x)[4])
        _shape = (1, 1, 1, 1, shape[4])

        if batch_variance:
            x_var = tf.reduce_mean(x**2, keepdims=True)

        if True:
            logs = get_variable_ddi("logs", _shape, initial_value=tf.log(
                scale/(tf.sqrt(x_var)+1e-6))/logscale_factor)*logscale_factor
            if not reverse:
                x = x * tf.exp(logs)
            else:
                x = x * tf.exp(-logs)
        else:
            # Alternative, doesn't seem to do significantly worse or better than the logarithmic version above
            s = get_variable_ddi("s", _shape, initial_value=scale /
                                 (tf.sqrt(x_var) + 1e-6) / logscale_factor)*logscale_factor
            logs = tf.log(tf.abs(s))
            if not reverse:
                x *= s
            else:
                x /= s

        dlogdet = tf.reduce_sum(logs) * logdet_factor
        if reverse:
            dlogdet *= -1
        return x, dlogdet

#Squeeze operation for invertible downsampling in 3D
#
#
class Squeeze3d(tfb.Reshape):
    """
    Borrowed from https://github.com/openai/glow/blob/master/tfops.py
    """
    def __init__(self,
                 event_shape_in,
                 factor=2,
                 is_constant_jacobian=True,
                 validate_args=False,
                 name=None):

        assert factor >= 1
        name = name or "squeeze"
        self.factor = factor
        event_shape_out = 1*event_shape_in
        event_shape_out[0] //=2
        event_shape_out[1] //=2
        event_shape_out[2] //=2
        event_shape_out[3] *=8
        self.event_shape_out = event_shape_out

        super(Squeeze3d, self).__init__(
            event_shape_out=event_shape_out,
            event_shape_in=event_shape_in,
        validate_args=validate_args,
        name=name)

    def _forward(self, x):
        if self.factor == 1:
            return x
        factor = self.factor

        shape = tf.shape(x)
        height = shape[1]
        width = shape[2]
        length = shape[3]
        n_channels = x.get_shape()[4]

#         print(height, width, length, n_channels )
#         assert height % factor == 0 and width % factor == 0 and length % factor == 0
        x = tf.reshape(x, [-1, height//factor, factor,
                           width//factor, factor, length//factor, factor, n_channels])
        x = tf.transpose(x, [0, 1, 3, 5, 7, 2, 4, 6])
        x = tf.reshape(x, [-1, height//factor, width//factor,
                               length//factor, n_channels*factor**3])
        return x

    def _inverse(self, x):
        if self.factor == 1:
            return x
        factor = self.factor

        shape = tf.shape(x)
        height = shape[1]
        width = shape[2]
        length = shape[3]
        n_channels = int(x.get_shape()[4])

#         print(height, width, length, n_channels )
        assert n_channels >= 8 and n_channels % 8 == 0
        x = tf.reshape(
            x, [-1, height, width, length, int(n_channels/factor**3), factor, factor, factor])
        x = tf.transpose(x, [0, 1, 5, 2, 6, 3, 7, 4])
        x = tf.reshape(x, (-1, height*factor,
                           width*factor, height*factor, int(n_channels/factor**3)))
        return x

def f_net(name, h, width, n_out=None):
    n_out = n_out or int(h.get_shape()[4])
    with tf.variable_scope(name, reuse=tf.AUTO_REUSE):
        h = tf.layers.conv3d(h, width, 3, padding='SAME', activation=tf.nn.relu)
        h = tf.layers.conv3d(h, n_out, 3, padding='SAME', activation=None)
    return h

def f_net3d(name, h, width, n_out=None):

    k_h, k_w, k_z = [3]*3
    fan_in = k_h * k_w * k_z * h.get_shape().as_list()[-1]
    stddev = tf.sqrt(2. / (fan_in))
    n_out = n_out or int(h.get_shape()[4])

    with tf.variable_scope(name, reuse=tf.AUTO_REUSE):
#         if scope_has_variables(scope):
#             scope.reuse_variables()
        w1 = tf.get_variable("w1", [3, 3, 3, h.get_shape()[-1], width],
                            initializer=tf.truncated_normal_initializer(stddev=stddev))
        w2 = tf.get_variable("w2", [3, 3, 3, width, width],
                            initializer=tf.truncated_normal_initializer(stddev=stddev))
        wout = tf.get_variable("wout", [3, 3, 3, width, n_out],
                            initializer=tf.truncated_normal_initializer(stddev=stddev))

        h = tf.nn.relu(tf.nn.conv3d(h, w1, strides=[1, 1, 1, 1, 1], padding='SAME'))
        h = tf.nn.relu(tf.nn.conv3d(h, w2, strides=[1, 1, 1, 1, 1], padding='SAME'))
        h = tf.nn.conv3d(h, wout, strides=[1, 1, 1, 1, 1], padding='SAME')
    return h


from binaryninja import BackgroundTaskThread
from binaryninjaui import DockHandler

import asyncio
import time

try:
    from pypresence import Presence
except ModuleNotFoundError:
    from pip._internal import main
    main(['install', '--quiet', 'pypresence==4.0.0'])

class Binjcord(BackgroundTaskThread):
    def __init__(self):
        super().__init__('binjcord running', True)
        self.time_started = time.time()
        self.rpc = Presence("740982162249089034")
        self.done = False

    def run(self):
        asyncio.set_event_loop(asyncio.new_event_loop())
        self.rpc.connect()
        dock = DockHandler.getActiveDockHandler()
        while not self.done:
            frame = dock.getViewFrame()
            if frame:
                fname = frame.getShortFileName()
                offset = hex(frame.getCurrentOffset())
                self.rpc.update(start=self.time_started,
                                large_image='binja',
                                large_text='Binary Ninja',
                                state=fname,
                                details=offset)
                time.sleep(15)
        self.rpc.close()

    def finish(self): self.done = True
    def cancel(self): self.done = True

Binjcord().start()


from datasets import load_dataset
import json

# 加载CoNLL-2003数据集、分词器
dataset = load_dataset('conll2003')
dataset_dict={}
label_list = dataset["train"].features["ner_tags"].feature.names

# 将训练集转换为可训练的特征形式
def tokenize_and_align_labels(examples):
    for id,tokens,ner_tags in zip(examples['id'],examples['tokens'],examples['ner_tags']):
        ner_labels=[label_list[ett_order] for ett_order in ner_tags]
        dataset_dict[id]={'sents':' '.join(tokens),'ner_labels':' '.join(ner_labels)}

datasets = dataset.map(tokenize_and_align_labels, batched=True, load_from_cache_file=False)
with open('conll2003.jsonl','w',encoding='utf8') as file:
    file.write(json.dumps(dataset_dict,indent=4))


#create the database
import sqlite3
import random
import string

example_db = '/var/jail/home/shruthi/gesture/random.db'

def create_database():
    conn = sqlite3.connect(example_db)  # connect to that database (will create if it doesn't already exist)
    c = conn.cursor()  # move cursor into database (allows us to execute commands)
    c.execute('''CREATE TABLE IF NOT EXISTS gestures_table (number int,x_vals text, y_vals text);''') # run a CREATE TABLE command
    conn.commit() # commit commands (VERY IMPORTANT!!)
    conn.close() # close connection to database

gest_list = []

def request_handler(request):
    if request["method"] == "GET":
        conn = sqlite3.connect(example_db)
        c = conn.cursor()
        things = c.execute('''SELECT * FROM gestures_table;''').fetchall() #WHERE number=1
        for row in things:
            gest_list.append(row)
        conn.commit()
        conn.close()
        return gest_list
    if request["method"] == "POST":
        create_database()  #call the function!

        number = int(request["form"]["number"])
        x_vals = request["form"]["x_vals"]
        y_vals = request["form"]["y_vals"]

        #send these values to the database
        conn = sqlite3.connect(example_db)
        c = conn.cursor()
        c.execute('''INSERT into gestures_table VALUES (%d, %s, %s);'''%(number, x_vals, y_vals))
        conn.commit()
        conn.close()

        return (number, x_vals, y_vals)
        #have the esp retrieve values from the database


from bs4 import BeautifulSoup
from main_bot.services.request import RequestManager

class ParseBleacherReport(RequestManager):
    """Парсер сайта bleacher report"""

    def __init__(self) -> None:
        self.__url = "https://bleacherreport.com/boston-celtics"
        self.source_site = f'' \
                           f'{self.__url.split("//")[0]}//' \
                           f'{self.__url.split("//")[1].split("/")[0]}'

    def parse_posts(self) -> list:
        get_content = self.get(self.__url)
        soup = BeautifulSoup(get_content.text, "html.parser")
        posts = soup.find_all("li", class_="articleSummary")
        posts_list = []
        for post in posts:
            post_link = post.find(
                "div",
                class_="articleContent"
            ).find("a", class_="atom")
            post_name = post.find('div', class_="articleContent").text
            if post_link:
                get_link = post_link.get("href")
                posts_dict = {
                    "post_title": post_name,
                    "link": get_link,
                    "proof": self.source_site
                }
                posts_list.append(posts_dict)
        return posts_list


import base64
import io
import os
import urllib

import matplotlib
import matplotlib.pyplot as plt
import pandas as pd

def get_base64_string(fig):
    buf = io.BytesIO()
    fig.savefig(buf, format='png',  bbox_inches="tight")
    buf.seek(0)
    string = base64.b64encode(buf.read())
    uri = urllib.parse.quote(string)
    return uri

def generate_plots_with_data(alldata):
    cols = ['DATE', 'AMOUNT', 'WHERE', 'TAGS']
    data = [[p.date, p.amount, p.where, p.tags] for p in alldata]
    df = pd.DataFrame(data=data, columns=cols)
    df.set_index("DATE", inplace=True)
    return df

def generate_plot(tdata):

    plt.style.use("ggplot")
    matplotlib.use('Agg')

    tdata.index = pd.to_datetime(tdata.index)
    # path = os.path.dirname(os.path.abspath(__file__))
    # static_path = os.path.join(path, "static", "exp")
    year = tdata.index.year.unique().max()
    data = tdata[tdata.index.year == year]

    this_month = data.index.month.unique().max()

    monthgroup = data.groupby(data.index.month)
    mmean = monthgroup.mean().mean()

    datadict = {}

    with plt.xkcd():
        ax = monthgroup.sum().plot.bar(color="orange", alpha=0.8, rot=0)
        ax.hlines(mmean, -100, 100, linestyles="dashed")
        ax.set_xlabel("Months")
        ax.set_title("Months Spends")
        fig = plt.gcf()
        # plt.savefig(os.path.join(static_path,"month.png"))
        monthly_spend = get_base64_string(fig)
        datadict["monthly_spend"] = monthly_spend
        plt.close()

    weekgroup = data.groupby([data.index.week])
    wmean = weekgroup.mean().mean()

    with plt.xkcd():
        ax = weekgroup.sum()[-5:].plot.bar(rot=0, color="green", alpha=0.8)
        ax.hlines(wmean, -10, 100, linestyles="dashed")
        ax.set_xlabel("Weeks")
        ax.set_title("Last 5 weeks")
        # plt.savefig(os.path.join(static_path,"week.png"))
        fig = plt.gcf()
        weekly_spend = get_base64_string(fig)
        datadict["weekly_spend"] = weekly_spend
        plt.close()

    thismonth = data[data.index.month == this_month]
    thismonth = thismonth.sort_index()

    with plt.xkcd():
        thismonth.AMOUNT.cumsum().plot(alpha=0.9, rot=0)
        ax.set_title("Trend for this month")
        # plt.savefig(os.path.join(static_path,"days.png"))
        fig = plt.gcf()
        month_trend = get_base64_string(fig)
        datadict["month_trend"] = month_trend
        plt.close()

    lastday = data.index.dayofyear.max()
    tenthday = lastday-30

    last10days = data[data.index.dayofyear >= tenthday]
    last10group = last10days.groupby(last10days.index.dayofyear)
    lmean = last10group.mean().mean()

    with plt.xkcd():
        ax = last10group.sum().plot.bar(rot=0, color="yellow", alpha=0.8)
        ax.hlines(lmean, -10, 500, linestyles="dashed")
        ax.set_title("Last 30 days")
        # plt.savefig(os.path.join(static_path,"last10days.png"))
        fig = plt.gcf()
        last10days_in = get_base64_string(fig)
        datadict["last10days_in"] = last10days_in
        plt.close()

    total_this_year = round(data.AMOUNT.sum(), 2)
    total_this_month = round(thismonth.AMOUNT.sum(), 2)
    no_purchases_this_month = thismonth.AMOUNT.count()
    no_purchases_this_year = data.AMOUNT.count()

    with plt.xkcd():
        ax = thismonth.groupby(thismonth.WHERE).sum().sort_values(
            by="AMOUNT")[-5:].plot.bar(color="pink", alpha=0.9, rot=0)
        ax.set_title("Top 5 this month")
        # plt.savefig(os.path.join(static_path,"top5thismonth.png"))
        fig = plt.gcf()
        top5thismonth = get_base64_string(fig)
        datadict["top5thismonth"] = top5thismonth
        plt.close()

    with plt.xkcd():
        ax = data.groupby(data.WHERE).sum().sort_values(
            by="AMOUNT")[-10:].plot.bar(color="purple", alpha=0.8, rot=0)
        ax.set_title("Top of the year")
        plt.xticks(fontsize=10)
        # plt.savefig(os.path.join(static_path,"top10thisyear.png"))
        fig = plt.gcf()
        top10year = get_base64_string(fig)
        datadict["top10year"] = top10year
        plt.close()

    with plt.xkcd():
        plt.text(0.1, 0.9, "Total this year:")
        plt.text(0.1, 0.5, str(total_this_year), fontsize=100)
        plt.axis("off")
        # plt.savefig(os.path.join(static_path,"total_this_year.png"))
        fig = plt.gcf()
        total_year = get_base64_string(fig)
        datadict["total_year"] = total_year
        plt.close()

    with plt.xkcd():
        plt.text(0.1, 0.9, "This Month:")
        plt.text(0.1, 0.5, str(total_this_month), fontsize=100)
        plt.axis("off")
        # plt.savefig(os.path.join(static_path,"total_this_month.png"))
        fig = plt.gcf()
        total_month = get_base64_string(fig)
        datadict["total_month"] = total_month
        plt.close()

    with plt.xkcd():
        plt.text(0.1, 0.9, "Total spends:")
        plt.text(0.1, 0.5, str(no_purchases_this_year), fontsize=100)
        plt.axis("off")
        # plt.savefig(os.path.join(static_path,"no_purchases_this_year.png"))
        fig = plt.gcf()
        no_of_purchase = get_base64_string(fig)
        datadict["no_of_purchase"] = no_of_purchase
        plt.close()

    with plt.xkcd():
        plt.text(0.1, 0.9, "This month no of spends:")
        plt.text(0.1, 0.5, str(no_purchases_this_month), fontsize=100)
        plt.axis("off")
        # plt.savefig(os.path.join(static_path,"no_purchases_this_month.png"))
        fig = plt.gcf()
        no_of_purchase_this_month = get_base64_string(fig)
        datadict["no_of_purchase_this_month"] = no_of_purchase_this_month
        plt.close()

    return datadict

    # with plt.xkcd():
    #     plt.text(0.1, 0.9, "Total this year:")
    #     plt.text(0.1, 0.5, str(total_this_year), fontsize=100)
    #     plt.axis("off");
    #     fig = plt.gcf()
    #     buff = io.BytesIO()
    #     fig.savefig(buff, format="png")
    #     buff.seek(0)
    #     string=base64.b64encode(buff.read())
    #     total_this_year_s = urllib.parse.quote(string)
    #     plt.close()


import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

import numpy as np
from matplotlib import rc
rc('text', usetex=True)

# Draw surface
us = np.linspace(0, 1, 64)
vs = np.linspace(0, 1, 64)

xs = np.outer(us, np.ones_like(vs))*2-1
ys = np.outer(np.ones_like(us), vs)*2-1
zs = xs*xs + ys*ys

# Draw tangent plane
up = np.linspace(0, 1, 64)
vp = np.linspace(0, 1, 64)

xp = np.outer(up, np.ones_like(vp))*2-1
yp = np.outer(np.ones_like(up), vp)*2-1
zp = np.outer(np.zeros_like(up), np.zeros_like(vp))

# Draw intersection plane
ui = np.linspace(0, 1, 64)
vi = np.linspace(0, 1, 64)

xi = np.outer(ui, np.ones_like(vi))*2-1
zi = np.outer(np.ones_like(ui), vi)*2-1
yi = np.outer(np.zeros_like(ui), np.zeros_like(vi))

# Normals
origin = (0,0,0)
n_tangent = (0,0,-1)
n_plane = (0,1,0)

n_line = np.cross(n_tangent, n_plane)

# Intersection close line
ts = np.linspace(-1, 1, 5)
xl = origin[0] + ts * n_line[0]
yl = origin[1] + ts * n_line[1]
zl = origin[2] + ts * n_line[2]

# Intersection
tc = np.linspace(0, 1, 100)
xc = 2*tc-1
yc = np.zeros_like(tc)
zc = xc*xc

# Plot
fig = plt.figure(figsize=(10, 5))

# Sub 1
ax = fig.add_subplot(121, projection='3d')
ax.set_box_aspect(aspect = (1,1,np.sqrt(2)))
ax.axis("off")

ax.plot_wireframe(xs, ys, zs, rstride=16, cstride=16, linewidth=0.8, color = "tab:blue")
ax.plot_wireframe(xp, yp, zp, rstride=16, cstride=16, linewidth=0.8, color = "tab:orange")
ax.quiver(*origin, *n_tangent, color = "tab:orange", lw=2)

ax.plot_wireframe(xi, yi, zi, rstride=16, cstride=16, linewidth=0.8, color = "tab:green")
ax.quiver(*origin, *n_plane, color="tab:green", lw=2)

ax.plot(xl, yl, zl, "black")

ax.plot(xc, yc, zc, "--", color = "black")
ax.plot(*origin, 'ro')

ax.view_init(30, 215, 180)

# Sub 3
ax = fig.add_subplot(122, projection='3d')
ax.set_box_aspect(aspect = (1,1,np.sqrt(2)))
ax.axis("off")

ax.plot_wireframe(xs, ys, zs, rstride=16, cstride=16, linewidth=0.8, color = "tab:blue")
ax.plot_wireframe(xp, yp, zp, rstride=16, cstride=16, linewidth=0.8, color = "tab:orange")
ax.quiver(*origin, *n_tangent, color = "tab:orange", lw=2)

ax.plot_wireframe(xi, yi, zi, rstride=16, cstride=16, linewidth=0.8, color = "tab:green")
ax.quiver(*origin, *n_plane, color="tab:green", lw=2)

ax.plot(xl, yl, zl, "black")

ax.plot(xc, yc, zc, "--", color = "black")
ax.plot(*origin, 'ro')

ax.view_init(30, 145, 180)

plt.tight_layout()

filenames = ["surfacePlaneIntersection2_whole.png"]
plt.savefig(filenames[0], bbox_inches='tight', dpi = 500)

from PIL import Image

outnames = ["surfacePlaneIntersection2_cropped.png"]

for i in range(len(filenames)):
	with Image.open(filenames[i]) as inp:
		arr = np.array(inp)[200:-150,400:-400]
		out = Image.fromarray(arr)
		out.save(outnames[i])

"""
for a in range(360):
	ax.view_init(30, a, 180)
	plt.draw()
	plt.pause(.001)
"""


from collections import Counter

class Solution:
    def uniqueOccurrences(self, arr: List[int]) -> bool:
        c = Counter(arr)
        l = list(c.values())
        c2 = Counter(l)
        for i in c2.values():
            if i > 1:
                return False
        return True


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

"""Test contents of :mod:`~utilipy.utils.misc`."""

__all__ = [
    "test_temporary_namespace",
    "test_make_help_function_raises",
]

##############################################################################
# IMPORTS

# BUILT-IN
import types

# THIRD PARTY
import pytest

# PROJECT-SPECIFIC
from utilipy.utils import misc

##############################################################################
# PARAMETERS

_doc_ = __doc__

_doc = """Docstring

Returns
-------
Nothing.

"""

##############################################################################
# CODE
##############################################################################

def test_temporary_namespace():  # TODO FIX
    """Test :func:`~utilipy.utils.misc.temporary_namespace`."""
    x = 1
    y = 2

    with misc.temporary_namespace(locals(), keep=["a"]):
        locals()["a"] = 3  # TODO FIX
        locals()["b"] = 4

    assert x, y == (1, 2)
    assert locals()["a"] == 3

    with pytest.raises(AssertionError):
        assert "b" in locals()

# /def

# -------------------------------------------------------------------

def test_make_help_function_raises():
    """Test :func:`~utilipy.utils.misc.make_help_function` Exceptions."""
    with pytest.raises(TypeError):
        misc.make_help_function("test", look_for=Exception)

# /def

def test_make_help_function_find_module():
    """Test :func:`~utilipy.utils.misc.make_help_function` Exceptions."""
    help_function = misc.make_help_function("test", module=None)

    assert help_function.__name__ == "test_help"
    assert help_function.__module__ == "utilipy.utils.tests.test_misc"
    assert help_function.__doc__ == "Help for test.\n\n" + _doc_

# /def

def test_make_help_function_pass_module():
    """Test :func:`~utilipy.utils.misc.make_help_function` Exceptions."""
    module = types.ModuleType("null_module", doc=_doc)

    help_function = misc.make_help_function("test", module=module)

    assert help_function.__name__ == "test_help"
    assert help_function.__module__ == "null_module"
    assert help_function.__doc__ == "Help for test.\n\n" + _doc

# /def

##############################################################################
# END


from django.db import models
from accounts.models import Section, Department
from pm_pdm.models import PM_PdM

class Category(models.Model):
    """Model representing a Category of equipment"""
    name = models.CharField(max_length=50, null=True, help_text='Enter name of Category(eg. Motor, Compressor...)')
    description = models.CharField(max_length=200, null=True, help_text='Enter description of Category')

    # Foreign Key used because Category can only have one section, but section can have multiple Categorys
    # Category as a string rather than object because it hasn't been declared yet in the file
    section = models.ForeignKey(Section, on_delete=models.SET_NULL, null=True)

    class Meta:
        ordering = ['section','name']

    def __str__(self):
        """String for representing the Model object."""
        return self.name

    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_dict(cls,dtDict):

        #get sect object
        sectName = dtDict.get('foreign_section')
        sect = Section.objects.get(name = sectName)

        #remove key foreign_section
        dtDict.pop('foreign_section')

        #insert Section
        dtDict['section']=sect

        #get first key for unique key
        k=None
        for k,v in dtDict.items():
            if k:
                break

        #name as unique value, kindly modify as needed
        return cls.objects.update_or_create(
            name=v,
            defaults=dtDict,
        )

class Risk(models.Model):
    """Model representing a Risk of RBM"""
    name = models.CharField(max_length=50, null=True, help_text='Enter name of Risk(eg. safety, enviromental)')
    description = models.CharField(max_length=200, null=True, help_text='Enter description of Risk')
    value = models.IntegerField(null=True)#value 1 - 5

    class Meta:
        ordering = ['name',]

    def __str__(self):
        """String for representing the Model object."""
        return self.name

    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_dict(cls,dtDict):

        #get first key for unique key
        k=None
        for k,v in dtDict.items():
            if k:
                break

        #name as unique value, kindly modify as needed
        return cls.objects.update_or_create(
            name=v,
            defaults=dtDict,
        )

class Unit(models.Model):
    """Model representing a Unit of Plant"""
    name = models.CharField(max_length=50, null=True, help_text='Enter name of Unit(eg. Boiler, Membrane, Cooling Tower)')
    description = models.CharField(max_length=200, null=True, help_text='Enter description of Unit')
    # Foreign Key used because Unit can only have one area, but area can have multiple Units
    # Unit as a string rather than object because it hasn't been declared yet in the file
    area = models.ForeignKey('Area', on_delete=models.SET_NULL, null=True)
    class Meta:
        ordering = ['area','name']

    def __str__(self):
        """String for representing the Model object."""
        return self.name

    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_dict(cls,dtDict):

        #get area object
        areaName = dtDict.get('foreign_area')
        areaObj = Section.objects.get(name = areaName)

        #remove key foreign_area
        dtDict.pop('foreign_area')

        #insert Area
        dtDict['area']=areaObj

        #get first key for unique key
        k=None
        for k,v in dtDict.items():
            if k:
                break

        #name as unique value, kindly modify as needed
        return cls.objects.update_or_create(
            name=v,
            defaults=dtDict,
        )

class Area(models.Model):
    """Model representing a Area of Plant"""
    name = models.CharField(max_length=50, null=True, help_text='Enter name of Area(eg. Utility, Area 100, CO2)')
    description = models.CharField(max_length=200, null=True, help_text='Enter description of Area')
    # Foreign Key used because Area can only have one department, but department can have multiple Areas
    # Department as a string rather than object because it hasn't been declared yet in the file
    department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True)
    class Meta:
        ordering = ['department','name']

    def __str__(self):
        """String for representing the Model object."""
        return self.name

    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_dict(cls,dtDict):

        #get department object
        departmentName = dtDict.get('foreign_department')
        departmentObj = Section.objects.get(name = departmentName)

        #remove key foreign_department
        dtDict.pop('foreign_department')

        #insert department
        dtDict['department']=departmentObj

        #get first key for unique key
        k=None
        for k,v in dtDict.items():
            if k:
                break

        #name as unique value, kindly modify as needed
        return cls.objects.update_or_create(
            name=v,
            defaults=dtDict,
        )

class Equipment(models.Model):
    """Model representing a Equipment of Plant"""
    name = models.CharField(max_length=50, null=True, help_text='Enter name of Equipment(eg. TI-4102, C-018, P-021)')
    description = models.CharField(max_length=200, null=True, help_text='Enter description of Equipment')
    location = models.CharField(max_length=100, null=True, help_text='Enter location of Equipment')

    # Foreign Key used because Equipment can only have one category, but category can have multiple Equipments
    # category as a string rather than object because it hasn't been declared yet in the file
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)

    # Foreign Key used because Equipment can only have one unit, but unit can have multiple Equipments
    # unit as a string rather than object because it hasn't been declared yet in the file
    unit = models.ForeignKey(Unit, on_delete=models.SET_NULL, null=True)

    #RBM data - Risk Based Maintenance
    rbmValue = models.IntegerField(null=True)#value 1 - 125
    rbmGrade = models.CharField(max_length=50, null=True, help_text='Enter grade of Risk(eg. Critical, Normal, Less)')

    # ManyToManyField used because Equipment can contain many risks. risk can cover many equipments.
    # Action class has already been defined so we can specify the object above.
    risks = models.ManyToManyField(Risk, help_text='Select risks')

    # ManyToManyField used because tbm can contain many PM_PdM. PM_PdM can cover many tbm.
    # PM_PdM class has already been defined so we can specify the object above.
    tbm = models.ManyToManyField(PM_PdM, help_text='Select PM_PdM')

    class Meta:
        ordering = ['unit','name']

    def __str__(self):
        """String for representing the Model object."""
        return self.name

    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_dict(cls,dtDict):

        #get category object - it is for one to many ORM
        categoryName = dtDict.get('foreign_category')
        categoryObj = Category.objects.get(name = categoryName)

        #remove key foreign_category
        dtDict.pop('foreign_category')

        #insert category
        dtDict['category']=categoryObj

        #get unit object - it is for one to many ORM
        unitName = dtDict.get('foreign_unit')
        unitObj = Unit.objects.get(name = unitName)

        #remove key foreign_unit
        dtDict.pop('foreign_unit')

        #insert unit
        dtDict['unit']=unitObj

        #get first key for unique key
        k=None
        for k,v in dtDict.items():
            if k:
                break

        #name as unique value, kindly modify as needed
        return cls.objects.update_or_create(
            name=v,
            defaults=dtDict,
        )

    #Many to many relationship
    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_risks_dict(cls,dtDict):

        #get Equipment
        eqp = None
        if dtDict.get('name'):
            eqp = Equipment.objects.get(name = dtDict.get('name'))

        #get risk
        rsk = None
        if dtDict.get('risk'):
            rsk = Risk.objects.get(name=dtDict.get('risk'))

        #add rsk to Equipment
        eqp.risks.add(rsk)
        eqp.save()

    #Many to many relationship
    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_tbm_dict(cls,dtDict):

        #get Equipment
        eqp = None
        if dtDict.get('name'):
            eqp = Equipment.objects.get(name = dtDict.get('name'))

        #get tbm - PmPdM
        pm_pdm = None
        if dtDict.get('risk'):
            pm_pdm = Risk.objects.get(name=dtDict.get('risk'))

        #add pm_pdm to Equipment
        eqp.tbm.add(pm_pdm)
        eqp.save()

class TBM_Package(models.Model):
    """Model representing a TBM - Time Based Maintenance"""
    name = models.CharField(max_length=50, null=True, help_text='Enter name of TBM(eg. PM Critical)')
    description = models.CharField(max_length=200, null=True, help_text='Enter description of TBM')
    periode = models.IntegerField(null=True, help_text='Enter periode of TBM (week)')#value 1 - 51

    # ManyToManyField used because eqpPackage can contain many Equipment. Equipment can cover many eqpPackages.
    # Equipment class has already been defined so we can specify the object above.
    eqpPackage = models.ManyToManyField(Equipment, help_text='Select TBM')

    class Meta:
        ordering = ['periode','name']

    def __str__(self):
        """String for representing the Model object."""
        return self.name

    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_dict(cls,dtDict):

        #get first key for unique key
        k=None
        for k,v in dtDict.items():
            if k:
                break

        #name as unique value, kindly modify as needed
        return cls.objects.update_or_create(
            name=v,
            defaults=dtDict,
        )

    #Many to many relationship
    #this decorator make posible to call method w/o instantiate class
    @classmethod
    #use cls instead of self
    def update_or_create_package_dict(cls,dtDict):

        #get TBM_Package
        pkg = None
        if dtDict.get('name'):
            pkg = TBM_Package.objects.get(name = dtDict.get('name'))

        #get Equioment
        eqp = None
        if dtDict.get('eqp'):
            eqp = Equipment.objects.get(name=dtDict.get('eqp'))

        #add eqp to TBM_Package
        pkg.risks.add(eqp)
        pkg.save()


import torch
import torch.nn.functional as F

class clsification_topk_decoder:
    def __init__(self, topk=3):
        self.topk = topk
        return

    def __call__(self, net_predict):
        sofmatmax_prob = F.softmax(net_predict['cls_pred'], dim=-1)
        topk_vals, topk_indices = torch.topk(sofmatmax_prob, k=self.topk)
        # topk_vals: n x k
        # topk_indices: n x k
        out_dict = {
            'pred_probs': topk_vals,
            'topk_indices': topk_indices
        }

        return out_dict


#!/usr/bin/python3
import os
from re import search
from sys import argv

from Dirr import Dirr
from utils import roundsSize
from styling import S, T, Bg, stylizesStr

TAB = ' ' * 4
fullDataFolders = list()

FILE, FOLDER = "file", "folder"
def printsTree(name, type, idtPrev, pathPos, amtPrevDirrPaths, size=None):
	idt = idtPrev
	dots = stylizesStr(":", T.red, s1=S.strong)
	if pathPos == amtPrevDirrPaths:
		idt = "{}{}{}".format(idt, TAB, " ")
	else:
		idt = "{}{}{}".format(idt, TAB, dots)

	arrowIdt = "{}{}".format(idtPrev, TAB)

	if type == FOLDER:
		if name[0] != '/':
			name = "/{}".format(name)
		name = stylizesStr(name, T.purple, s1=S.strong, s2=S.italic)

		arrow = "`--> "
		arrow = stylizesStr(arrow, T.red, s1=S.strong)
		print("{}{}{}".format(arrowIdt, arrow, name))
	elif type == FILE:
		name = stylizesStr(name, T.purple)
		size = roundsSize(size)
		size = stylizesStr(size, T.cyan, s1=S.strong)

		arrow = "`-> "
		arrow = stylizesStr(arrow, T.red, s1=S.strong)
		text = stylizesStr(" has usage ", s1=S.blur, s2=S.italic)

		print("{}{}{}{}{}".format(arrowIdt, arrow, name, text, size))

		if amtPrevDirrPaths == pathPos: print(arrowIdt)

	return idt

def analyzesIgnoredDirr(entry, name, nv, amtIgnr, ignrSize):
	newAmtIgnr, newIgnrS = 0, 0
	if os.path.isdir(entry):
		newAmtIgnr, newIgnrS, _, _, _, _ = analyzesMem(entry.path, nv+1)
	elif os.path.isfile(entry):
		newIgnrS = os.path.getsize(entry)

	if name[0] == '.':
		newAmtIgnr += 1

	return amtIgnr + newAmtIgnr, ignrSize + newIgnrS

def analyzesMem(path, nv, amtPrevDirrPaths=1, idtPrev=" ", pathPos=1):
	ignore = r"/\."
	folderName = os.path.basename(path)
	isIgnr = search(ignore, path)

	amtIgnr, amtFolders, amtFiles = 0, 0, 0
	for entry in os.scandir(path):
		name = os.path.basename(entry)

		if search(ignore, entry.path):
			continue

		if os.path.isdir(entry):
			amtFolders += 1
		elif os.path.isfile(entry):
			amtFiles += 1
	amtPrevDirrPaths = amtFolders + amtFiles

	amtSubFolders, amtSubFiles = 0, 0
	ignrSize, notIgnrSize = 0, 0
	for entry in os.scandir(path):
		name = os.path.basename(entry)

		if search(ignore, entry.path):
			amtIgnr, ignrSize = analyzesIgnoredDirr(entry, name, nv, amtIgnr, ignrSize)
			continue

		if os.path.isdir(entry):
			idt = printsTree(name, FOLDER, idtPrev, pathPos, amtPrevDirrPaths)
			# analyzesSubFolder()
			amtIgnrF, ignrS, amtSubFo, amtSubFi, notIgnrS, _ = analyzesMem(entry.path, nv+1, amtPrevDirrPaths, idt)
			amtIgnr += amtIgnrF

			amtSubFolders += amtSubFo
			amtSubFiles += amtSubFi

			ignrSize += ignrS
			notIgnrSize += notIgnrS

		elif os.path.isfile(entry):
			size = os.path.getsize(entry)
			notIgnrSize += size

			printsTree(name, FILE, idtPrev, pathPos, amtPrevDirrPaths, size)

		pathPos += 1

	if not isIgnr:
		folderData = Dirr(nv, folderName, amtIgnr, ignrSize, amtFolders, amtSubFolders, amtSubFiles, amtFiles, notIgnrSize)
		fullDataFolders.append(folderData)

	return amtIgnr, ignrSize, amtSubFolders + amtFolders, amtSubFiles + amtFiles, notIgnrSize, amtFolders

def getsInputPath(path):
	workingPath = os.getcwd()
	dirr = "{}/{}".format(workingPath, path)

	if not os.path.exists(dirr):
		print("Bad inpuT. Try again with path to a existing directory.")
		exit()
	elif not os.path.isdir(dirr):
		print("Bad inpuT. Try again with path to a directory.")
		exit()

	os.chdir(path)
	dirr = os.getcwd()

	return dirr

def validatesInput():
	if len(argv) > 2:
		print("Bad inpuT. Try again with:")
		print(" \"./diskanalyzesMem <path>\" or only \"./diskanalyzesMem\" for analize current directory.")
		exit()

	dirr = "/home"
	if len(argv) == 2:
		dirr = getsInputPath(argv[1])

	return dirr

def printHeaderTree(directory, terminalWidth):
	name = "/{}".format(os.path.basename(directory))
	name = stylizesStr(name, T.purple, s1=S.strong, s2=S.italic)

	edge = ' - ' * (terminalWidth // 6 - 1)
	title = "{}|TREE|{}".format(edge[1:], edge[:-1])
	title = stylizesStr(title, T.cyan)

	arrow = "`--> "
	arrow = stylizesStr(arrow, T.red, s1=S.strong)
	print("\n{}".format(title))
	print("{}{}".format(arrow, name))

def printsDataTree(terminalWidth):
	edge = ' - ' * (terminalWidth // 6 - 1)
	title = "{}|DATA TREE|{}".format(edge[4:], edge[:-1])
	title = stylizesStr(title, T.cyan, s1=S.strong)

	print("\n\n{}".format(title))
	for folder in fullDataFolders[::-1]: print(folder, end="")

def main():
	directory = validatesInput()
	terminalWidth = int(os.popen('stty size', 'r').read().split()[1])

	printHeaderTree(directory, terminalWidth)
	analyzesMem(directory, 1)
	printsDataTree(terminalWidth)

if __name__ == "__main__":
	main()


"""HotelIFBA URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,include
from rest_framework import routers
from HotelariaIFBA.api import viewsets
from django.conf.urls.static import static
from django.conf import settings
from rest_framework_simplejwt.views import (TokenObtainPairView,TokenRefreshView,)

# Empresa, ListaDeServico, TipoServico,Empregados,
# Cliente,Reserva,Alojamento,ServicosUtilizados
router = routers.DefaultRouter()
router.register(r'empresa', viewsets.EmpresaViewSet)
router.register(r'listadeservico', viewsets.ListaDeServicoViewSet)
router.register(r'tiposervico', viewsets.TipoServicoViewSet)
router.register(r'empregados', viewsets.EmpregadosViewSet)
router.register(r'cliente', viewsets.ClienteViewSet)
router.register(r'reserva', viewsets.ReservaViewSet)
router.register(r'alojamento', viewsets.AlojamentoViewSet)
router.register(r'servicosutilizados', viewsets.ServicosUtilizadosViewSet)
router.register(r'users', viewsets.UserViewSet)
urlpatterns = [
    path('', include(router.urls)),
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


import backtrader as bt

class MaCrossStrategy(bt.Strategy):

    params = (("fast_length", 10), ("slow_length", 50))

    def __init__(self):
        ma_fast = bt.ind.SMA(period=self.params.fast_length)
        ma_slow = bt.ind.SMA(period=self.params.slow_length)

        self.crossover = bt.ind.CrossOver(ma_fast, ma_slow)

    def next(self):
        if not self.position:
            if self.crossover > 0:
                self.buy()
        elif self.crossover < 0:
            self.close()


import itertools
from math import factorial as fac

# n! permutations of hats
# but how many are "all wrong"?

# What is the probability that the result will be all wrong?

# if hat(i) == i, it's not "all wrong" -- throw these away (this hat(i) == i property is sometimes called "fixed")

# find all permutations where hat(0) == 0. (n-1)! of those
# then find all hat(1) == 1. (n-1)! of those
# but... some permutations of each overlap. [ where hat(0) == 0 AND hat(1) == 1 ]
# -- so we have to add those back
# -- leads to the +, -, +, -, ... pattern
# -- n! - (n-1)! + (n-2)! - (n-3)! + ... ???
# let's try it!

def formula(n):
    # GOAL:
    # 1 = 0
    # 2 = 1
    # 3 = 2
    # 4 = 9
    # 5 = 44
    # 6 = 265
    # 7 = 1854
    # 8 = 14833
    # 9 = 133496
    return formula(n-1) * n + (-1)**n if n > 1 else 0

def count_all_wrong(n):
    count = 0
    for p in itertools.permutations(range(n)):
        for i in range(n):
            if p[i] == i:
                break
        else:
            #print(p)
            count += 1
    return count

def main():
    for n in range(1, 10):
        all_wrong = count_all_wrong(n)
        f = formula(n)
        assert all_wrong == f
        prob = all_wrong / fac(n)
        print(f'{n} = {all_wrong} (formula says {f}) -- probability is {prob}')

if __name__ == '__main__':
    main()

# "all wrong" is commonly known as a derangement. Or a subfactorial. Typically written !n instead of n!.
# !N = N! * [1 − 1/!1 + 1/2! - 1/3! + 1/4! - ... + 1/N!]


from functools import partial

from PyQt5 import QtWidgets
from PyQt5 import QtCore

from config import APP_MODE, AppMode
from database.db_obj import DB
from database.data_model import PlanListRow, PlanData, PlanPdfData
from gui.editors import PlanAreaViewer
from gui.widgets import (
    ScrollArea, PlanListView, TitleLabel, HBoxPane, ImageButton,
    DBTitleLabel,
)
from gui.dialogs import ErrorMessage, QuestionDialog, InfoMessage
from gui.font import Font, FontFlag
from gui.colors import Colors
from gui.util import set_value, get_value
from gui.flags import ImageFp, AlignFlag, PermissionType, SizePolicy

db = DB()

class _PlanViewerToolbar(QtWidgets.QWidget):
    def __init__(self, parent):
        super().__init__(parent)
        # style_sheet = """
        #     border: 0;
        # """
        # self.setStyleSheet(style_sheet)
        # self.setFixedHeight(50)
        self.hbox_layout = None
        self.bttn_load = None
        self.bttn_export = None
        self.bttn_create_pdf = None
        self.bttn_delete = None
        # ----- Init UI -----
        self.init_ui()
        # ----- Connect events to slots -----
        # self.bttn_load.clicked.connect(self._load_plan_to_planner)

    def init_ui(self):
        self.bttn_load = ImageButton(self, 'bttn_load', ImageFp.LOAD, 'Load plan to Planner')
        self.bttn_export = ImageButton(self, 'bttn_export', ImageFp.EXPORT, 'Export plan to motfile')
        self.bttn_create_pdf = ImageButton(self, 'bttn_create_pdf', ImageFp.PLAN_PDF, 'Create plan pdf')
        self.bttn_delete = ImageButton(self, 'bttn_delete', ImageFp.DELETE, 'Delete plan')
        self.hbox_layout = QtWidgets.QHBoxLayout(self)
        self.hbox_layout.setContentsMargins(0, 0, 0, 0)
        self.hbox_layout.addWidget(self.bttn_load)
        self.hbox_layout.addWidget(self.bttn_export)
        self.hbox_layout.addWidget(self.bttn_create_pdf)
        self.hbox_layout.addWidget(self.bttn_delete)
        self.hbox_layout.setAlignment(AlignFlag.Left)
        self.setLayout(self.hbox_layout)

class _PlanViewerTopRow(QtWidgets.QFrame):
    def __init__(self, parent):
        super().__init__(parent)
        # GUI children
        self.hbox_layout = None
        self.toolbar = None
        self.title = None
        self.label_plan_type = None
        self.cb_plan_type = None
        # Initialize UI
        self._init_ui()

    def _init_ui(self):
        self.toolbar = _PlanViewerToolbar(self)
        self.title = TitleLabel(
            self, 'plan_name', '-', font_flag=FontFlag.TITLE_BOLD,
            bg_color=Colors.PLAN_TITLE.hex,
            size_policy=(SizePolicy.MAXIMUM, SizePolicy.MAXIMUM))
        _id_name_dict = dict(DB().select_from_table('plan_type', ('id', 'name')))
        self.label_plan_type = DBTitleLabel(
            self, 'plan_type', _id_name_dict, font_flag=FontFlag.NORMAL_TEXT_BOLD,
            bg_color=Colors.PLAN_TYPE.hex, text_color='black',
            size_policy=(SizePolicy.MAXIMUM, SizePolicy.MAXIMUM))
        self.label_plan_type.setToolTip('Plan type')
        self.hbox_layout = QtWidgets.QHBoxLayout(self)
        self.hbox_layout.setContentsMargins(0, 0, 0, 0)
        self.hbox_layout.addWidget(self.toolbar)
        self.hbox_layout.addStretch(10)
        self.hbox_layout.addWidget(self.title)
        self.hbox_layout.addStretch(10)
        self.hbox_layout.addWidget(self.label_plan_type)
        self.hbox_layout.addStretch(1)
        self.hbox_layout.setAlignment(self.title, AlignFlag.Center)
        self.hbox_layout.setAlignment(self.title, AlignFlag.Right)
        self.setLayout(self.hbox_layout)

class PlanViewer(QtWidgets.QWidget):
    signal_create_plan_pdf = QtCore.pyqtSignal(QtWidgets.QWidget, PlanPdfData)
    signal_export_plan = QtCore.pyqtSignal(PlanData)

    def __init__(self, parent):
        super().__init__(parent)
        self.setObjectName('plan_viewer')
        # Data
        self.loaded_plan_id = None
        # ----- GUI children -----
        self.vbox_layout = None
        self.top_row = None
        self.plan_area_viewer = None
        # ----- Init UI -----
        self._init_ui()
        # ----- Connect events to slots -----
        self.top_row.toolbar.bttn_export.clicked.connect(self._export_to_json_file)
        self.top_row.toolbar.bttn_create_pdf.clicked.connect(self._create_plan_pdf)

    def _init_ui(self):
        self.vbox_layout = QtWidgets.QVBoxLayout(self)
        self.vbox_layout.setContentsMargins(0, 0, 0, 0)
        self.top_row = _PlanViewerTopRow(self)
        self.plan_area_viewer = PlanAreaViewer(self)
        self.scroll_area = ScrollArea(self)
        self.scroll_area.setWidget(self.plan_area_viewer)
        # ----- Set Layout -----
        self.vbox_layout.addWidget(self.top_row)
        self.vbox_layout.addWidget(self.scroll_area)
        self.setLayout(self.vbox_layout)

    def set_plan(self, plan_row=None):
        if plan_row:
            self.loaded_plan_id = plan_row.plan_id
            set_value(self.top_row.title, plan_row.name)
            set_value(self.top_row.label_plan_type, plan_row.plan_type)
            workouts_data = db.select_plan_workouts_data(plan_row.plan_id)
            self.plan_area_viewer.set_plan_workouts(workouts_data)
            bttn_delete_enabled = True if plan_row.user_permission else False
            self.top_row.toolbar.bttn_delete.setEnabled(bttn_delete_enabled)
        else:
            self.loaded_plan_id = None
            set_value(self.top_row.title, '-')
            set_value(self.top_row.label_plan_type, '-')
            self.plan_area_viewer.set_plan_workouts([None] * 7)
            self.top_row.toolbar.bttn_delete.setEnabled(False)

    def _export_to_json_file(self):
        plan_data = self._get_plan_data()
        self.signal_export_plan.emit(self, plan_data)

    def _create_plan_pdf(self):
        plan_pdf_data = self._get_plan_pdf_data()
        self.signal_create_plan_pdf.emit(self, plan_pdf_data)

    def _get_plan_data(self):
        plan_name = get_value(self.top_row.title)
        plan_type_id = self.top_row.label_plan_type.get_item_db_id()
        workouts_data = self.plan_area_viewer.get_workouts_data()
        return PlanData(self.loaded_plan_id, plan_name, plan_type_id, workouts_data)

    def _get_plan_pdf_data(self):
        plan_name = get_value(self.top_row.title)
        plan_type = get_value(self.top_row.label_plan_type)
        workouts_pdf_data = self.plan_area_viewer.get_workouts_pdf_data()
        links = self.plan_area_viewer.get_all_links()
        return PlanPdfData(plan_name, plan_type, workouts_pdf_data, links)

class PlanListViewer(QtWidgets.QFrame):
    def __init__(self, parent, title, perm_type):
        super().__init__(parent)
        self.setFixedHeight(350)
        # GUI children
        self.vbox_layout = None
        self.title = None
        self.plan_list = None
        # Initilize GUI
        self.init_ui(title, perm_type)

    def init_ui(self, title, perm_type):
        self.title = TitleLabel(self, 'title', title,
                                font_flag=FontFlag.BIG_TEXT_BOLD, round_bottom=False)
        self.plan_list = PlanListView(self, perm_type=perm_type)
        self.vbox_layout = QtWidgets.QVBoxLayout(self)
        self.vbox_layout.setSpacing(0)
        self.vbox_layout.addWidget(self.title)
        self.vbox_layout.addWidget(self.plan_list)
        self.vbox_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.vbox_layout)

    def refresh_from_db(self):
        indexes = self.plan_list.selectedIndexes()
        sel_row = indexes[0].row() if indexes else None
        self.plan_list.set_model_from_db()
        if sel_row is not None:
            self.plan_list.select_index(sel_row)

    def _get_plan_pdf_data(self):
        pass

class TabPlans(QtWidgets.QFrame):
    signal_load_plan = QtCore.pyqtSignal(PlanListRow)
    signal_plan_deleted = QtCore.pyqtSignal(int)

    def __init__(self, parent, index):
        super().__init__(parent)
        self.index = index
        self.setObjectName('tab_plans')
        # ----- Data -----
        self.info_dialog = None  # For testing
        self.question_dialog = None  # For testing
        # ----- GUI chlderen -----
        self.vbox_layout = None
        self.system_plan_list_viewer = None
        self.user_plan_list_viewer = None
        self.plan_viewer = None
        # ----- Init UI -----
        self.init_ui()
        # ----- GUI chlderen -----
        # connect event to slots
        self.system_plan_list_viewer.plan_list.signal_select_next_plan.connect(self._select_next_plan)
        self.user_plan_list_viewer.plan_list.signal_select_next_plan.connect(self._select_next_plan)
        self.system_plan_list_viewer.plan_list.signal_plan_selected.connect(
            partial(self._set_plan_data, PermissionType.System))
        self.user_plan_list_viewer.plan_list.signal_plan_selected.connect(
            partial(self._set_plan_data, PermissionType.User))
        self.plan_viewer.top_row.toolbar.bttn_load.clicked.connect(self._bttn_load_clicked)
        self.plan_viewer.top_row.toolbar.bttn_delete.clicked.connect(self._bttn_delete_clicked)
        # Post actions
        self._select_next_plan()

    def init_ui(self):
        self.system_plan_list_viewer = PlanListViewer(self, 'System Plans', PermissionType.System)
        self.user_plan_list_viewer = PlanListViewer(self, 'User Plans', PermissionType.User)
        _row_plan_lists = HBoxPane(self, (self.system_plan_list_viewer, self.user_plan_list_viewer),
                                   cont_margins=(0, 0, 0, 0))
        self.plan_viewer = PlanViewer(self)
        # ----- Set Layout -----
        self.vbox_layout = QtWidgets.QVBoxLayout(self)
        self.vbox_layout.addWidget(self.plan_viewer)
        self.vbox_layout.addWidget(_row_plan_lists)
        self.vbox_layout.setAlignment(_row_plan_lists, AlignFlag.Top)
        self.setLayout(self.vbox_layout)

    def refresh_plans(self):
        self.system_plan_list_viewer.refresh_from_db()
        self.user_plan_list_viewer.refresh_from_db()

    def _select_next_plan(self):
        for plan_list in (self.user_plan_list_viewer.plan_list,
                          self.system_plan_list_viewer.plan_list):
            if plan_list.model().rowCount() > 0:
                plan_list.select_index(0)
                return
        # Not plan available, so plan table data is reset
        self.plan_viewer.set_plan()

    # ----- SLOTS -----

    def _bttn_load_clicked(self):
        system_plan_list = self.system_plan_list_viewer.plan_list
        user_plan_list = self.user_plan_list_viewer.plan_list
        plan_row = system_plan_list.get_selected_plan_row()
        if not plan_row:
            plan_row = user_plan_list.get_selected_plan_row()
        self.signal_load_plan.emit(plan_row)

    def _bttn_delete_clicked(self):
        loaded_plan_id = self.plan_viewer.loaded_plan_id
        if not loaded_plan_id:
            ErrorMessage('Delete plan failed', 'No plan is loaded').exec()
            return
        _plan_name = get_value(self.plan_viewer.top_row.title)
        _msg = f'Are you sure you want to delete plan "{_plan_name}"?'
        self.question_dialog = QuestionDialog('Delete plan', _msg)
        delete_plan = self.question_dialog.exec()
        if not delete_plan:
            return
        deleted = DB().delete_week_plan(loaded_plan_id)
        if not deleted:
            _msg = f'Error occured: Plan "{_plan_name}" couldn\'t be deleted.'
            ErrorMessage('Delete plan failed', _msg).exec()
            return
        self.plan_viewer.set_plan()
        if APP_MODE == AppMode.DEVELOPMENT_MODE:
            indexes = self.system_plan_list_viewer.plan_list.selectedIndexes()
            if indexes:
                plan_id = self.system_plan_list_viewer.get_selected_item_id()
                self.system_plan_list_viewer.model().removeRows(indexes[0].row(), 1)
                self.signal_plan_deleted.emit(plan_id)
                return
        indexes = self.user_plan_list_viewer.plan_list.selectedIndexes()
        if indexes:
            plan_id = self.user_plan_list_viewer.plan_list.get_selected_item_id()
            self.user_plan_list_viewer.plan_list.model().removeRows(indexes[0].row(), 1)
            self.signal_plan_deleted.emit(plan_id)
        self._select_next_plan()
        _msg = f'Plan "{_plan_name}" was deleted.'
        self.info_dialog = InfoMessage('Plan deleted', _msg)
        self.info_dialog.exec()
        self.info_dialog = None

    def _set_plan_data(self, perm_type, plan_row):
        self.plan_viewer.set_plan(plan_row)
        if perm_type == PermissionType.System:
            self.user_plan_list_viewer.plan_list.selectionModel().clearSelection()
        else:  # == PermissionType.User
            self.system_plan_list_viewer.plan_list.selectionModel().clearSelection()


import pandas as pd
import joblib
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import f1_score, make_scorer
from sklearn.model_selection import GridSearchCV

# Load the preprocessed data while skipping the header row
X_train = pd.read_csv('data/X_train.csv', header=None, skiprows=1)
y_train = pd.read_csv('data/y_train.csv', header=None, skiprows=1)

# Convert y_train to a NumPy array
y_train = np.array(y_train)

# Add the code to check the number of samples
print("Number of samples in X_train:", X_train.shape[0])
print("Number of samples in y_train:", y_train.shape[0])

print("X_train head:")
print(X_train.head())

print("\ny_train head:")
print(y_train[:5])  # Print the first 5 elements of y_train

# Initialize the classifier (you can choose a different one)
classifier = RandomForestClassifier(random_state=42)

# Define the parameter grid for hyperparameter tuning
param_grid = {
    'n_estimators': [100, 200, 300],
    'max_depth': [None, 10, 20, 30],
}

# Define custom scorer for F1 score
scorer = make_scorer(f1_score)

# Perform grid search with cross-validation to find the best parameters
grid_search = GridSearchCV(classifier, param_grid, scoring=scorer, cv=5, n_jobs=-1)
grid_search.fit(X_train, y_train.ravel())  # Use ravel() to flatten y_train

# Get the best model from the grid search
best_classifier = grid_search.best_estimator_

# Save the best model
joblib.dump(best_classifier, 'models/trained_model.pkl')


#%%
import math
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as sig
from scipy import interpolate
import pywt
from matplotlib.pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文的命令
mpl.rcParams['axes.unicode_minus'] = False  #  显示负号的命令
#经验模态函数EMD

#函数1：判定当前时间序列是否是单调序列
def mon(x):
    max_peaks=sig.argrelextrema(x,np.greater)[0]#极大值点横坐标，np.greater实现的是">"的功能
    min_peaks=sig.argrelextrema(x,np.less)[0]#极小值点横坐标
    num=len(max_peaks)+len(min_peaks)#极值点个数
    if num >0:#不是单调序列
        return False
    else:
        return  True
#函数2：寻找当前时间序列的极值点横坐标
def findpeaks(x):
    return sig.argrelextrema(x,np.greater)[0]
#函数3：判断是否为IMF序列
def  imfyn(x):
    N = np.size(x)
    pzero = np.sum(x[0:N-2] * x[1:N-1] < 0)#过零点个数
    psum = np.size(findpeaks(x)) + np.size(findpeaks(-x))#极值点个数
    if abs(pzero - psum) > 1:
        return False
    else:
        return True

#函数4：获取样条曲线
def getspline(x):
    N = np.size(x)
    peaks = findpeaks(x)
    peaks = np.concatenate(([0],peaks))
    peaks = np.concatenate((peaks,[N - 1]))
    if (len(peaks) <=3):
        t = interpolate.splrep(peaks,y=x[peaks] , w=None , xb=None , xe=None ,k=len(peaks) -1)
        return interpolate.splev(np.arange(N),t)
    t = interpolate.splrep(peaks, y=x[peaks])
    return interpolate.splev(np.arange(N),t)
#函数5：CBemd
def emd(x):
    imf= []
    while not mon(x):
        x1 = x
        sd = np.inf
        while sd >0.1 or (not imfyn(x1)):
            s1 = getspline(x1)
            s2 = -getspline(-1*x1)
            x2 = x1 - (s1 + s2)/2
            sd = np.sum((x1-x2)**2) / np.sum(x1 ** 2)
            x1 = x2
        imf.append(x1)
        x = x -x1
    imf.append(x)
    return imf
# 函数6：模拟噪声函数wgn
def wgn(x,snr):
    snr = 10**(snr/10.0)
    xpower = np.sum(x**2)/len(x)
    npower = xpower / snr
    return np.random.randn(len(x) )* np.sqrt(npower)
# 函数7：matlab仿写的软阈值去噪函数
def Thr(x):
    len1 = len(x)
    w = sorted(x) #从小到大排序
    if len1 % 2 == 1:
        v = w[int((len1+1)/2)-1] # 如len1=5，计算结果为3 ，但是3不是中间位置还需要减1
    else:
        v = (w[int(len1/2)-1] + w[int(len1/2)]) / 2 #是 偶数就 取中间两个值的平均值
    sigmal = abs(v) / 0.6745
    valve = sigmal * ( ( 2 * ( math.log(len1, math.e)  ) ) ** (0.5) )
    return valve
# 函数8：python小波去噪函数
def  quzao(data):
    mode = 'db38'
    w = pywt.Wavelet(mode)
    maxlev = pywt.dwt_max_level(len(data), w.dec_len)#找到数据可以分解的最大水平
    #maxlev = 3 #一般可以取3
    print(f"matlab小波去噪函数 - 原始数据在{mode}小波基下的最大分解水平为："  + str (maxlev) ) # 这是可以分解的最大水平，但是不推荐，本信号最大可分解6层，但是3 最好
    coeffs = pywt.wavedec(data , w ,level = int(maxlev / 2 ) )# 高频细节系数 ，#返回CAn,CDn,CDn-1,CDn-2,....CD1
    for j in range(1 , len(coeffs)) : # 外循环，不同的细节系数轮流去噪 ,从1开始，因为第1个是近似系数
        valve = Thr(coeffs[j]) #当前的细节系数 计算阈值
        temp = coeffs[j] #把当前细节系数给副本temp ，整行赋值
        for i in range(int(len(temp))):#内循环 ，对当前细节系数每一个元素进行处理 ， 循环次数取决于 当前细节系数的长度
            if (abs(temp[int(i)]) <= valve):#绝对值小于等于阈值的都取0
                temp[int(i)] = 0
            else:
                if (temp[int(i)] > valve ):
                    temp[int(i)] = temp[int(i)-1] - valve  #绝对值大于阈值的都减去阈值
                else:
                    temp[int(i)] = temp[int(i) - 1] + valve #其他情况 ，比如很大的负数，加上阈值
        coeffs[j] = temp #可以这样赋值，把当前去噪后的细节系数替换掉 存放细节系数的coeffs
    datarec = pywt.waverec(coeffs , w) #外循环结束 ，  所有替换过的 coeffs 再做逆重构
    return datarec
#函数9：db8 小波去噪函数
def quzao_1(x):
    w = pywt.Wavelet('db8')
    maxlev = pywt.dwt_max_level(len(x), w.dec_len )
    print("python小波去噪函数 - 原始数据在db8小波基的最大分解水平为： " + str(maxlev))
    threshold = 0.04
    coeffs = pywt.wavedec(x, 'db8',level = maxlev )
    for i in range(1, len(coeffs)): #只对细节系数处理 ，也就是高频分量去噪
        coeffs[i] = pywt.threshold(coeffs[i], threshold*max(coeffs[i]))
    datarec = pywt.waverec(coeffs,'db8') #将信号小波重构
    return  datarec
#函数10：自定义的绘图函数Plot
def Plot(x,y,legendname,titlename,xlabelname,ylabelname):
    '''设置图片大小，分辨率，[图像编号]，背景色，是否显示边框 ， 边框颜色'''
    plt.figure(figsize=(8,4) , dpi= 144, facecolor= 'w' , frameon= True  ,  edgecolor= 'b')

    '''设置图例文字，线颜色，线型，线宽，线风格，标记类型，标记尺寸，标记颜色，透明度'''
    plt.plot(x,y,label=legendname, color='r' , linewidth = 0.6, linestyle =  '--' , marker = 'o',
             markersize = '2' , markerfacecolor = 'w' , alpha = 0.5)

    '''设置图例的文字，位置 ， 文字大小， 多图例按列数显示(默认按行)， 图例标记为原尺寸的多少倍大小 ， 是否添加阴影 ， 图里圆角方角，是否带边框， 边框透明度'''
    plt.legend((legendname,), loc= 'upper right' , fontsize = 18,ncol = 1, markerscale=1, shadow=False , fancybox=True,  frameon = True , framealpha=0.5)

    '''设置网格线是否出现、显示哪个轴的网格线 ，网格线颜色， 风格、 宽度、 设置次刻度线（default = major）'''
    #plt.grid(b=None, axis= 'x', color ='k', linestyle = '-.',linewidth = 5 , which= 'major')

    '''设置坐标轴范围'''
    ymax = max(y)
    ymin = min(y)
    xmax = max(x)
    xmin = min(x)
    plt.ylim(ymin , ymax)
    plt.xlim(xmin , xmax)

    '''设置轴标签是否旋转，文字垂直和水平位置'''
    plt.xlabel(xlabelname,fontsize=18 ,rotation = None , verticalalignment = 'top' )
    plt.ylabel(ylabelname,fontsize=18 ,rotation = 90 , verticalalignment = 'bottom' )

    '''设置轴刻度'''
    plt.yticks(())
    plt.xticks(())

    '''设置哪个轴的属性、次刻度线设置， 刻度线显示方式(绘图区内测、外侧、同时显示)，刻度线宽度，刻度线颜色、刻度线标签颜色(任命/日期等)
    刻度线与标签距离、刻度线标签大小、刻度线是否显示(default=bottom ,left)、刻度线标签是否显示(default = bottom/left)'''
    plt.tick_params (axis='both',which='major' , direction = 'in' , width=1,length=3,color='k',labelcolor='k', pad=1,
                     labelsize = 15, bottom = True , right =True , top = False, labeltop=False,labelbottom = True ,
                                    labelleft = True , labelright = False)

    '''方框外形、背景色、 透明度、方框粗细、方框到文字的距离'''
    bb = dict(boxstyle ='round',fc='w', ec = 'm',alpha=0.8, lw=10, pad= 0.6)

    '''设置标题文字大小、标题大小、标题正常/斜体/倾斜、垂直位置、水平位置、透明度、标题背景色、是否旋转、标题边框有关设置（字典格式）'''
    plt.title (label=titlename , fontsize =24, fontweight='normal', fontstyle='italic',verticalaligment='bottom',
                alpha=0.8 , backgroundcolor = 'w', rotation = None )#bbox = bb

    plt.show()
#主程序main################################################
# 1、定义原始数据
fs=25000 #采样频率要大于 信号频率 的两倍
f0=2000
f1=6000
t = np.arange(0,1,1/fs)
#x = 0.6 * (1+np.sin(2 * np.pi * f0 * t)) * np.sin(2 * np.pi * f1 * t)
x = 4 + 6*np.sin(2000*np.pi*t) + 8*np.sin(6000*np.pi*t) + 10*np.sin(10000*np.pi*t)
#2、添加白噪声
x = x + wgn(x,3)
#3、使用函数9 db8小波基去噪
xrec = quzao_1(x)
ymax = max(xrec)
ymin = max(xrec)
#4、去噪前后图像比对，因为子图缘故不可以调用Plot函数
plt.figure(figsize= (8,4))
plt.subplot(2,1,1)
plt.plot(t,x,c='cornflowerblue',linestyle='-',linewidth=0.6)
plt.xlabel('时间 (s)')
plt.ylabel('幅值 (m)')
plt.xlim(min(t),max(t))
plt.ylim(min(x)+1,max(x)+1)
plt.legend(('source_signal',),loc='upper right',fontsize=10,frameon=True )
plt.title('source',fontsize=20)
plt.xticks(())
plt.yticks(())

plt.subplot(2,1,2)
plt.plot(t,xrec,c='lightslategrey',linestyle='-',linewidth=0.6)
plt.xlabel('时间 (s)')
plt.ylabel('幅值 (m)')
plt.xlim(min(t),max(t))
plt.ylim(min(xrec)+1,max(xrec)+1)
plt.legend(('denoised_signal',),loc='upper right',fontsize=10,frameon=True )
plt.title('denoised',fontsize=20)
plt.xticks(())
plt.yticks(())

plt.tight_layout ()#自动调整子图间距，使之填充整个图像区域
plt.show()
#5、emd分解
imf = emd(xrec)
#6、imf分量绘制 前4个imf分量
fig , ax = plt.subplots (2,2)
plt.subplots_adjust (wspace= 0.4,hspace=0.4)#调整子图大小
axs = ax.flatten() #面向对象，将子图句柄展开，其中每个元素代表1个子图
'''子图分别绘制'''
'''imf1'''
axs[0].plot(t , imf[0] , color='lightseagreen' , linewidth = 0.6 ,linestyle = '-')
axs[0].set_title('imf1', fontsize=15)
axs[0].legend(('imf1',),loc = 'upper right',fontsize=10,frameon =True)
axs[0].set_xticks(())
axs[0].set_yticks(())
'''imf2'''
axs[1].plot(t , imf[1] , color='deepskyblue' , linewidth = 0.6 ,linestyle = '-')
axs[1].set_title('imf2', fontsize=15)
axs[1].legend(('imf2',),loc = 'upper right',fontsize=10,frameon =True)
axs[1].set_xticks(())
axs[1].set_yticks(())
'''imf3'''
axs[2].plot(t , imf[2] , color='blueviolet' , linewidth = 0.6 ,linestyle = '-')
axs[2].set_title('imf2', fontsize=15)
axs[2].legend(('imf2',),loc = 'upper right',fontsize=10,frameon =True)
axs[2].set_xticks(())
axs[2].set_yticks(())
'''imf4'''
axs[3].plot(t , imf[3] , color='dimgrey' , linewidth = 0.6 ,linestyle = '-')
axs[3].set_title('imf3', fontsize=15)
axs[3].legend(('imf3',),loc = 'upper right',fontsize=10,frameon =True)
axs[3].set_xticks(())
axs[3].set_yticks(())

plt.show()
# 7、傅里叶变换
from scipy.fftpack import fft , ifft
fftx = fft(xrec)
mol = np.abs(fftx)
t_mol = mol[range(int(fs/2))]/(fs/2) #频域纵坐标到时域纵坐标的转换
freq = ( ( t[ range(int(fs/2 ) ) ] + 1/fs) * fs -1) #时域横坐标到频域横坐标的转换，并取一半
angle = np.angle(fftx) #复数模 和 相位
'''绘制原始信号的频谱图'''
plt.figure(dpi=144,figsize= (8,4))
plt.plot(freq , t_mol ,c = 'blueviolet' , linewidth=0.6 , linestyle = '-')
plt.title('去噪信号的频谱图', fontsize =20)
plt.legend(('频谱图',),loc = 'upper right' , fontsize=15 , frameon = True)
plt.show()
'''循环绘制4个imf分量的频谱图'''
fig1  = plt.figure(dpi=144,figsize= (8,6))
title = ('imf1','imf2','imf3','imf4')
for i in range(4):
    fftimf = fft(imf[i])
    molimf = np.abs(fftimf)
    angleimf = np.angle(fftimf)
    half_molimf = molimf[range(int(fs/2))] / (fs/2)
    freq = ((t[range(int(fs/2))] + 1/fs) * fs -1)
    Q=fig1.add_subplot(2,2,i+1)
    Q.plot(freq , half_molimf ,c = 'blueviolet' , linestyle='-' , linewidth = 0.6)
    Q.set_title(title[i],fontsize=20)
    Q.legend((title[i],),loc='upper right',fontsize=15 , frameon=True )
plt.tight_layout ()
plt.show()

#8、主成分分析PCA
from sklearn.decomposition import PCA
data_pca = np.array(imf) #转换为数组格式，原本是列表格式，imf是行向量
pca = PCA(n_components= 0.90 , copy =True ,whiten = False ) #找到占比95%以上的imf分量
pca.fit(data_pca )
pca_tran = pca.transform(data_pca )
print('主要的imf分量个数为：'+ str(pca.n_components_)) #返回被保留的主成分个数
print('各imf分量占比依次为：'+str(pca.explained_variance_ratio_))# 各imf分量的占比
#print(pca.explained_variance_ ) #找到特征向量的方差，也就是特征值
#print(pca.components_ ) #返回被保留的主成分值，也可以直接查看pca


"""
@Author: Su Ming Yi
@Date: 10/15/2018
@five.py

1. load an image
2. indentify the five lines positions
3. draw the upper line and lower line draw on
    the image and save them in Output directory.
4. return the y upper line and lower line.

"""

import sys
import math
import cv2 as cv
import numpy as np
import line_detection as ld

'''
Get five_lines positions.

@param filename
    - the file that we want to predict
@output
    - directory: Output/Result_Five/
    - name: after + "filename"
    - change: add additional colored lines
@return - the positions of the five lines, top y position, and bottom y position
'''
def five_lines(filename):
    y_position =[];
    y_position_bottom =[];
    print("Input filename: ", filename)
    # Loads an image
    src = cv.imread(filename, cv.IMREAD_UNCHANGED)
    #print("filename: ", filename)
    # Check if image is loaded fine
    if src is None:
        print('Error opening image!')
        return -1;
    height, width = src.shape[:2]
    print("Original image size \nheight: ", height, "\nwidth: ", width)
#####################################################################################
    # x: the horizon position of the top left
    # y: the vertical position of the top left
    # slide_w: the width of sliding window
    # slide_h: the height of sliding window
    #slide_h = round(height/20);
    #h_increase = round(height/20);
    slide_h = round(height/20);
    h_increase = round(height/100*2);
    w_increase = round(width/20);
    x = [round(width/5), round(width/2), round(width/5*4)];
    b_h = False;
    while(slide_h<=height/10 and b_h!=True):
        slide_w = round(width/20);
        while(slide_w<=width/10):

            for i in range(0, len(x)):
                y=0;
                cur_x = x[i];
                while y < height-slide_h:
                    crop_img = src[y:y+slide_h, cur_x:cur_x+slide_w];
                    # Display the image
                    line_number = ld.number_line(filename, cur_x, y, crop_img, slide_w, slide_h, False);
                    #print("the # of lines in segment regions: ", line_number);
                    if (line_number<5):
                        y = y+1;
                    if (line_number>=5):
                        b_h = True;
                        b= True;
                        for k in range(0, len(y_position)):
                            if(abs(y_position[k]-y)<height/100):
                                b = False;
                            if(abs(y_position_bottom[k]-(y+slide_h))<height/100):
                                b = False;
                            if(y>y_position[k] and y<y_position_bottom[k]):
                                b = False;
                            if(y+slide_h>y_position[k] and y+slide_h<y_position_bottom[k]):
                                b = False;
                        if(b):
                            y_position.append(y);
                            tmp = y+slide_h;
                            y_position_bottom.append(tmp);
                            print("y position of five lines= [", y, ", ", y+slide_h, "]");
                        y = y + slide_h;
            slide_w = slide_w+w_increase;
        slide_h = slide_h+h_increase;
############################################################################################
    # draw the lines on source image
    for i in range(0, len(y_position)):
        cv.line(src, (0, y_position[i]), (width, y_position[i]), (0,0,255), 2)
        cv.line(src, (0, y_position_bottom[i]), (width, y_position_bottom[i]), (255,0,0), 2)
    # save result
    store = "../Output/Result_Five/after_"+filename[29:];
    cv.imwrite(store,src);

    return y_position, y_position_bottom;


from django.db import models
from django.utils.translation import ugettext_lazy as _

class PageHit(models.Model):
    """
    Model to save the hit counts for any urls.
    """
    url = models.CharField(_('URL'), max_length=2000)
    visit_date = models.DateField(_('Visit date'), editable=False)
    modified_at = models.DateTimeField(_('Modified'), auto_now=True,
                                       editable=False)
    anonymous_hits = models.PositiveIntegerField(_('Anonymous user Hits'),
                                                 default=0)
    created_at = models.DateTimeField(_('Created'), auto_now_add=True,
                                      editable=False)
    registered_hits = models.PositiveIntegerField(_('Registered user hits'),
                                                  default=0)

    class Meta:
        ordering = ('-visit_date', '-modified_at')
        get_latest_by = 'created_at'


import flask
import json
from flask import Flask, request, render_template, jsonify
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

graphs = {}
@app.route("/", methods=["GET"])
def get_data():
    for name in graphs:
        print(graphs[name])
    html_graphs = [{"x": graphs[name]["x"],"y": graphs[name]["y"], "name": name } for name in graphs]
    print("html_graphs=", html_graphs)

    return flask.render_template("graph.html", graphs=html_graphs)

@app.route("/", methods=["POST"])
def put_data():
    # Use the line below if request comes through usual POST
    graph = request.get_json()
    for name in graph:
        if name not in graphs:
            graphs[name]={"x":[], "y":[]}
        graphs[name]["x"].extend(graph[name]["x"])
        graphs[name]["y"].extend(graph[name]["y"])

    html_graphs = [{"x": graphs[name]["x"],"y": graphs[name]["y"], "name": name } for name in graphs]
    return flask.render_template("graph.html", graphs=html_graphs)

if __name__=="__main__":
    app.run(debug=True)


# -*- coding: utf-8 -*-
"""
Created on Sun Apr 16 19:31:29 2023

@author: ranad
"""

import torch
import torch.nn as nn

# Initial setup
# --------------------------------------------------------------------
device = "cuda" if torch.cuda.is_available() else "cpu"

# Calculate losses
def real_loss(D_out, smooth=False):
    batch_size = D_out.size(0)
    # label smoothing
    if smooth:
        # smooth, real labels = 0.9
        labels = torch.ones(batch_size).to(device)*0.9
    else:
        labels = torch.ones(batch_size).to(device) # real labels = 1

    # numerically stable loss
    criterion = nn.BCEWithLogitsLoss()
    # calculate loss
    loss = criterion(D_out.squeeze(), labels)
    return loss

def fake_loss(D_out):
    batch_size = D_out.size(0)
    labels = torch.zeros(batch_size).to(device) # fake labels = 0
    criterion = nn.BCEWithLogitsLoss()
    # calculate loss
    loss = criterion(D_out.squeeze(), labels)
    return loss


import sys
import numpy as np
import cv2

# 녹색 배경 동영상
cap1 = cv2.VideoCapture('woman.mp4')

if not cap1.isOpened():
    print('video open failed!')
    sys.exit()

# 비오는 배경 동영상
cap2 = cv2.VideoCapture('raining.mp4')

if not cap2.isOpened():
    print('video open failed!')
    sys.exit()

# 두 동영상의 크기, FPS는 같다고 가정
frame_cnt1 = round(cap1.get(cv2.CAP_PROP_FRAME_COUNT))
frame_cnt2 = round(cap2.get(cv2.CAP_PROP_FRAME_COUNT))
print('frame_cnt1:', frame_cnt1)
print('frame_cnt2:', frame_cnt2)

fps = cap1.get(cv2.CAP_PROP_FPS)
delay = int(1000 / fps)
#두개 프레임사이의 간격 알기
# 합성 여부 플래그
do_composit = False
#True면 합성을 하고 거짓이면 합성을 하지 않는다.
# 전체 동영상 재생
while True:
    ret1, frame1 = cap1.read()
    #한장한장의 프레임을 frame1으로 받는다.
    if not ret1:
        break

    # do_composit 플래그가 True일 때에만 합성 아래에서 스페이스바를 통해 합성을 왔다갔다 하기 위해서임.
    if do_composit: #do_composit이 트루면,
        ret2, frame2 = cap2.read()

        if not ret2:
            break

        #frame2=cv2.resize(frame2,(w,h)) ->만약 웹캠으로 할경우 마스크와 내 웹캠의 사이즈를 맞추어야 하므로 리사이즈 해주어야합니다.

        # HSV 색 공간에서 녹색 영역을 검출하여 합성
        hsv = cv2.cvtColor(frame1, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, (50, 150, 0), (70, 255, 255))
        #마스크영상 제작
        cv2.copyTo(frame2, mask, frame1)
        #마스크가 흰색으로 되어있는 부분만 frame1(여자)으로 복사를 해라.
        #frame2 비오는 동영상

    cv2.imshow('frame', frame1)
    key = cv2.waitKey(delay)

    # 스페이스바를 누르면 do_composit 플래그를 변경
    # 스페이스를 눌러서 true와 false를 왔다갔다 한다.
    if key == ord(' '):
        do_composit = not do_composit
    elif key == 27:
        break
    #아무것도 누르지 않으면 true문에서 계속돌아 다음영상을 받는다.

cap1.release()
cap2.release()
cv2.destroyAllWindows()

21.크로마키 이미지 합성.py

21.크로마키 이미지 합성.py


from flask import Flask, render_template, send_from_directory
import os

app = Flask(__name__)

dirname = 'static/playlist'

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'),
                            'favicon.ico', mimetype='image/vnd.microsoft.icon')

@app.route('/')
def index():
    songs = []
    for song in os.listdir(dirname):
        if song.split('.')[-1] == 'mp3':
            songs.append(song)

    songs.sort(key=lambda s: s.split('-')[0])

    return render_template('index.html', songs=songs)


from collections import namedtuple
import random
import math

import torch
import torch.nn as nn
import torch.nn.functional as F

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

class CnnQLearning(nn.Module):
    def __init__(self, h, w):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=5, stride=2)
        self.bn1 = nn.BatchNorm2d(16)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=5, stride=2)
        self.bn2 = nn.BatchNorm2d(32)
        self.conv3 = nn.Conv2d(32, 32, kernel_size=5, stride=2)
        self.bn3 = nn.BatchNorm2d(32)

        def conv2d_output_size(size, kernel_size=5, stride=2):
            return (size - kernel_size) // stride + 1

        def function_call_repeat(f, time, *args):
            if time == 1:
                return f(*args)
            else:
                return f(function_call_repeat(f, time - 1, *args))
        convw = function_call_repeat(conv2d_output_size, 3, w)
        convh = function_call_repeat(conv2d_output_size, 3, h)
        linear_output_size = convh * convw * 32
        self.head = nn.Linear(linear_output_size, 2)

    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.relu(self.bn2(self.conv2(x)))
        x = F.relu(self.bn3(self.conv3(x)))
        return self.head(x.view(x.size(0), -1))

class DnnQLearning(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear1 = nn.Linear(4, 10)
        self.linear2 = nn.Linear(10, 5)
        self.head = nn.Linear(5, 2)

    def forward(self, x):
        x = F.relu((self.linear1(x)))
        x = F.relu(self.linear2(x))
        return self.head(x)

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

class ReplayMemory(object):
    def __init__(self, capacity):
        self.capacity = capacity
        self.memory = []
        self.position = 0

    def push(self, *args):
        if len(self.memory) < self.capacity:
            self.memory.append(None)
        self.memory[self.position] = Transition(*args)
        self.position = (self.position + 1) % self.capacity

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

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

def select_action(policy_net, state, steps_done, eps_start=0.9, eps_end=0.05, eps_decay=0.005):
    sample = random.random()
    eps_threshold = eps_end + (eps_start - eps_end) * math.exp(-1. * steps_done * eps_decay)
    if sample >= eps_threshold:
        with torch.no_grad():
            # t.max(1) will return largest column value of each row.
            # second column on max result is index of where max element was
            # found, so we pick action with the larger expected reward.
            return policy_net(state).max(1)[1].view(1, 1)
    else:
        return torch.tensor([[random.randrange(2)]], dtype=torch.long).to(device)


import os
from flask import Flask, redirect, request
import json

app = Flask(__name__)

@app.route("/", methods=['POST','GET', 'HEAD'])
def index():
    if request.method == 'HEAD':
        return ''
    if request.method == 'GET':
        return 'reqIest = GET'
    mandrill_event = json.loads(request.form['mandrill_events'])
    metadata = (mandrill_event[0]['msg']['metadata'])
    domain = metadata['domain']
    return redirect(domain.rstrip('/') + "/menu/autounsub/")
if __name__ == "__main__":
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)


from __future__ import print_function, division

from keras.layers import Input, Dense, GaussianNoise, LeakyReLU
from keras.models import Sequential, Model

from keras.layers import Input, Dense, GaussianNoise, LeakyReLU
from keras.models import Sequential, Model
from keras.optimizers import Adam
from keras import backend as K
import tensorflow as tf
import scipy.io as sio
import argparse
from math import *
import scipy.interpolate as interpolate
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import numpy as np
from tensorflow import keras
import tensorflow.keras.backend as K
from tensorflow.keras.models import Model
from tensorflow.keras import layers
from tensorflow.keras.losses import Loss
from sklearn.preprocessing import MinMaxScaler
from tqdm import tqdm
from sklearn.utils import shuffle
from statsmodels.distributions.empirical_distribution import ECDF as fit_ecdf
from scipy.interpolate import RegularGridInterpolator
from sklearn.model_selection import train_test_split

def inverse_transform_sampling(hist, bin_edges):
    cum_values = np.zeros(bin_edges.shape)
    cum_values[1:] = np.cumsum(hist)
    inv_cdf = interpolate.interp1d(cum_values, bin_edges)
    return inv_cdf

def wasserstein_loss(y_true, y_pred):
    return K.mean(y_true* y_pred)

def reciprocal_loss(y_true, y_pred):
    return K.mean(K.pow(y_true*y_pred,-1))

def my_binary_crossentropy(y_true, y_pred):
    return -K.mean(K.log(y_true)+K.log(y_pred))

def logsumexp_loss(y_true, y_pred):
    loss = K.logsumexp(y_pred) - K.log(tf.cast(K.shape(y_true)[0], tf.float32))
    return loss

def phi(x, mu, sigma):
    N,D = np.shape(x)
    unif_output = np.zeros((N,D))
    for i in range(N):
        for j in range(D):
            unif_output[i,j] = (1 + erf((x[i,j] - mu) / sigma / sqrt(2))) / 2
    return unif_output

#Maximum Mean Discrepancy (MMD)
def mmd_score(x,y, kernel="pow", sigma=1.0, beta=1.0, sigmas_mixture=[0.001, 0.01, 0.15, 0.25, 0.50, 0.75], drop_xx=False, drop_yy=False):
    """
    Compute Maximum Mean Discrepancy (MMD) between two multivariate distributions based on samples.
    For kernel = "pow" and beta=1.0 the MMD is equivalent to the energy distance.

    Args:
        x (numpy array): Samples from distribution p
        y (numpy array): Samples from distribution q
        kernel (str, optional): Type of kernel function. Defaults to "rbf".
        sigma (float, optional): bandwidth parameter for RBF kernel. Defaults to 1.0.
        beta (float, optional): Power for power kernel. Defaults to 1.0. This kernel recovers the energy distance.
        sigmas_mixture (list, optional): Bandwidths for mixture of RBF kernels. Defaults to [0.01, 0.1, 1.0, 10.0].

    Returns:
        float: MMD score
    """

    beta=1.0
    N = x.shape[0]
    M = y.shape[0]

    if kernel == "rbf":
        def kern(a):
            return np.exp(-np.power(a,2)/(2*sigma**2))

    elif kernel == "pow":
        def kern(a):
            return -np.power(a,beta)

    elif kernel == "rbf_mixture":
        def kern(a):
            res = 0.0
            for sig in sigmas_mixture:
                res = res + np.exp(-np.power(a,2)/(2*sig**2))
            return res

    def get_score(x,y):
        res = 0.0
        for i in range(x.shape[0]):
            res = res + np.sum(kern(np.sqrt(np.sum(np.square(x[[i],:] - y), axis=1))))
        return res

    if (drop_xx is False) and (drop_yy is False):
        return get_score(x,x)/(N*(N-1)) - 2*get_score(x,y)/(N*M)  + get_score(y,y)/(M*(M-1))

    else:
        if drop_xx:
            return get_score(y,y)/(M*(M-1)) - 2*get_score(x,y)/(N*M)
        elif drop_yy:
            return get_score(x,x)/(N*(N-1)) - 2*get_score(x,y)/(N*M)

############### define loss ################
def ed(y_data, y_model):
    """Compute Energy distance

    Args:
        y_data (tf.tensor, shape 1xDxN): Samples from true distribution.
        y_model (tf. tensor, shape 1xDxM): Samples from model.

    Returns:
        tf.float: Energy distance for batch
    """
    n_samples_model = tf.cast(tf.shape(y_model)[2], dtype=tf.float32)
    n_samples_data = tf.cast(tf.shape(y_data)[2], dtype=tf.float32)

    N = y_model.shape[-1]

    mmd_12 = tf.reduce_sum(tf.sqrt(tf.reduce_sum(tf.square(y_model - tf.repeat(tf.transpose(y_data, perm=(2,1,0)), repeats=N, axis=2)), axis=1)+K.epsilon()))
    mmd_22 = tf.reduce_sum(tf.sqrt(tf.reduce_sum(tf.square(y_model - tf.repeat(tf.transpose(y_model, perm=(2,1,0)), repeats=N, axis=2)), axis=1)+K.epsilon()))

    loss = 2*mmd_12/(n_samples_model*n_samples_data) -  mmd_22/(n_samples_model*(n_samples_model-1))
    return loss

# subclass Keras loss
class MaxMeanDiscrepancy(Loss):
    def __init__(self, beta=1.0, name="MaxMeanDiscrepancy", **kwargs):
        super().__init__(name=name, **kwargs)
        self.beta = beta

    def call(self, y_data, y_model):
        return ed(y_data, y_model)

    def get_config(self):
        cfg = super().get_config()
        cfg['beta'] = self.beta
        return cfg

################ define soft rank layer ################
class SoftRank(layers.Layer):
    """Differentiable ranking layer"""
    def __init__(self, alpha=1000.0):
        super(SoftRank, self).__init__()
        self.alpha = alpha # constant for scaling the sigmoid to approximate sign function, larger values ensure better ranking, overflow is handled properly by tensorflow

    def call(self, inputs, training=None):
        # input is a ?xSxD tensor, we wish to rank the S samples in each dimension per each batch
        # output is  ?xSxD tensor where for each dimension the entries are (rank-0.5)/N_rank
        if training:
            x = tf.expand_dims(inputs, axis=-1) #(?,S,D) -> (?,S,D,1)
            x_2 = tf.tile(x, (1,1,1,tf.shape(x)[1])) # (?,S,D,1) -> (?,S,D,S) (samples are repeated along axis 3, i.e. the last axis)
            x_1 = tf.transpose(x_2, (0,3,2,1)) #  (?,S,D,S) -> (?,S,D,S) (samples are repeated along axis 1)
            return tf.transpose(tf.reduce_sum(tf.sigmoid(self.alpha*(x_1-x_2)), axis=1), perm=(0,2,1))/(tf.cast(tf.shape(x)[1], dtype=tf.float32))
        return inputs

    def get_config(self):
        return {"alpha": self.alpha}


from requests import get
import random

def get_series():
    cs = 2
    stillvalid = True
    while stillvalid:
        if get("http://www.scpwiki.com/scp-series-" + str(cs)).status_code == 404:
            cs -= 1
            return cs
        else:
            cs += 1

def get_random_number():
    get404 = True
    while get404:
        num = random.randint(1, (get_series() * 1000) - 1)
        num_str = ""
        if len(str(num)) == 1:
            num_str = "00" + str(num)
        elif len(str(num)) == 2:
            num_str = "0" + str(num)
        else:
            num_str = str(num)
        if get("http://www.scpwiki.com/scp-" + num_str).status_code != 404:
            return num_str


__author__ = 'miguelbarbosa'
import requests
import json

def get_all_comics(start, end):  # grab all comics from 1 - 404 (because 404 is missing)
    store = []
    with open('xkcd/data/comics.json', 'w') as f:
        for n in range(start, 404):
            each_comic = requests.get("http://xkcd.com/{}/info.0.json".format(n)).json()
            store.append(each_comic)
            json.dump(each_comic, f)
        for n in range(405, end):
            each_comic = requests.get("http://xkcd.com/{}/info.0.json".format(n)).json()
            json.dump(each_comic, f)
            store.append(each_comic)
    return store