import numpy as np
import matplotlib.pyplot as plt
import os
import torch
import torchvision
import numpy as np
from torchvision import transforms
from sklearn.metrics import precision_recall_curve, average_precision_score, auc, roc_auc_score, roc_curve
import matplotlib.pyplot as plt
from config import *
import random

maha_dists = np.load('maha_dists.npy',allow_pickle=True)
input_data = np.load('/network/tmp1/bhattdha/detectron2_kitti/embeddings_storage/final_data.npy', allow_pickle=True)[()]
input_data_OOD = np.load('/network/tmp1/bhattdha/detectron2_kitti/embeddings_storage/final_data_OOD.npy', allow_pickle=True)[()]

## the dataset
X_org = input_data['features']
y_org = input_data['labels']
# X_ood = input_data_OOD['features']
# y_ood = input_data_OOD['labels']

# y_ood[y_ood == 6] = 5
# y_ood[y_ood == 7] = 5
# ood_class = [5, 6, 7]
X =  X_org
y =  y_org
## total reprodicibility
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
np.random.seed(seed)
random.seed(seed)

X_ood = input_data_OOD['features']
y_ood = input_data_OOD['labels']
val_data_all_classes = {}

means = {}
covars = {}

# train_fraction = 0.7
num_classes = max(y)+1

class_labels = np.arange(num_classes)
# class_labels = np.random.permutation(num_classes)
# class_labels = np.random.permutation(class_labels)

for class_label in class_labels:
	print('Training Class# {}'.format(class_label))

	indices = np.where(y==class_label)[0]
	# indices = np.random.permutation(indices)
	data = X[indices,:]
	# class_label_fake = (class_label + 5)%len(class_labels)
	# indices_fake = np.where(y==class_label_fake)[0]
	# val_other_class_data = X[indices_fake,:]
	# data = np.random.permutation(data)

	train_data_samples = int(len(data)*train_fraction)
	val_data_samples = int(len(data) - train_data_samples)

	train_data = 1e2*data[:train_data_samples,:]
	val_data = 1e2*data[train_data_samples:, :]

	# data = {'train_data': train_data, 'val_data': val_data}

	val_data_all_classes[str(class_label)] = val_data

	mean = np.mean(train_data, axis = 0)
	cov = np.cov(train_data.T)
	means[str(class_label)] = mean
	## may be wrong!
	covars[str(class_label)] = np.linalg.inv(cov + 1e-10*np.identity(1024))

maha_class = maha_dists[:,5].astype(int)
maha_true_dist = []
maha_false_dist = []

# for ind, m in enumerate(maha_dists):
# 	maha_true_dist.append(m[maha_class[ind]])
# 	m[maha_class[ind]] = np.inf
# 	m[5] = np.inf
# 	maha_false_dist.append(m.min())

## loading the results
# maha_true_dist = np.array(maha_true_dist)
# maha_false_dist = np.array(maha_false_dist)
# input_data_OOD = np.load('/network/tmp1/bhattdha/detectron2_kitti/embeddings_storage/final_data_OOD.npy', allow_pickle=True)[()]
# X_ood = input_data_OOD['features']
# y_ood = input_data_OOD['labels']

acc_threshs = [60.0, 70.0, 80.0, 85.0, 90.0, 95.0]
ood_stats = {}
for acc_thresh in acc_threshs:
	print("For accuracy: ", acc_thresh)
	mahathresh = {}
	class_dist = {}
	for i in range(num_classes):
		class_dist[i] = maha_dists[maha_dists[:,5]==i][:,i]
		class_dist[i].sort()
		class_dist[i] = class_dist[i][::-1]
		index = int(len(class_dist[i]) - len(class_dist[i])*acc_thresh/100.0)
		mahathresh[i] = class_dist[i][index]

	# mahathresh = {0: 3093.944707607109, 1: 5710.413855647991, 2: 28235.425795092746, 3: 79163.39452332728, 4: 2313.9860080440644}
	tp = 0
	fp = 0

	for x in X_ood:
		data_point = 1e2*x
		flag = True
		mds = [] ## has mahalanobis distances
		for mean_label in means.keys():
			diff = (data_point - means[mean_label]).reshape(len(data_point), 1)

			mahalanobis_distance = np.dot(diff.T, np.dot(covars[mean_label], diff))[0][0]

			# maha_all.append(mahalanobis_distance)
			mds.append(mahalanobis_distance)

		for i in mahathresh.keys():

			if mahathresh[i] > mds[i]:
				fp += 1
				flag = False
				break
			else:
				continue

		if flag:
			tp += 1

	ood_stats[acc_thresh] = {'tp':tp, 'fp':fp, 'accuracy': tp/(tp+fp)}

import ipdb; ipdb.set_trace()

colors = ['C'+str(i+1) for i in range(5)]

for i in range(4):
	plt.plot(class_dist[i], '-o', alpha=0.7, color=colors[i], label="class maha dists"+str(i).zfill(5))
	# plt.plot(maha_false_dist, '-o', alpha=0.7, color=colors[1], label="maha_false_dist")

# [1e3, 1e4,  1e3]
plt.legend()
plt.legend(loc='upper right')
plt.xlabel('datapoint ->')
plt.ylabel('mahalanobis distance -> ')
plt.title('Mahalanobis distance plot')
plt.savefig('maha_dists.png')

import ipdb; ipdb.set_trace()


# Sinw wave plot tool
import numpy as np
import matplotlib.pyplot as plt
f =0.5 #frequency of sine wave
# f =2
A =5# maximum amplitude of sine wave
# A = 1
x = np.arange(-6.28, 6.28, 0.01)# array arranged from -pi to +pi and with small increment of 0.01
# x = np.arange(-3.14, 3.14, 0.01)
#y = A*np.sin(f*x)
y = A*np.tan(f*x)
plt.plot(x,y)
plt.xlabel('angle')
plt.ylabel('amplitude')
plt.show()


from playsound import playsound
import os
import pandas as pd

path = "audio/" # path to the dataset
files = os.listdir(path)

df = pd.DataFrame([], columns = ["file_name", "label"])

for file, i in zip(files, range(len(files))):
	print("Currently playing " + file)
	playsound(path + file)
	label = input("Please, provide the label(n for noisy and c for clean audio files): ")
	while(label != "c" and label != "n"):
		label = input("Provided label is neither n nor c. Try again... ")
	df.loc[i] = [file, label]

df.to_json("data.json", orient = "records")


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

filters = torch.tensor([[[[2, 0, 0],
                          [1, 0, 1],
                          [0, 3, 0]],
                         [[1, 0, 1],
                          [0, 0, 0],
                          [1, 1, 0]],
                         [[0, 0, 1],
                          [1, 1, 1],
                          [1, 1, 0]]]])  # [1,3,3,3] [ [filter_nums/output_channels,input_channels,high,width]

inputs = torch.tensor([0, 2, 0, 1, 0, 0, 2, 0, 1, 1, 2, 1, 2, 0, 0, 1, 0, 0, 1, 0, -1, 1, 1, 0, 1,
                       0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0,
                       # [batch_size,in_channels,high,width]
                       1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0]).reshape([1, 3, 5, 5])

bias = torch.tensor([1])
result = F.conv2d(inputs, filters, bias=bias, stride=1, padding=0)

print("输入数据为：", inputs)
print("输入数据的形状为：", inputs.shape)
print("卷积核的形状：[filter_nums/output_channels,input_channels,high,width]  ==>", filters.shape)
print("卷积后的结果：", result)
print("结果的形状：", result.shape)


import dgl
import torch
import torch.nn as nn
import torch.nn.functional as F
import math
import dgl.function as fn
from dgl.nn.pytorch import edge_softmax
class GCNLayer(nn.Module):
    def __init__(self,
                 in_feats,
                 out_feats,
                 activation,
                 dropout,
                 bias=True):
        super(GCNLayer, self).__init__()
        self.weight = nn.Parameter(torch.Tensor(in_feats, out_feats))
        if bias:
            self.bias = nn.Parameter(torch.Tensor(out_feats))
        else:
            self.bias = None
        self.activation = activation
        if dropout:
            self.dropout = nn.Dropout(p=dropout)
        else:
            self.dropout = 0.
        self.reset_parameters()

    def reset_parameters(self):
        '''uniform init.
        '''

        stdv = 1. / math.sqrt(self.weight.size(1))
        self.weight.data.uniform_(-stdv, stdv)
        if self.bias is not None:
            self.bias.data.uniform_(-stdv, stdv)

    def forward(self, g, h):
        g = g.local_var()
        if self.dropout:
            h = self.dropout(h)
        h = torch.mm(h, self.weight)
        # normalization by square root of src degree
        h = h * g.ndata['norm']
        g.ndata['h'] = h
        g.update_all(fn.copy_src(src='h', out='m'),
                          fn.sum(msg='m', out='h'))
        h = g.ndata.pop('h')
        # normalization by square root of dst degree
        h = h * g.ndata['norm']
        # bias
        if self.bias is not None:
            h = h + self.bias
        if self.activation:
            h = self.activation(h)
        return h

class GATLayer(nn.Module):
    r"""Apply `Graph Attention Network <https://arxiv.org/pdf/1710.10903.pdf>`__
    over an input signal.

    .. math::
        h_i^{(l+1)} = \sum_{j\in \mathcal{N}(i)} \alpha_{i,j} W^{(l)} h_j^{(l)}

    where :math:`\alpha_{ij}` is the attention score bewteen node :math:`i` and
    node :math:`j`:

    .. math::
        \alpha_{ij}^{l} & = \mathrm{softmax_i} (e_{ij}^{l})

        e_{ij}^{l} & = \mathrm{LeakyReLU}\left(\vec{a}^T [W h_{i} \| W h_{j}]\right)

    Parameters
    ----------
    in_feats : int
        Input feature size.
    out_feats : int
        Output feature size.
    num_heads : int
        Number of heads in Multi-Head Attention.
    feat_drop : float, optional
        Dropout rate on feature, defaults: ``0``.
    attn_drop : float, optional
        Dropout rate on attention weight, defaults: ``0``.
    negative_slope : float, optional
        LeakyReLU angle of negative slope.
    residual : bool, optional
        If True, use residual connection.
    activation : callable activation function/layer or None, optional.
        If not None, applies an activation function to the updated node features.
        Default: ``None``.
    """
    def __init__(self,
                 in_feats,
                 out_feats,
                 num_heads,
                 feat_drop=0.,
                 attn_drop=0.,
                 negative_slope=0.2,
                 residual=False,
                 activation=None):
        super(GATLayer, self).__init__()
        self._num_heads = num_heads
        self._in_feats = in_feats
        self._out_feats = out_feats
        self.fc = nn.Linear(in_feats, out_feats * num_heads, bias=False)
        self.attn_l = nn.Parameter(torch.FloatTensor(size=(1, num_heads, out_feats)))
        self.attn_r = nn.Parameter(torch.FloatTensor(size=(1, num_heads, out_feats)))
        self.feat_drop = nn.Dropout(feat_drop)
        self.attn_drop = nn.Dropout(attn_drop)
        self.leaky_relu = nn.LeakyReLU(negative_slope)
        if residual:
            if in_feats != out_feats:
                self.res_fc = nn.Linear(in_feats, num_heads * out_feats, bias=False)
            else:
                self.res_fc = lambda x:x
        else:
            self.register_buffer('res_fc', None)
        self.reset_parameters()
        self.activation = activation

    def reset_parameters(self):
        """Reinitialize learnable parameters."""
        gain = nn.init.calculate_gain('relu')
        nn.init.xavier_normal_(self.fc.weight, gain=gain)
        nn.init.xavier_normal_(self.attn_l, gain=gain)
        nn.init.xavier_normal_(self.attn_r, gain=gain)
        if isinstance(self.res_fc, nn.Linear):
            nn.init.xavier_normal_(self.res_fc.weight, gain=gain)

    def forward(self, graph, feat):
        r"""Compute graph attention network layer.

        Parameters
        ----------
        graph : DGLGraph
            The graph.
        feat : torch.Tensor
            The input feature of shape :math:`(N, D_{in})` where :math:`D_{in}`
            is size of input feature, :math:`N` is the number of nodes.

        Returns
        -------
        torch.Tensor
            The output feature of shape :math:`(N, H, D_{out})` where :math:`H`
            is the number of heads, and :math:`D_{out}` is size of output feature.
        """
        graph = graph.local_var()
        h = self.feat_drop(feat)
        feat = self.fc(h).view(-1, self._num_heads, self._out_feats)
        el = (feat * self.attn_l).sum(dim=-1).unsqueeze(-1)
        er = (feat * self.attn_r).sum(dim=-1).unsqueeze(-1)
        graph.ndata.update({'ft': feat, 'el': el, 'er': er})
        # compute edge attention
        graph.apply_edges(fn.u_add_v('el', 'er', 'e'))
        e = self.leaky_relu(graph.edata.pop('e'))
        # compute softmax
        graph.edata['a'] = self.attn_drop(edge_softmax(graph, e))
        # message passing
        graph.update_all(fn.u_mul_e('ft', 'a', 'm'),
                         fn.sum('m', 'ft'))
        rst = graph.ndata['ft']
        # residual
        if self.res_fc is not None:
            resval = self.res_fc(h).view(h.shape[0], -1, self._out_feats)
            rst = rst + resval
        # activation
        if self.activation:
            rst = self.activation(rst)
        return rst

def adaptive_message_func(edges):
    '''
    send data for computing metrics and update.
    '''
    return {'feat':edges.src['h'],'logits': edges.src['logits']}

def adaptive_attn_message_func(edges):
    return {'feat': edges.src['ft']* edges.data['a'],
        'logits': edges.src['logits'],
        'a': edges.data['a']}

def adaptive_attn_reduce_func(nodes):
    # (n_nodes, n_edges, n_classes)
    _, pred = torch.max(nodes.mailbox['logits'], dim=2)
    _, center_pred = torch.max(nodes.data['logits'], dim=1)
    n_degree = nodes.data['degree']
    # case 1
    # ratio of common predictions
    a = nodes.mailbox['a'].squeeze(3) #(n_node, n_neighbor, n_head, 1)
    n_head = a.size(2)
    idxs = torch.eq(pred, center_pred.unsqueeze(1)).unsqueeze(2).expand_as(a)
    f1 = torch.div(torch.sum(a*idxs, dim=1), n_degree.unsqueeze(1)) # (n_node, n_head)
    f1 = f1.detach()
    # case 2
    # entropy of neighborhood predictions
    uniq = torch.unique(pred)
    # (n_unique)
    cnts_p = torch.zeros((pred.size(0), n_head, uniq.size(0),)).cuda()
    for i,val in enumerate(uniq):
        idxs = torch.eq(pred, val).unsqueeze(2).expand_as(a)
        tmp = torch.div(torch.sum(a*idxs, dim=1),n_degree.unsqueeze(1)) # (n_nodes, n_head)
        cnts_p[:,:,  i] = tmp
    cnts_p = torch.clamp(cnts_p, min=1e-5)
    f2 = (-1)* torch.sum(cnts_p * torch.log(cnts_p),dim=2)
    f2 = f2.detach()
    neighbor_agg = torch.sum(nodes.mailbox['feat'], dim=1) #(n_node, n_head, n_feat)
    return {
        'f1': f1,
        'f2':f2,
        'agg': neighbor_agg,
    }

def adaptive_reduce_func(nodes):
    '''
    compute metrics and determine if we need to do neighborhood aggregation.
    '''
    # (n_nodes, n_edges, n_classes)
    _, pred = torch.max(nodes.mailbox['logits'], dim=2)
    _, center_pred = torch.max(nodes.data['logits'], dim=1)
    n_degree = nodes.data['degree']
    # case 1
    # ratio of common predictions
    f1 = torch.sum(torch.eq(pred,center_pred.unsqueeze(1)), dim=1)/n_degree
    f1 = f1.detach()
    # case 2
    # entropy of neighborhood predictions
    uniq = torch.unique(pred)
    # (n_unique)
    cnts_p = torch.zeros((pred.size(0), uniq.size(0),)).cuda()
    for i,val in enumerate(uniq):
        tmp = torch.sum(torch.eq(pred, val), dim=1)/n_degree
        cnts_p[:, i] = tmp
    cnts_p = torch.clamp(cnts_p, min=1e-5)

    f2 = (-1)* torch.sum(cnts_p * torch.log(cnts_p),dim=1)
    f2 = f2.detach()
    return {
        'f1': f1,
        'f2':f2,
    }

class GatedAttnLayer(nn.Module):
    def __init__(self, g, in_feats, out_feats, activation, dropout, num_heads,
                 attn_drop=0.,
                 negative_slope=0.2,lidx=1):
        super(GatedAttnLayer, self).__init__()

        self._num_heads = num_heads
        self._in_feats = in_feats
        self._out_feats = out_feats
        if in_feats != out_feats:
            self.fc = nn.Linear(in_feats, out_feats * num_heads, bias=False) # for first layer

        self.feat_drop = nn.Dropout(dropout)
        self.attn_drop = nn.Dropout(attn_drop)
        self.leaky_relu = nn.LeakyReLU(negative_slope)
        self.activation = activation
        self.tau_1 = nn.Parameter(torch.zeros((1,)))
        self.tau_2 = nn.Parameter(torch.zeros((1,)))

        self.ln_1 = nn.LayerNorm((g.number_of_nodes(), num_heads),elementwise_affine=False)
        self.ln_2 = nn.LayerNorm((g.number_of_nodes(),num_heads), elementwise_affine=False)

        self.reset_parameters(lidx)

    def reset_parameters(self, lidx, how='layerwise'):
        gain = nn.init.calculate_gain('relu')
        if how == 'normal':
            nn.init.normal_(self.tau_1)
            nn.init.normal_(self.tau_2)
        else:
            nn.init.constant_(self.tau_1, 1/(lidx+1))
            nn.init.constant_(self.tau_2, 1/(lidx+1))

        return

    def forward(self, g, h, logits, old_z, attn_l, attn_r, shared_tau=True, tau_1=None, tau_2=None):
        g = g.local_var()
        if self.feat_drop:
            h = self.feat_drop(h)

        if hasattr(self, 'fc'):
            feat = self.fc(h).view(-1, self._num_heads, self._out_feats)
        else:
            feat = h
        g.ndata['h'] = feat # (n_node, n_feat)
        g.ndata['logits'] = logits

        el = (feat * attn_l).sum(dim=-1).unsqueeze(-1)
        er = (feat * attn_r).sum(dim=-1).unsqueeze(-1)
        g.ndata.update({'ft': feat, 'el': el, 'er': er})
        # compute edge attention
        g.apply_edges(fn.u_add_v('el', 'er', 'e'))
        e = self.leaky_relu(g.edata.pop('e'))
        # compute softmax
        g.edata['a'] = self.attn_drop(edge_softmax(g, e))

        g.update_all(message_func=adaptive_attn_message_func, reduce_func=adaptive_attn_reduce_func)
        f1 = g.ndata.pop('f1')
        f2 = g.ndata.pop('f2')
        norm_f1 = self.ln_1(f1)
        norm_f2 = self.ln_2(f2)
        if shared_tau:
            z = F.sigmoid((-1)*(norm_f1-tau_1)) * F.sigmoid((-1)*(norm_f2-tau_2))
        else:
            # tau for each layer
            z = F.sigmoid((-1)*(norm_f1-self.tau_1)) * F.sigmoid((-1)*(norm_f2-self.tau_2))

        gate = torch.min(old_z, z)

        agg = g.ndata.pop('agg')
        normagg = agg * g.ndata['norm'].unsqueeze(1)   # normalization by tgt degree

        if self.activation:
            normagg = self.activation(normagg)
        new_h = feat + gate.unsqueeze(2)*normagg
        return new_h,z

class GatedLayer(nn.Module):
    def __init__(self,g,in_feats, out_feats, activation, dropout, lidx=1):
        super(GatedLayer, self).__init__()
        self.weight_neighbors= nn.Linear(in_feats, out_feats)
        self.activation = activation
        self.dropout = nn.Dropout(p=dropout)
        self.tau_1 = nn.Parameter(torch.zeros((1,)))
        self.tau_2 = nn.Parameter(torch.zeros((1,)))

        self.ln_1 = nn.LayerNorm((g.number_of_nodes()),elementwise_affine=False)
        self.ln_2 = nn.LayerNorm((g.number_of_nodes()), elementwise_affine=False)

        self.reset_parameters(lidx)

    def reset_parameters(self,lidx, how='layerwise'):
        # initialize params
        if how == 'normal':
            nn.init.normal_(self.tau_1)
            nn.init.normal_(self.tau_2)
        else:
            nn.init.constant_(self.tau_1, 1/(lidx+1))
            nn.init.constant_(self.tau_2, 1/(lidx+1))
        return

    def forward(self, g, h, logits, old_z, shared_tau=True, tau_1=None, tau_2=None):
        # operates on a node
        g = g.local_var()
        if self.dropout:
            h = self.dropout(h)
        g.ndata['h'] = h
        g.ndata['logits'] = logits

        g.update_all(message_func=fn.copy_u('logits','logits'), reduce_func=adaptive_reduce_func)
        f1 = g.ndata.pop('f1')
        f2 = g.ndata.pop('f2')
        norm_f1 = self.ln_1(f1)
        norm_f2 = self.ln_2(f2)
        if shared_tau:
            z = F.sigmoid((-1)*(norm_f1-tau_1)) * F.sigmoid((-1)*(norm_f2-tau_2))
        else:
            # tau for each layer
            z = F.sigmoid((-1)*(norm_f1-self.tau_1)) * F.sigmoid((-1)*(norm_f2-self.tau_2))

        gate = torch.min(old_z, z)
        g.update_all(message_func=fn.copy_u('h','feat'), reduce_func=fn.sum(msg='feat', out='agg'))

        agg = g.ndata.pop('agg')

        normagg = agg * g.ndata['norm']   # normalization by tgt degree

        if self.activation:
            normagg = self.activation(normagg)
        new_h = h + gate.unsqueeze(1)*normagg
        return new_h,z

class GatedAPPNPConv(nn.Module):
    r"""Approximate Personalized Propagation of Neural Predictions
    layer from paper `Predict then Propagate: Graph Neural Networks
    meet Personalized PageRank <https://arxiv.org/pdf/1810.05997.pdf>`__.
    .. math::
        H^{0} & = X
        H^{t+1} & = (1-\alpha)\left(\hat{D}^{-1/2}
        \hat{A} \hat{D}^{-1/2} H^{t}\right) + \alpha H^{0}
    Parameters
    ----------
    k : int
        Number of iterations :math:`K`.
    alpha : float
        The teleport probability :math:`\alpha`.
    edge_drop : float, optional
        Dropout rate on edges that controls the
        messages received by each node. Default: ``0``.
    """
    def __init__(self,
                 g, k,
                 n_hidden, n_classes,
                 edge_drop=0., lidx=1):
        super(GatedAPPNPConv, self).__init__()
        self._k = k
        self.edge_drop = nn.Dropout(edge_drop)
        self.tau_1 = nn.Parameter(torch.zeros((1,)))
        self.tau_2 = nn.Parameter(torch.zeros((1,)))

        self.ln_1 = nn.LayerNorm((g.number_of_nodes()),elementwise_affine=False)
        self.ln_2 = nn.LayerNorm((g.number_of_nodes()), elementwise_affine=False)
        self.weight_y = nn.Linear(n_hidden, n_classes)
        self.reset_parameters(lidx)

    def reset_parameters(self,lidx, how='layerwise'):
        # initialize params
        if how == 'normal':
            nn.init.normal_(self.tau_1)
            nn.init.normal_(self.tau_2)
        else:
            nn.init.constant_(self.tau_1, 1/(lidx+1))
            nn.init.constant_(self.tau_2, 1/(lidx+1))
        return

    def forward(self, graph, feat, logits):
        r"""Compute APPNP layer.
        Parameters
        ----------
        graph : DGLGraph
            The graph.
        feat : torch.Tensor
            The input feature of shape :math:`(N, *)` :math:`N` is the
            number of nodes, and :math:`*` could be of any shape.
        Returns
        -------
        torch.Tensor
            The output feature of shape :math:`(N, *)` where :math:`*`
            should be the same as input shape.
        """
        graph = graph.local_var()
        norm = torch.pow(graph.in_degrees().float().clamp(min=1), -0.5)
        shp = norm.shape + (1,) * (feat.dim() - 1)
        norm = torch.reshape(norm, shp).to(feat.device)
        feat_0 = feat
        z = torch.FloatTensor([1.0,]).cuda()
        for lidx in range(self._k):
            # normalization by src node
            old_z = z
            feat = feat * norm
            graph.ndata['h'] = feat
            old_feat = feat
            if lidx != 0:
                logits = self.weight_y(feat)
            graph.ndata['logits'] = logits

            graph.update_all(message_func=fn.copy_u('logits','logits'), reduce_func=adaptive_reduce_func)
            f1 = graph.ndata.pop('f1')
            f2 = graph.ndata.pop('f2')
            norm_f1 = self.ln_1(f1)
            norm_f2 = self.ln_2(f2)
            z = F.sigmoid((-1)*(norm_f1-self.tau_1)) * F.sigmoid((-1)*(norm_f2-self.tau_2))

            gate = torch.min(old_z, z)
            graph.edata['w'] = self.edge_drop(
                torch.ones(graph.number_of_edges(), 1).to(feat.device))
            graph.update_all(fn.u_mul_e('h', 'w', 'm'),
                             fn.sum('m', 'h'))
            feat = graph.ndata.pop('h')
            # normalization by dst node
            feat = feat * norm
            feat = z.unsqueeze(1)* feat + old_feat # raw features

        return feat

class GraphTopoAttention(nn.Module):
    def __init__(self,
                 g,
                 in_dim,
                 topo_dim,
                 out_dim,
                 num_heads,
                 feat_drop,
                 attn_drop,
                 residual=False,
                 concat=True,
                 last_layer=False):
        super(GraphTopoAttention, self).__init__()
        self.g = g
        self.num_heads = num_heads
        if feat_drop:
            self.feat_drop = nn.Dropout(feat_drop)
        else:
            self.feat_drop = lambda x : x
        if attn_drop:
            self.attn_drop = nn.Dropout(attn_drop)
        else:
            self.attn_drop = lambda x : x
        # weight matrix Wl for leverage property
        if last_layer:
            self.fl = nn.Linear(in_dim+topo_dim, out_dim, bias=False)
        else:
            self.fl = nn.Linear(in_dim, num_heads*out_dim, bias=False)
        # weight matrix Wc for aggregation context
        self.fc = nn.Parameter(torch.Tensor(size=(in_dim+topo_dim, num_heads*out_dim)))
        # weight matrix Wq for neighbors' querying
        self.fq = nn.Parameter(torch.Tensor(size=(in_dim, num_heads*out_dim)))
        nn.init.xavier_normal_(self.fl.weight.data)
        nn.init.constant_(self.fc.data, 10e-3)
        nn.init.constant_(self.fq.data, 10e-3)
        self.attn_activation = nn.ELU()
        self.softmax = edge_softmax
        self.residual = residual
        if residual:
            if in_dim != out_dim:
                self.res_fl = nn.Linear(in_dim, num_heads * out_dim, bias=False)
                nn.init.xavier_normal_(self.res_fl.weight.data)
            else:
                self.res_fl = None
        self.concat = concat
        self.last_layer = last_layer

    def forward(self, inputs, topo=None):
        # prepare
        h = self.feat_drop(inputs)  # NxD
        if topo:
            t   = self.feat_drop(topo) #N*T

        if not self.last_layer:
            ft = self.fl(h).reshape((h.shape[0], self.num_heads, -1))  # NxHxD'
            if topo:
                ft_c = torch.matmul(torch.cat((h, t), 1), self.fc).reshape((h.shape[0], self.num_heads, -1))  # NxHxD'
            else:
                ft_c = torch.matmul(h, self.fc).reshape((h.shape[0], self.num_heads, -1))  # NxHxD'
            ft_q = torch.matmul(h, self.fq).reshape((h.shape[0], self.num_heads, -1))  # NxHxD'
            self.g.ndata.update({'ft' : ft, 'ft_c' : ft_c, 'ft_q' : ft_q})
            self.g.apply_edges(self.edge_attention)
            self.edge_softmax()

            l_s = int(0.713*self.g.edata['a_drop'].shape[0])
            topk, _ = torch.topk(self.g.edata['a_drop'], l_s, largest=False, dim=0)
            thd = torch.squeeze(topk[-1])
            self.g.edata['a_drop'] = self.g.edata['a_drop'].squeeze()
            self.g.edata['a_drop'] = torch.where(self.g.edata['a_drop']-thd<0, self.g.edata['a_drop'].new([0.0]), self.g.edata['a_drop'])
            attn_ratio = torch.div((self.g.edata['a_drop'].sum(0).squeeze()+topk.sum(0).squeeze()), self.g.edata['a_drop'].sum(0).squeeze())
            self.g.edata['a_drop'] = self.g.edata['a_drop'] * attn_ratio
            self.g.edata['a_drop'] = self.g.edata['a_drop'].unsqueeze(-1)

            self.g.update_all(fn.src_mul_edge('ft', 'a_drop', 'ft'), fn.sum('ft', 'ft'))
            ret = self.g.ndata['ft']
            if self.residual:
                if self.res_fl is not None:
                    resval = self.res_fl(h).reshape((h.shape[0], self.num_heads, -1))  # NxHxD'
                else:
                    resval = torch.unsqueeze(h, 1)  # Nx1xD'
                ret = resval + ret
            ret = torch.cat((ret.flatten(1), ft.mean(1).squeeze()), 1) if self.concat else ret.flatten(1)
        else:
            if topo:
                ret = self.fl(torch.cat((h, t), 1))
            else:
                ret = self.fl(h)

        return ret

    def edge_attention(self, edges):
        c = edges.dst['ft_c']
        q = edges.src['ft_q'] - c
        a = (q * c).sum(-1).unsqueeze(-1)
        return {'a': self.attn_activation(a)}

    def edge_softmax(self):
        attention = self.softmax(self.g, self.g.edata.pop('a'))
        self.g.edata['a_drop'] = self.attn_drop(attention)


from typing import List

class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        ans = [0] * len(temperatures)
        stack = [0]
        for i in range(1, len(temperatures)):
            if temperatures[i] <= temperatures[stack[-1]]:
                # if temp is not larger, just push into stack
                stack.append(i)
            else:
                while len(stack) != 0 and temperatures[i] > temperatures[stack[-1]]:
                    # if temp is larger, update the index
                    ans[stack[-1]] = i - stack[-1]
                    stack.pop()
                stack.append(i)
        return ans

if __name__ == "__main__":
    temperatures = [73,74,75,71,69,72,76,73]
    s = Solution()
    print(s.dailyTemperatures(temperatures))


import matplotlib.pyplot as plt
import numpy as np
import os, tkinter, tkinter.filedialog, tkinter.messagebox

# show the file selection filedialog
root = tkinter.Tk()
root.withdraw()
fTyp = [('','*')]
iDir = os.path.abspath(os.path.dirname(__file__))
# tkinter.messagebox.showinfo('簡易プロットプログラムです','どのフォルダのcsvでグラフを作る？')

# output the processing file name
file = tkinter.filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir)
# tkinter.messagebox.showinfo('oxプログラム',file)

df = np.loadtxt(file, skiprows=5, delimiter=',', encoding='utf-8')

rows = len(df[:,0])
x = np.arange(rows)

# 横軸の単位をsecondにしてグラフを見たいときはこちら↓を使う。
# plt.plot(df[:,0], df[:,1])
# 横軸を「1～csvファイルの行数」としてグラフを見たいときはこちら↓を使う。
plt.plot(x, df[:,1])

# plt.vlines(np.arange(24800,26400,200), -0.05, 0.05, color='k', linestyle=':', lw=0.5)
# plt.fill_between([24800,26400], -0.05, 0.05, color='skyblue')

plt.show()


from django.shortcuts import render, get_object_or_404, redirect, HttpResponse
from django.contrib.auth.decorators import login_required
from account.models import User
from product.models import Product
from .models import Message, MessageRoom

@login_required
def check_message_room(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    receiver = product.creator
    sender = request.user
    message_room = MessageRoom.objects.filter(product=product,sender=sender)
    if not message_room.exists():
        message_room =MessageRoom.objects.create(product=product,sender=sender, receiver=receiver)
    else:
        message_room = MessageRoom.objects.get(product=product,sender=sender)

    # if request.method == 'POST':
    #     content = request.POST.get('content')
    #     sender = request.user

    #     message = Message.objects.create(
    #         sender=sender,
    #         receiver=receiver,
    #         product=product,
    #         content=content
    #     )

        # Perform any additional actions, notifications, or redirects

    return redirect('messaging:message-room',id=message_room.id)

@login_required
def message_room(request,id):

    message_room = get_object_or_404(MessageRoom, id=id)
    if request.user == message_room.sender or request.user == message_room.receiver:
        return render(request, 'messaging/messageroom.html', {'message_room':message_room})

    else:
        return HttpResponse('Unauthorized access. Sorry')

def view_messages(request):
    # messages = MessageRoom.objects.filter(receiver=user).order_by('-id') | MessageRoom.objects.filter(sender=user).order_by('-id')
    messages = MessageRoom.with_messages(request.user)
    return render(request, 'messaging/view_messages.html', {'messages': messages})

@login_required
def send_messages(request):
    if request.method == "POST":
        message = request.POST.get('message')
        room_id = request.POST.get("roomid")
        room = MessageRoom.objects.get(id=room_id)
        Message.objects.create(room=room,content=message, sender=request.user)
        return redirect('messaging:message-room',id=room.id)

    return HttpResponse('Something went wrong.')


from fastapi import APIRouter, Depends, HTTPException

from ...celery.tasks import ExcelParser
from ..crud.dishes_crud import DishesCrud
from ..crud.menu_crud import MenuCrud
from ..crud.submenu_crud import SubmenuCrud

parser_router = APIRouter(prefix='/parser', tags=['Parser'])

@parser_router.post('/parse-excel')
async def parse_excel(
    menu_service: MenuCrud = Depends(),
    submenu_service: SubmenuCrud = Depends(),
    dish_service: DishesCrud = Depends()
):
    try:
        excel_parser = ExcelParser(menu_service, submenu_service, dish_service)
        await excel_parser.parser()
        return {'message': 'Excel data parsed and loaded successfully'}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


from typing import Dict, List, Optional, Tuple

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

from .conv_tasnet import TCN, GatedTCN
from .lobe.activation import get_activation
from .lobe.norm import get_norm
from .lobe.rnn import FSMN, ConditionFSMN

class Unet(nn.Module):
    """
    Generic_Args:
        input_type: Real or RI(real+image)
        input_dim: input feature dimension
        activation_type: activation function
        norm_type: normalization function
        dropout: if not 0, add dropout in down-CNN layers

    Unet_Args:
        channels: controlled input/output channel for Unet
        kernel_t: kernel size in time axis for each down cnn layer
        kernel_f: kernel size in freq axis for each down/up cnn layer
        stride_t: stride size in time axis for each down cnn layer
        stride_f: stride size in freq axis for each down/up cnn layer
        dilation_t: dilation size in time axis for each down cnn layer
        dilation_f: dilation size in freq axis for each down/up cnn layer
        delay: add lookahead frames in each down cnn layers, if 0 means causal cnn operation
        transpose_t_size: the kernel size of ConvTranspose2d's time axis for up cnn layer
        skip_conv
    """

    def __init__(
        self,
        input_type: str = "RI",
        input_dim: int = 512,
        activation_type: str = "PReLU",
        norm_type: str = "bN2d",
        dropout: float = 0.05,
        channels: Tuple = (1, 1, 8, 8, 16, 16),
        transpose_t_size: int = 2,
        skip_conv: bool = False,
        kernel_t: Tuple = (5, 1, 9, 1, 1),
        stride_t: Tuple = (1, 1, 1, 1, 1),
        dilation_t: Tuple = (1, 1, 1, 1, 1),
        kernel_f: Tuple = (1, 5, 1, 5, 1),
        stride_f: Tuple = (1, 4, 1, 4, 1),
        dilation_f: Tuple = (1, 1, 1, 1, 1),
        delay: Tuple = (0, 0, 1, 0, 0),
        multi_output: int = 1,
    ):
        super().__init__()
        assert (
            len(kernel_t)
            == len(kernel_f)
            == len(stride_t)
            == len(stride_f)
            == len(dilation_t)
            == len(dilation_f)
        )
        self.input_type = input_type
        self.input_dim = input_dim
        self.multi_output = multi_output
        self.activation_type = activation_type
        self.norm_type = norm_type
        self.dropout = dropout
        self.skip_conv = skip_conv

        # Structure information
        self.kernel_t = kernel_t
        self.kernel_f = kernel_f
        self.stride_t = stride_t
        self.stride_f = stride_f
        self.dilation_t = dilation_t
        self.dilation_f = dilation_f
        self.transpose_t_size = transpose_t_size

        active_cls = get_activation(activation_type.lower())
        norm_cls = get_norm(norm_type)

        self.n_cnn = len(kernel_t)
        self.channels = list(channels)
        self.kernel = list(
            zip(kernel_f, kernel_t)
        )  # each layer's kernel size (freq, time)
        self.delay = delay  # how much delay for each layer
        self.dilation = list(zip(dilation_f, dilation_t))
        self.stride = list(zip(stride_f, stride_t))
        self.t_kernel = transpose_t_size

        # Check relationship between feature-type and input-channel
        if input_type.lower() == "ri":
            self.num_freq = input_dim // 2
            self.channels[0] = self.channels[0] * 2  # will expand RI channel

        elif input_type.lower() == "real":
            self.num_freq = input_dim

        else:
            raise TypeError("Input feature type should be RI-concate, RI-stack or Real")

        # CNN-down, downsample in frequency axis
        self.cnn_down = nn.ModuleList()
        for i in range(self.n_cnn):
            encode = []
            freq_pad = (
                self.kernel[i][0] // 2,
                self.kernel[i][0] // 2,
            )  # center padding in frequency axis
            time_pad = (self.kernel[i][1] - self.delay[i] - 1, self.delay[i])
            encode += [
                nn.ZeroPad2d(time_pad + freq_pad),  # (left, right, top, down)
                nn.Conv2d(
                    self.channels[i],
                    self.channels[i + 1],
                    kernel_size=self.kernel[i],
                    stride=self.stride[i],
                    dilation=self.dilation[i],
                ),
                norm_cls(self.channels[i + 1]),
                active_cls(),
                nn.Dropout(self.dropout),
            ]

            self.cnn_down.append(nn.Sequential(*encode))

        # CNN-up, upsample in frequency axis
        self.cnn_up = nn.ModuleList()
        skip_double = 2 if not skip_conv else 1
        skip_double = [skip_double] * self.n_cnn

        for i in reversed(range(self.n_cnn)):
            s, _ = self.stride[i]
            k = self.kernel[i][0]
            p = k // 2
            op = s - k + 2 * p
            encode = []
            if i != 0:
                encode += [
                    nn.ConvTranspose2d(
                        self.channels[i + 1] * skip_double[i],
                        self.channels[i],
                        kernel_size=(k, self.t_kernel),
                        stride=self.stride[i],
                        dilation=self.dilation[i],
                        padding=(p, 0),
                        output_padding=(op, 0),
                    ),
                    norm_cls(self.channels[i]),
                    active_cls(),
                ]

            else:
                # linear output
                encode += [
                    nn.ConvTranspose2d(
                        self.channels[i + 1] * skip_double[i],
                        self.channels[i] * self.multi_output,
                        kernel_size=(k, self.t_kernel),
                        stride=self.stride[i],
                        dilation=self.dilation[i],
                        padding=(p, 0),
                        output_padding=(op, 0),
                    )
                ]

            self.cnn_up.append(nn.Sequential(*encode))

        if skip_conv:
            self.skip_cnn = nn.ModuleList()
            for i in reversed(range(self.n_cnn)):
                encode = []
                encode += [
                    nn.Conv2d(
                        self.channels[i + 1],
                        self.channels[i + 1],
                        kernel_size=(1, 1),
                        stride=1,
                    ),
                    active_cls(),
                ]

                self.skip_cnn.append(nn.Sequential(*encode))

    def shape_info(self):
        # input_shape = [N, ch, C, T]
        # conv-transpose output size is:
        #   (freq): (input_shape[2] -1) * stride[0] - 2*padding[0] + dilation[0] * (kernel_size[0]-1) + output_padding[0] + 1
        #   (time): (input_shape[2] -1) * stride[1] - 2*padding[1] + dilation[1] * (kernel_size[1]-1) + output_padding[1] + 1
        down_shape = [self.num_freq]
        for i in range(self.n_cnn):
            stride, _ = self.stride[i]
            if down_shape[i - 1] % stride == 0:
                _f = down_shape[-1] // stride
            else:
                _f = down_shape[-1] // stride
                _f += 1
            down_shape.append(_f)

        up_shape = [_f]
        for i in range(self.n_cnn):
            stride, _ = self.stride[-i - 1]
            kernel_size = self.kernel[-i - 1][0]
            padding = kernel_size // 2
            output_padding = stride - kernel_size + 2 * padding
            _f = (
                (up_shape[-1] - 1) * stride
                - 2 * padding
                + self.dilation[-i - 1][0] * (kernel_size - 1)
                + output_padding
                + 1
            )
            up_shape.append(_f)

        return down_shape, up_shape

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        Args:
            x: input tensor shape [N, C, T]

        Returns:
            output tensor has shape [N, C, T]
        """
        if self.input_type.lower() == "ri":
            _re, _im = torch.chunk(x, 2, dim=-2)
            x = torch.stack([_re, _im], dim=1)  # [N, C, T] -> [N, 2, C, T]
        else:
            if x.dim() == 3:
                x = x.unsqueeze(1)  # [N, 1, C, T]

        skip = [x.clone()]

        # forward CNN-down layers
        for cnn_layer in self.cnn_down:
            x = cnn_layer(x)  # [N, ch, C, T]
            skip.append(x)

        # forward CNN-up layers
        for i, cnn_layer in enumerate(self.cnn_up):
            if self.skip_conv:
                x += self.skip_cnn[i](skip[-i - 1])
            else:
                x = torch.cat([x, skip[-i - 1]], dim=1)

            x = cnn_layer(x)
            if self.t_kernel != 1:
                x = x[
                    ..., : -(self.t_kernel - 1)
                ]  # transpose-conv with t-kernel size would increase (t-1) length

        if self.multi_output != 1:
            batch, ch, fdim, tdim = x.shape
            x = x.reshape(batch, self.multi_output, -1, fdim, tdim)
            if self.input_type.lower() == "ri":
                _re = x[:, :, 0, :, :]
                _im = x[:, :, 1, :, :]
                x = torch.cat([_re, _im], dim=2)

            else:
                x = x.squeeze(2)  # [N, M, 1, C, T] -> [N, C, T]

        else:
            if self.input_type.lower() == "ri":
                _re = x[:, 0, :, :]
                _im = x[:, 1, :, :]
                x = torch.cat([_re, _im], dim=1)

            else:
                x = x.squeeze(1)  # [N, 1, C, T] -> [N, C, T]

        return x

    @property
    def get_args(self) -> Dict:
        return {
            "input_type": self.input_type,
            "input_dim": self.input_dim,
            "activation_type": self.activation_type,
            "norm_type": self.norm_type,
            "dropout": self.dropout,
            "channels": self.channels,
            "transpose_t_size": self.transpose_t_size,
            "skip_conv": self.skip_conv,
            "kernel_t": self.kernel_t,
            "stride_t": self.stride_t,
            "dilation_t": self.dilation_t,
            "kernel_f": self.kernel_f,
            "stride_f": self.stride_f,
            "dilation_f": self.dilation_f,
            "delay": self.delay,
            "multi_output": self.multi_output,
        }

class UnetTcn(Unet):
    """
    Improve temporal modeling ability by inserting a TCN inside an Unet model.

    Args:
        embed_dim: Embedding feature dimension.
        embed_norm: If True, applies the 2-norm on the input embedding.
    """

    def __init__(
        self,
        embed_dim: int = 0,
        embed_norm: bool = False,
        input_type: str = "RI",
        input_dim: int = 512,
        activation_type: str = "PReLU",
        norm_type: str = "bN2d",
        dropout: float = 0.05,
        channels: Tuple = (1, 1, 8, 8, 16, 16),
        transpose_t_size: int = 2,
        transpose_delay: bool = False,
        skip_conv: bool = False,
        kernel_t: Tuple = (5, 1, 9, 1, 1),
        stride_t: Tuple = (1, 1, 1, 1, 1),
        dilation_t: Tuple = (1, 1, 1, 1, 1),
        kernel_f: Tuple = (1, 5, 1, 5, 1),
        stride_f: Tuple = (1, 4, 1, 4, 1),
        dilation_f: Tuple = (1, 1, 1, 1, 1),
        delay: Tuple = (0, 0, 1, 0, 0),
        tcn_layer: str = "normal",
        tcn_kernel: int = 3,
        tcn_dim: int = 256,
        tcn_dilated_basic: int = 2,
        per_tcn_stack: int = 5,
        repeat_tcn: int = 4,
        tcn_with_embed: List = [1, 0, 0, 0, 0],
        tcn_use_film: bool = False,
        tcn_norm: str = "gLN",
        dconv_norm: str = "gGN",
        causal: bool = False,
    ):
        super().__init__(
            input_type,
            input_dim,
            activation_type,
            norm_type,
            dropout,
            channels,
            transpose_t_size,
            skip_conv,
            kernel_t,
            stride_t,
            dilation_t,
            kernel_f,
            stride_f,
            dilation_f,
            delay,
        )

        self.embed_dim = embed_dim
        self.embed_norm = embed_norm
        self.tcn_layer = tcn_layer
        self.tcn_dim = tcn_dim
        self.tcn_kernel = tcn_kernel
        self.per_tcn_stack = per_tcn_stack
        self.repeat_tcn = repeat_tcn
        self.tcn_dilated_basic = tcn_dilated_basic
        self.tcn_with_embed = tcn_with_embed
        self.tcn_norm = tcn_norm
        self.dconv_norm = dconv_norm
        self.tcn_use_film = tcn_use_film
        self.causal = causal
        self.transpose_delay = transpose_delay

        # TCN module's
        temporal_input_dim = self.num_freq
        for stride, _ in self.stride:
            if temporal_input_dim % stride == 0:
                temporal_input_dim //= stride
            else:
                temporal_input_dim //= stride
                temporal_input_dim += 1

        temporal_input_dim *= self.channels[-1]  # extend by channel size

        if self.tcn_layer.lower() == "normal":
            tcn_cls = TCN
        elif self.tcn_layer.lower() == "gated":
            print("GatedTCN would ignore dconv_norm configuration.")
            tcn_cls = GatedTCN
        else:
            raise NameError

        assert per_tcn_stack == len(tcn_with_embed)
        self.tcn_list = nn.ModuleList()
        for _ in range(repeat_tcn):
            _tcn = []

            for i in range(per_tcn_stack):
                if tcn_with_embed[i]:
                    if self.tcn_layer.lower() == "normal":
                        _tcn.append(
                            tcn_cls(
                                temporal_input_dim,
                                tcn_dim,
                                kernel=tcn_kernel,
                                dilation=tcn_dilated_basic ** i,
                                emb_dim=embed_dim,
                                causal=causal,
                                tcn_norm=tcn_norm,
                                dconv_norm=dconv_norm,
                            )
                        )
                    else:
                        _tcn.append(
                            tcn_cls(
                                temporal_input_dim,
                                tcn_dim,
                                kernel=tcn_kernel,
                                dilation=tcn_dilated_basic ** i,
                                emb_dim=embed_dim,
                                causal=causal,
                                tcn_norm=tcn_norm,
                                use_film=tcn_use_film,
                            )
                        )
                else:
                    if self.tcn_layer.lower() == "normal":
                        _tcn.append(
                            tcn_cls(
                                temporal_input_dim,
                                tcn_dim,
                                kernel=tcn_kernel,
                                dilation=tcn_dilated_basic ** i,
                                emb_dim=0,
                                causal=causal,
                                tcn_norm=tcn_norm,
                                dconv_norm=dconv_norm,
                            )
                        )
                    else:
                        _tcn.append(
                            tcn_cls(
                                temporal_input_dim,
                                tcn_dim,
                                kernel=tcn_kernel,
                                dilation=tcn_dilated_basic ** i,
                                emb_dim=0,
                                causal=causal,
                                tcn_norm=tcn_norm,
                                use_film=False,
                            )
                        )

            self.tcn_list.append(nn.ModuleList(_tcn))

    def forward(
        self, x: torch.Tensor, dvec: Optional[torch.Tensor] = None
    ) -> torch.Tensor:
        """
        Args:
            x: input tensor shape [N, C, T]
            dvec: conditional tensor shape [N, C]

        Returns:
            output tensor has shape [N, C, T]
        """
        # normalize
        if self.embed_norm and dvec is not None:
            dvec = F.normalize(dvec, p=2, dim=1)

        if self.input_type.lower() == "ri":
            _re, _im = torch.chunk(x, 2, dim=-2)
            x = torch.stack([_re, _im], dim=1)  # [N, C, T] -> [N, 2, C, T]
        else:
            if x.dim() == 3:
                x = x.unsqueeze(1)  # [N, 1, C, T]

        skip = [x.clone()]

        # forward CNN-down layers
        for cnn_layer in self.cnn_down:
            x = cnn_layer(x)  # [N, ch, C, T]
            skip.append(x)

        # forward TCN block
        N_ori, ch, C_ori, T = x.shape
        x = x.reshape(N_ori, ch * C_ori, T)

        for r in range(self.repeat_tcn):
            for i in range(len(self.tcn_list[r])):
                if self.tcn_with_embed[i]:
                    x = self.tcn_list[r][i](x, dvec)
                else:
                    x = self.tcn_list[r][i](x)

        x = x.reshape(N_ori, ch, C_ori, T)

        # forward CNN-up layers
        for i, cnn_layer in enumerate(self.cnn_up):
            if self.skip_conv:
                x += self.skip_cnn[i](skip[-i - 1])
            else:
                x = torch.cat([x, skip[-i - 1]], dim=1)

            x = cnn_layer(x)
            if self.t_kernel != 1:
                if self.transpose_delay:
                    x = x[
                        ..., (self.t_kernel - 1) :
                    ]  # transpose-conv with t-kernel size would increase (t-1) length
                else:
                    x = x[
                        ..., : -(self.t_kernel - 1)
                    ]  # transpose-conv with t-kernel size would increase (t-1) length

        if self.input_type.lower() == "ri":
            _re = x[:, 0, :, :]
            _im = x[:, 1, :, :]
            x = torch.cat([_re, _im], dim=1)

        else:
            x = x.squeeze(1)  # [N, 1, C, T] -> [N, C, T]

        return x

    @property
    def get_args(self) -> Dict:
        return {
            "input_type": self.input_type,
            "input_dim": self.input_dim,
            "activation_type": self.activation_type,
            "norm_type": self.norm_type,
            "dropout": self.dropout,
            "channels": self.channels,
            "transpose_t_size": self.transpose_t_size,
            "transpose_delay": self.transpose_delay,
            "skip_conv": self.skip_conv,
            "kernel_t": self.kernel_t,
            "stride_t": self.stride_t,
            "dilation_t": self.dilation_t,
            "kernel_f": self.kernel_f,
            "stride_f": self.stride_f,
            "dilation_f": self.dilation_f,
            "delay": self.delay,
            "embed_dim": self.embed_dim,
            "embed_norm": self.embed_norm,
            "tcn_norm": self.tcn_norm,
            "dconv_norm": self.dconv_norm,
            "tcn_layer": self.tcn_layer,
            "tcn_dim": self.tcn_dim,
            "tcn_kernel": self.tcn_kernel,
            "tcn_dilated_basic": self.tcn_dilated_basic,
            "repeat_tcn": self.repeat_tcn,
            "per_tcn_stack": self.per_tcn_stack,
            "tcn_with_embed": self.tcn_with_embed,
            "tcn_use_film": self.tcn_use_film,
            "causal": self.causal,
        }

class UnetFsmn(Unet):
    """
    Improve temporal modeling ability by inserting a FSMN inside an Unet model.

    Args:
        embed_dim: Embedding feature dimension.
        embed_norm: If True, applies the 2-norm on the input embedding.
    """

    def __init__(
        self,
        embed_dim: int = 0,
        embed_norm: bool = False,
        input_type: str = "RI",
        input_dim: int = 512,
        activation_type: str = "PReLU",
        norm_type: str = "bN2d",
        dropout: float = 0.05,
        channels: Tuple = (1, 1, 8, 8, 16, 16),
        transpose_t_size: int = 2,
        transpose_delay: bool = False,
        skip_conv: bool = False,
        kernel_t: Tuple = (5, 1, 9, 1, 1),
        stride_t: Tuple = (1, 1, 1, 1, 1),
        dilation_t: Tuple = (1, 1, 1, 1, 1),
        kernel_f: Tuple = (1, 5, 1, 5, 1),
        stride_f: Tuple = (1, 4, 1, 4, 1),
        dilation_f: Tuple = (1, 1, 1, 1, 1),
        delay: Tuple = (0, 0, 1, 0, 0),
        fsmn_l_context: int = 3,
        fsmn_r_context: int = 0,
        fsmn_dim: int = 256,
        num_fsmn: int = 8,
        fsmn_with_embed: List = [1, 1, 1, 1, 1, 1, 1, 1],
        fsmn_norm: str = "gLN",
        use_film: bool = True,
    ):
        super().__init__(
            input_type,
            input_dim,
            activation_type,
            norm_type,
            dropout,
            channels,
            transpose_t_size,
            skip_conv,
            kernel_t,
            stride_t,
            dilation_t,
            kernel_f,
            stride_f,
            dilation_f,
            delay,
        )

        self.transpose_delay = transpose_delay
        self.embed_dim = embed_dim
        self.embed_norm = embed_norm
        self.fsmn_l_context = fsmn_l_context
        self.fsmn_r_context = fsmn_r_context
        self.fsmn_dim = fsmn_dim
        self.num_fsmn = num_fsmn
        self.fsmn_with_embed = fsmn_with_embed
        self.fsmn_norm = fsmn_norm
        self.use_film = use_film

        # FSMN module's
        temporal_input_dim = self.num_freq
        for stride, _ in self.stride:
            if temporal_input_dim % stride == 0:
                temporal_input_dim //= stride
            else:
                temporal_input_dim //= stride
                temporal_input_dim += 1

        temporal_input_dim *= self.channels[-1]  # extend by channel size

        assert num_fsmn == len(fsmn_with_embed)
        self.fsmn_list = nn.ModuleList()

        for i in range(num_fsmn):
            if fsmn_with_embed[i]:
                self.fsmn_list.append(
                    ConditionFSMN(
                        temporal_input_dim,
                        temporal_input_dim,
                        fsmn_dim,
                        embed_dim,
                        fsmn_l_context,
                        fsmn_r_context,
                        norm_type=fsmn_norm,
                        use_film=use_film,
                    )
                )

            else:
                self.fsmn_list.append(
                    FSMN(
                        temporal_input_dim,
                        temporal_input_dim,
                        fsmn_dim,
                        fsmn_l_context,
                        fsmn_r_context,
                        norm_type=fsmn_norm,
                    )
                )

    def forward(
        self, x: torch.Tensor, dvec: Optional[torch.Tensor] = None
    ) -> torch.Tensor:
        """
        Args:
            x: input tensor shape [N, C, T]
            dvec: conditional tensor shape [N, C]

        Returns:
            output tensor has shape [N, C, T]
        """
        # normalize
        if self.embed_norm and dvec is not None:
            dvec = F.normalize(dvec, p=2, dim=1)

        if self.input_type.lower() == "ri":
            _re, _im = torch.chunk(x, 2, dim=-2)
            x = torch.stack([_re, _im], dim=1)  # [N, C, T] -> [N, 2, C, T]
        else:
            if x.dim() == 3:
                x = x.unsqueeze(1)  # [N, 1, C, T]

        skip = [x.clone()]

        # forward CNN-down layers
        for cnn_layer in self.cnn_down:
            x = cnn_layer(x)  # [N, ch, C, T]
            skip.append(x)

        # forward FSMN block
        N_ori, ch, C_ori, T = x.shape
        x = x.reshape(N_ori, ch * C_ori, T)
        memory = None
        for i in range(len(self.fsmn_list)):
            if self.fsmn_with_embed[i]:
                x, memory = self.fsmn_list[i](x, dvec, memory)
            else:
                x, memory = self.fsmn_list[i](x, memory)

        x = x.reshape(N_ori, ch, C_ori, T)

        # forward CNN-up layers
        for i, cnn_layer in enumerate(self.cnn_up):
            if self.skip_conv:
                x += self.skip_cnn[i](skip[-i - 1])
            else:
                x = torch.cat([x, skip[-i - 1]], dim=1)

            x = cnn_layer(x)
            if self.t_kernel != 1:
                if self.transpose_delay:
                    x = x[
                        ..., (self.t_kernel - 1) :
                    ]  # transpose-conv with t-kernel size would increase (t-1) length
                else:
                    x = x[
                        ..., : -(self.t_kernel - 1)
                    ]  # transpose-conv with t-kernel size would increase (t-1) length

        if self.input_type.lower() == "ri":
            _re = x[:, 0, :, :]
            _im = x[:, 1, :, :]
            x = torch.cat([_re, _im], dim=1)

        else:
            x = x.squeeze(1)  # [N, 1, C, T] -> [N, C, T]

        return x

    @property
    def get_args(self) -> Dict:
        return {
            "input_type": self.input_type,
            "input_dim": self.input_dim,
            "activation_type": self.activation_type,
            "norm_type": self.norm_type,
            "dropout": self.dropout,
            "channels": self.channels,
            "transpose_t_size": self.transpose_t_size,
            "transpose_delay": self.transpose_delay,
            "skip_conv": self.skip_conv,
            "kernel_t": self.kernel_t,
            "stride_t": self.stride_t,
            "dilation_t": self.dilation_t,
            "kernel_f": self.kernel_f,
            "stride_f": self.stride_f,
            "dilation_f": self.dilation_f,
            "delay": self.delay,
            "embed_dim": self.embed_dim,
            "embed_norm": self.embed_norm,
            "fsmn_l_context": self.fsmn_l_context,
            "fsmn_r_context": self.fsmn_r_context,
            "fsmn_dim": self.fsmn_dim,
            "num_fsmn": self.num_fsmn,
            "fsmn_with_embed": self.fsmn_with_embed,
            "fsmn_norm": self.fsmn_norm,
            "use_film": self.use_film,
        }


from collections import deque
n, k = map(int, input().split())
graph = [[] * (k+1) for _ in range(k+1)]
gmap = [[] * (n+1) for _ in range(n+1)]
for i in range(1, n+1):
    arr = list(map(int, input().split()))
    gmap[i] = arr
    for j, m in zip(arr, range(1, n+1)):
        if j != 0:
            graph[j].append((i, m))
s, a, b = map(int, input().split())
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
graph.sort()
for k in range(s):
    print(k)
    for i in range(1, k+1):
        queue = deque()
        while graph[i]:
            queue.append(graph[i].pop())
            x, y = queue.popleft()
            for j in range(4):
                nx = x + dx[j]
                ny = y + dy[j]
                if nx <= 0 or ny <= 0 or nx > n or ny > n:
                    continue
                if gmap[nx][ny-1] == 0:
                    gmap[nx][ny-1] = i
                    queue.append((nx, ny))
        graph[i] = queue

print(gmap[a][b-1])


from stevedore import extension

class Extensions:
    """Lazy singleton container for stevedore extensions.

    Loads each namespace when requested for the first time.
    """

    _managers = {}

    def __init__(self):
        raise NotImplementedError()

    @classmethod
    def get(cls, namespace, name):
        manager = cls._managers.get(namespace)
        if manager is None:
            manager = cls._load_namespace(namespace)
        return manager[name].plugin

    @classmethod
    def _load_namespace(cls, namespace):
        manager = extension.ExtensionManager(namespace)
        cls._managers[namespace] = manager
        return manager


#!/usr/bin/env python

import robot
import time
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import json
import logging

def send_json(data):
	msg = {'action':data}
	msg = json.dumps(msg)
	return (msg)

def action(client, userdata, message):
	data = message.payload.decode()
	data = json.loads(data)
	data = data['action']
	print (data)
	if data == 'forward':
		print ('forward')
		robot.forward()
	elif data == 'stop':
		print ('stop')
		robot.stop()
	elif data == 'left':
		print ('left')
		robot.left()
	elif data == 'right':
		print ('right')
		robot.right()
	elif data == 'backward':
		print ('backward')
		robot.backward()
	elif data == 'servo left':
		print ('servo left')
		robot.servo_left()
	elif data == 'servo center':
		print ('servo center')
		robot.servo_center()
	elif data == 'servo right':
		print ('servo right')
		robot.servo_right()
	elif data == 'lights':
		print ('lights')
		robot.lights()
	elif data == 'blinkers':
		print ('blinkers')
		robot.blinkers()
	elif data == 'voltage':
		print('voltage')
		voltage = robot.voltage()
		voltage = send_json(voltage)
		myMQTT.publish('from_robot', voltage, 0)
	elif data == 'distance':
		print('distance')
		distance = robot.distance()
		distance = send_json(distance)
		myMQTT.publish('from_robot', distance, 0)
	else:
		pass

key_dir = '/home/pi/aaa_mikes_gopigo/keys/'

myMQTT = AWSIoTMQTTClient('Leonard')
myMQTT.configureEndpoint('a111amujev1y9r.iot.us-west-2.amazonaws.com', 8883)
myMQTT.configureCredentials(key_dir+'root-CA.crt', key_dir+'Leonard.private.key', key_dir+'Leonard.cert.pem')
myMQTT.configureOfflinePublishQueueing(-1)
myMQTT.configureDrainingFrequency(2)
myMQTT.configureConnectDisconnectTimeout(10)
myMQTT.connect()
myMQTT.subscribe('to_robot', 1, action)

logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)

print('Waiting for data...')

while True:
	pass


import pandas as pd
from datetime import datetime
import os

def get_csv(source):
    try:
        df = pd.read_csv('data/' + source + '.csv')
    except (OSError, IOError) as e:
        df = pd.DataFrame()
        print(e)
    return df;

def get_status(source_name):
    return '';

def set_status(source_name, status):
    return;

def get_data(source_name, meta_filter):
    df = get_csv(source_name)
    df = df[df['meta'].str.contains(meta_filter)]
    return df

def put_all_data(source_name, descr, df):
    local = get_csv(source_name)
    result = pd.concat([local, df]).drop_duplicates(['ref', 'date'])
    result = result.sort_values(by=['ref', 'date'])
    if not os.path.exists('data'):
        os.makedirs('data')
    result.to_csv('data/'+source_name+'.csv', columns=['ref', 'date', 'meta', 'value', 'file_date'], quoting=1, index=False)
    df['file_date'] = pd.to_datetime(df['file_date'])
    date = df['file_date'].max()
    date = date.today().replace(microsecond=0)
    lu = pd.DataFrame(data=[[source_name, date, 'None']], columns=['Name', 'Date', 'Status'])
    try:
        lu_new = pd.read_csv('data/last-update.csv')
    except (OSError, IOError) as e:
        lu_new = lu
    result = pd.concat([lu, lu_new]).drop_duplicates(['Name'])
    result.to_csv('data/last-update.csv', quoting=1, index=False)
    print(result)

def get_last_update(source_name, alternative_date):
    try:
        df = pd.read_csv('data/last-update.csv', index_col='Name')
    except (OSError, IOError) as e:
        return None
    if df.empty or source_name not in df.index:
        return alternative_date;
    date = df.get_value(source_name, "Date", takeable=False)
    return datetime.strptime(date, '%Y-%m-%d %H:%M:%S')


import cv2
import numpy as np
import glob
import uuid
import caffe
import skimage.io
from util import histogram_equalization
from scipy.ndimage import zoom
from skimage.transform import resize
import random
import cv2
import numpy as np
from matplotlib import pyplot as plt
import dlib
from project_face import frontalizer

IMAGE_WIDTH = 32
IMAGE_HEIGHT = 32

class mouth_detector():
    def __init__(self):
        self.PATH_face_model = '../lib/shape_predictor_68_face_landmarks.dat'
        self.face_cascade = cv2.CascadeClassifier('../lib/haarcascade/haarcascade_frontalface_default.xml')
        self.eye_cascade = cv2.CascadeClassifier('../lib/haarcascade/haarcascade_eye.xml')
        self.mouth_cascade = cv2.CascadeClassifier('../lib/haarcascade/mouth.xml')
        self.md_face = dlib.shape_predictor(self.PATH_face_model)
        self.fronter = frontalizer('../lib/ref3d.pkl')

    def mouth_detect_single(self,image,isPath):

        if isPath == True:
            img = cv2.imread(image, cv2.IMREAD_UNCHANGED)
        else:
            img = image

        img = histogram_equalization(img)
        gray_img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = self.face_cascade.detectMultiScale(gray_img1, 1.3, 5)

        for (x,y,w,h) in faces:
            roi_gray = gray_img1[y:y+h, x:x+w]
            eyes = self.eye_cascade.detectMultiScale(roi_gray)
            if(len(eyes)>0):
                p = x
                q = y
                r = w
                s = h
                face_region = gray_img1[q:q+s, p:p+r]
                face_region_rect = dlib.rectangle(long(q),long(p),long(q+s),long(p+r))
                rectan = dlib.rectangle(long(x),long(y),long(x+w),long(y+h))
                shape = self.md_face(img,rectan)
                p2d = np.asarray([(shape.part(n).x, shape.part(n).y,) for n in range(shape.num_parts)], np.float32)
                rawfront, symfront = self.fronter.frontalization(img,face_region_rect,p2d)
                face_hog_mouth = symfront[165:220, 130:190]
                gray_img = cv2.cvtColor(face_hog_mouth, cv2.COLOR_BGR2GRAY)
                crop_img_resized = cv2.resize(gray_img, (IMAGE_WIDTH, IMAGE_HEIGHT), interpolation = cv2.INTER_CUBIC)
                #cv2.imwrite("../img/output_test_img/mouthdetectsingle_crop_rezized.jpg",gray_img)
                return crop_img_resized,rectan.left(),rectan.top(),rectan.right(),rectan.bottom()
        else:
            return None,-1,-1,-1,-1

    def mouth_detect_bulk(self,input_folder,output_folder):

        transformed_data_set = [img for img in glob.glob(input_folder+"/*jpg")]

        for in_idx, img_path in enumerate(transformed_data_set):
            mouth,x,y,w,h = self.mouth_detect_single(img_path,True)
            if 'showingteeth' in img_path:
                guid = uuid.uuid4()
                uid_str = guid.urn
                str_guid = uid_str[9:]
                path = output_folder+"/"+str_guid+"_showingteeth.jpg"
                cv2.imwrite(path,mouth)
            else:
                guid = uuid.uuid4()
                uid_str = guid.urn
                str_guid = uid_str[9:]
                path = output_folder+"/"+str_guid+".jpg"
                cv2.imwrite(path,mouth)

    def negative_image(self,imagem):
        imagem = (255-imagem)
        return imagem

    def adaptative_threashold(self,input_img_path):
        img = cv2.imread(input_img_path,0)
        img = cv2.medianBlur(img,3)
        ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
        th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
                    cv2.THRESH_BINARY,11,2)
        th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
                    cv2.THRESH_BINARY,11,2)
        #cv2.imwrite("../img/output_test_img/hmouthdetectsingle_adaptative.jpg",th3)
        return th3


import re
import requests
from selenium import webdriver
from xvfbwrapper import Xvfb
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.common import exceptions

class YTGrabber:
    '''
    Класс принимает Youtube URL страниц, все плейлисты, плейлист и все видео,
    и возваращает все видеоматериалы данной страницы.
    '''
    driver = None
    vdisplay = None

    def _check_valid_url(self, url):

        if type(url) is int:
            raise TypeError("URL is not to be int type!")

        self.url = url.strip()

        if re.match(r"https://www\.youtube\.com/(playlist\?list=|channel/)[\w]+(/playlists|/videos)", self.url):
            return True

        if re.match(r"https://www\.youtube\.com/(playlist\?list=|channel/)[\w]+", self.url):
            return True

        raise ValueError("URL is not correct!")

    def _get_page(self, url):
        self._check_valid_url(url)

        resp = requests.get(self.url)

        if resp.text.find("404 Not Found") >= 0:
            raise ValueError("'{}' , страница не найдена либо не существует".format(self.url))

        if resp.text.find("Произошла ошибка! - YouTube") >= 0:
            raise ValueError("'{}' , Произошла ошибка! - YouTube".format(self.url))

        self.driver.get(self.url)

        return True

    def get_content(self, url):
        self._get_page(url)

        preload = True

        html = WebDriverWait(self.driver, 3).until(EC.presence_of_element_located((By.TAG_NAME , "html")), "Содержимое не найден или его нет !")

        while preload:
            html.send_keys(Keys.END)
            try:
                WebDriverWait(self.driver, 3).until(EC.presence_of_element_located((By.CSS_SELECTOR, "#contents #contents #continuations #spinner")))
            except:
                preload = False

        items = self.driver.find_elements(By.CSS_SELECTOR , "#contents #contents #items > *")

        if not items:
             items = self.driver.find_elements(By.CSS_SELECTOR , "#contents #contents #contents > *")

        if not items:
            raise ValueError("Содержимое не найден или его нет !")

        videos = []

        for item in items:
            videos.append({
                "title": item.find_element_by_id("video-title").get_attribute("title"),
                "href": item.find_element_by_id("video-title").get_attribute("href") or item.find_element_by_class_name("ytd-thumbnail").get_attribute("href"),
                "thumbnail": item.find_element_by_id("img").get_attribute("src"),
            })

        return videos

    def __enter__(self):
        self.vdisplay = Xvfb()
        self.vdisplay.start()

        options = webdriver.ChromeOptions()
        options.handless = False
        options.add_argument("--no-sandbox")
        options.add_argument("--disable-setuid-sandbox")

        self.driver = webdriver.Chrome(options=options, executable_path="driver/chromedriver")

        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.driver:
            self.driver.close()

        if self.vdisplay:
            self.vdisplay.stop()


import numpy as np
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QIcon, QColor
from PyQt5.QtWidgets import QListWidgetItem, QPushButton
from LGEprocess.flags_LGE import *
from skimage import exposure, img_as_float
import torch.utils.data as Datas
from LGEprocess import Network as Network
import nibabel as nib
import os
import torch
def Seg(img):
    print(img.shape)
    os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
    device = torch.device("cuda:0")
    print(torch.__version__)
    data=img
    dataloder = Datas.DataLoader(dataset=data, batch_size=1, shuffle=False)
    Segnet = Network.DenseBiasNet(n_channels=1, n_classes=4).to(device)

    pretrained_dict = torch.load('./model/net_epoch_source-Seg-Network.pkl', map_location='cpu')
    model_dict = Segnet.state_dict()
    pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
    model_dict.update(pretrained_dict)
    Segnet.load_state_dict(model_dict)

    with torch.no_grad():
        for epoch in range(1):
            for step, (img) in enumerate(dataloder):
                print(img.shape)
                img=img.to(device).float()
                print(img.shape)
                img=Segnet(img)
    img= img[0, 1, :, :, :] * 1 + img[0, 2, :, :, :] * 2 + img[0, 3, :, :, :] * 3
    img = img.data.cpu().numpy()
    print(img.shape)
    return img

def Reg(mov,fix):
    print(mov.shape)
    print(fix.shape)
    os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"

    device = torch.device("cuda:0")
    print(torch.__version__)
    data = mov,fix
    dataloder = Datas.DataLoader(dataset=data, batch_size=2, shuffle=False)
    Flownet = Network.VXm(2).to(device)
    ##
    pretrained_dict = torch.load('./model/net_epoch_source-Flow-Network.pkl')
    model_dict = Flownet.state_dict()
    pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
    model_dict.update(pretrained_dict)
    Flownet.load_state_dict(model_dict)

    with torch.no_grad():
        for epoch in range(1):
            for step, (mov,fix) in enumerate(dataloder):
                print(mov.shape)
                print(fix.shape)
                mov = mov.to(device).float()
                fix = fix.to(device).float()
                print(mov.shape)
                print(fix.shape)
                flow_field_x1, mov_fix, flow_field_x2, es_source = Flownet(fix, mov, fix)
                mov_fix = mov_fix[0, 0, :, :, :].data.cpu().numpy()
                print(mov_fix.shape)
                return mov_fix

def load_nii(path):
    image = nib.load(path)
    affine = image.affine
    image = np.asarray(image.dataobj)
    return image, affine

def normor(image):
    image -=image.mean()
    image /=image.std()
    return image

def crop_img(label_es, img, box_height=128, box_width=128):
    a = label_es.nonzero()
    a_x = a[0]
    a_x_middle = np.median(a[0])
    a_height = max((a_x)) - min((a_x)) + 1

    assert a_height < box_height, 'height小了'
    a_x_start = max(0,int(a_x_middle - box_height / 2))
    if(int(a_x_middle - box_height / 2)>=0):
        a_x_end = int(a_x_middle + box_height / 2)
    else:
        a_x_end=box_height
    print('axs',a_x_start)
    print('axe',a_x_end)
    print('x:',a_x_end-a_x_start)

    a_y = a[1]
    a_y_middle = np.median(a_y)
    a_width = max(a_y) - min(a_y) + 1
    # print(a_width,a_height)
    assert a_width < box_width, 'width小了'
    a_y_start = max(0,int(a_y_middle - box_width / 2))
    if(int(a_y_middle - box_width / 2)>=0):
        a_y_end = int(a_y_middle + box_width / 2)
    else:
        a_y_end=box_width

    img_1 = img[a_x_start:a_x_end, a_y_start:a_y_end, :]
    print('img1',img_1.shape)
    #plt.imshow(img_1[:,:,5], cmap='gray')
    return img_1

class MyItem_LGE(QListWidgetItem):
    def __init__(self, name=None, parent=None):
        super(MyItem_LGE, self).__init__(name, parent=parent)
        self.setIcon(QIcon('icons/color.png'))
        self.setSizeHint(QSize(60, 60))  # size
        print('MyItem_LGE')

    def get_params(self):
        protected = [v for v in dir(self) if v.startswith('_') and not v.startswith('__')]
        param = {}
        for v in protected:
            param[v.replace('_', '', 1)] = self.__getattribute__(v)
        return param

    def update_params(self, param):
        for k, v in param.items():
            if '_' + k in dir(self):
                self.__setattr__('_' + k, v)

class LabelItem(MyItem_LGE):
    def __init__(self, parent=None):
        super(LabelItem, self).__init__('添加GT', parent=parent)

    def __call__(self, label):
        # blank = np.zeros(img.shape, img.dtype)
        # img = cv2.addWeighted(img, self._alpha, blank, 1 - self._alpha, self._beta)
        return label

class NormItem(MyItem_LGE):
    def __init__(self, parent=None):
        super(NormItem, self).__init__('归一化', parent=parent)

    def __call__(self, img):
        max = img.max()
        min = img.min()
        img = (img - min) / (max - min)
        return img

class LightItem(MyItem_LGE):
    def __init__(self, parent=None):
        super(LightItem, self).__init__('亮度', parent=parent)
        self.alpha = 1

    def __call__(self, img):
        img = img_as_float(img)
        if (self.alpha <=1 & self.alpha >0):
            img = exposure.adjust_gamma(img, self.alpha)  # 图片调暗
        elif (self.alpha > 1):
            img = exposure.adjust_gamma(img, 0.5)  # 图片调亮
        else:
            print('请输入大于0的数字！')
        return img

class ROIItem(MyItem_LGE):
    def __init__(self, parent=None):
        super(ROIItem, self).__init__('ROI提取', parent=parent)

    def __call__(self, img):
        print(img.shape)
        label_path='./image/patient081_frame01_gt.nii.gz'
        label=nib.load(label_path).get_data()
        print(label.shape)
        img=crop_img(label_es=label,img=img,box_height=128,box_width=128)
        print(img.shape)

        return img

class RegItem(MyItem_LGE):
    def __init__(self, parent=None):
        super(RegItem, self).__init__('配准', parent=parent)

    def __call__(self, img):
        path='./image/_es.nii.gz'
        fix=nib.load(path).get_data()
        img = np.transpose(img, (2, 1, 0))  # xyz-zyx
        img = normor(img)
        img = img[np.newaxis, np.newaxis, :, :, :]
        fix = np.transpose(fix, (2, 1, 0))  # xyz-zyx
        fix = normor(fix)
        fix = fix[np.newaxis, np.newaxis, :, :, :]
        mov=img

        img=Reg(mov,fix)
        img = np.transpose(img, (2, 1, 0))  # zyx-xyz
        return img

class SegItem(MyItem_LGE):
    def __init__(self, parent=None):
        super(SegItem, self).__init__('分割', parent=parent)
    def __call__(self, img):
        img = np.transpose(img, (2, 1, 0))  # xyz-zyx
        img=normor(img)
        img = img[np.newaxis,np.newaxis, :, :, :]
        # print(img.shape)
        img=Seg(img)
        img=np.transpose(img,(2,1,0))#zyx-xyz
        print(img.shape)

        return img


from pymongo import MongoClient

from flask import Flask, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def hello():
    new_list = []
    client = MongoClient()
    db = client.variables
    variables = db.variables
    cursor = variables.find({})
    # print(variables)
    for doc in cursor:
        message = ''
        symbol = doc['symbol']
        fiveMinSuccess =  doc['values']["5MIN"]['success']
        fiveMinBlackX =  doc['values']["5MIN"]['black_x']
        fiveMinPrice =  doc['values']["5MIN"]['price']
        fiveMinMa =  doc['values']["5MIN"]['ma']

        fifteenMinSuccess = doc['values']["15MIN"]['success']
        fifteenMinBlackX = doc['values']["15MIN"]['black_x']
        fifteenMinPrice =  doc['values']["15MIN"]['price']
        fifteenMinMa =  doc['values']["15MIN"]['ma']

        oneHourSuccess = doc['values']["1HRS"]['success']
        oneHourBlackX = doc['values']["1HRS"]['black_x']
        oneHourPrice =  doc['values']["1HRS"]['price']
        oneHourMa =  doc['values']["1HRS"]['ma']

        fourHourSuccess = doc['values']["4HRS"]['success']
        fourHourBlackX = doc['values']["4HRS"]['black_x']
        fourHourPrice =  doc['values']["4HRS"]['price']
        fourHourMa =  doc['values']["4HRS"]['ma']

        oneDaySuccess = doc['values']["1DAY"]['success']
        oneDayBlackX = doc['values']["1DAY"]['black_x']
        oneDayPrice =  doc['values']["1DAY"]['price']
        oneDayMa =  doc['values']["1DAY"]['ma']

        new_dict = {"symbol": symbol, "fiveMin": f"{fiveMinSuccess}/{fiveMinBlackX}     {calculate_difference(fiveMinPrice, fiveMinMa)}", "fifteenMin": f"{fifteenMinSuccess}/{fifteenMinBlackX}  {calculate_difference(fifteenMinPrice, fifteenMinMa)}", "oneHour": f"{oneHourSuccess}/{oneHourBlackX}    {calculate_difference(oneHourPrice, oneHourMa)}", "fourHour": f"{fourHourSuccess}/{fourHourBlackX}   {calculate_difference(fourHourPrice, fourHourMa)}", "oneDay": f"{oneDaySuccess}/{oneDayBlackX}    {calculate_difference(oneDayPrice, oneDayMa)}"}
        new_list.append(new_dict)
        print(new_list)
    return jsonify(new_list)

def calculate_difference(price, ma) -> str:
    up = '↗'
    down = '↘'
    if price > ma:
        return up
    return down

app.run(debug=True)


import sqlite3
conn=sqlite3.connect("Stationary_inventt.db")
c = conn.cursor()
print(" database successful")
#using drop table to avoid duplicate copy
c.execute("DROP TABLE  IF EXISTS Stationery_stock")
c.execute("""
CREATE TABLE Stationery_stock(
ITEM_ID INTEGER,
ITEMS TEXT,
COST_PRICE INTEGER,
QUANTITY_IN_STOCK INTEGER
)
""")
print("table created successfully")
Avail_items = [
(1,"2b 60 leaves bks",600,10),
(2,"Staple pin",800,5),
(3,"Gum",1000,15),
(4,"Pencils",500,30),
(5,"A4 paper",5000,7),
(6,"Flexible Ruler",1500,22),
(7,"set square",4000,5),
(8,"Math set",2500,3),
(9,"Eraser",750,8),
(10,"Calculator",3000,10)
]
c.executemany("INSERT INTO Stationery_stock VALUES(?,?,?,?)",Avail_items)
#amount the business owner invested in the procurement of the items.
c.execute("SELECT SUM(COST_PRICE) FROM Stationery_stock" )
print(c.fetchall())
# average quantity of items in stock.
c.execute("SELECT AVG(QUANTITY_IN_STOCK) FROM Stationery_stock")
print(c.fetchall())
#item with the least quantity in stock
c.execute("SELECT ITEMS, MIN(QUANTITY_IN_STOCK) FROM Stationery_stock")
print(c.fetchall())
# item with the most quantity in stock
c.execute("SELECT ITEMS,MAX(QUANTITY_IN_STOCK) FROM Stationery_stock")
print(c.fetchall())

conn.commit()
conn.close()


# -*- coding: utf-8 -*-
"""
This is a prototype script.
"""
import numpy as np
from PIL import Image
from PIL import ImageEnhance
from scipy.ndimage import gaussian_filter
import cv2
from skimage import io as ip

frame_rate = 24 #output frame rate

vidcap = cv2.VideoCapture('video9.mov')
success,image = vidcap.read()
count = 1
print('Demuxing video')
while success:
  cv2.imwrite("frame%d.png" % count, image)     # save frame as JPEG file
  success,image = vidcap.read()
  count += 1

def initial_processing(iminit, low_val, max_val):
    img = Image.open(iminit)
    converter = ImageEnhance.Contrast(img)
    print(low_val)
    print(max_val)
    cont = (1/(max_val/low_val))*2.0
    img = converter.enhance(cont)
    array = np.array(img)
    ip.imsave('temp1.png', array)

def calc_val(im1):
    img = Image.open(im1)
    array = np.array(img)
    low_val = np.mean(array)
    max_val = np.amax(array)
    return low_val, max_val

def imadd(I, K):

    import numbers
    if isinstance(K, numbers.Number):
        J = I.astype('int32')
        J += K
    elif isinstance(K, np.ndarray):
        assert K.shape == I.shape, f'Cannot add images with sizes {I.shape} and {K.shape}.'
        J = I.astype('int32') + K.astype('int32')
    else:
        raise TypeError('K must be a number or an array.')

    np.clip(J, 0, 255, out=J)
    J = J.astype('uint8')
    return J

def gaussian_filt(I, sigma, pad=0):

    import numbers
    assert isinstance(pad, numbers.Number) or pad in ['reflect', 'nearest', 'wrap'], \
            'Choose a correct value for pad: a number (0-255), ''reflect'', ''nearest'', or ''wrap''.'

    if isinstance(pad, numbers.Number):
        md = 'constant'
        c = pad
    else:
        md = pad
        c = 0
    return gaussian_filter(I, sigma, mode=md, cval=c)

def final_processing(finalim, k):
    I = ip.imread(finalim)

    R = np.logical_and(I[:, :, 0] > 254, I[:, :, 1] < 255)

    new_R = gaussian_filt(255 * R, 5)

    J = I.copy()
    J[:, :, 0] = imadd(new_R, J[:, :, 0])

    ip.imsave('temp.png', J)
    img2 = Image.open('temp.png')
    converter = ImageEnhance.Color(img2)
    img2 = converter.enhance(1.4)
    im = np.array(img2)
    ip.imsave('final{}.png'.format(k), im)

def process_loop():
    for i in range(count):
        low_val, max_val=calc_val('frame{}.png'.format(i+1))
        print('Processing image {}'.format(i+1))
        initial_processing('frame{}.png'.format(i+1), low_val, max_val)
        final_processing('temp1.png', i+1)

def video_mux():
    print("Remuxing Files")
    pathOut = 'video_out.mp4'
    fps = frame_rate
    frame_array = []
    files = ['final{}.png'.format(i+1) for i in range(count)]
    for i in range(len(files)):
        #filename=pathIn + files[i]
        filename=files[i]
        #reading each files
        img = cv2.imread(filename)
        height, width, layers = img.shape
        size = (width,height)
        #inserting the frames into an image array
        frame_array.append(img)
    out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'H264'), fps, size)
    for i in range(len(frame_array)):
        # writing to a image array
        out.write(frame_array[i])
    out.release()
count = count-1
process_loop()
video_mux()