import math
from functools import partial
from collections import defaultdict

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from . import torchvision_models
from .torchvision_models import load_pretrained, inflate_pretrained, modify_resnets
from network.non_local_gaussian import NONLocalBlock3D

class STABlock(nn.Module):
    def __init__(self, in_channels, inter_channels=None):
        super(STABlock, self).__init__()

        self.in_channels = in_channels
        self.inter_channels = inter_channels

        if self.inter_channels is None:
            self.inter_channels = in_channels // 2
            if self.inter_channels == 0:
                self.inter_channels = 1

        # self.sa1 = nn.Conv3d(in_channels=self.in_channels, out_channels=128,
        #                  kernel_size=(1, 2, 2), stride=(1, 2, 2), padding=0) # 8, 14, 14
        # self.sa2 = nn.Conv3d(in_channels=128, out_channels=128,
        #                  kernel_size=(1, 2, 2), stride=(1, 2, 2), padding=0) # 8, 7, 7
        # self.sa3 = nn.Conv3d(in_channels=128, out_channels=128,
        #                  kernel_size=(1, 7, 7), stride=(1, 1, 1), padding=0) # 128, 8, 1, 1
        # self.sa4 = nn.Conv3d(in_channels=128, out_channels=1,
        #                  kernel_size=(1, 1, 1), stride=(1, 1, 1), padding=0) # 1, 8, 1, 1

        self.Qs = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.Ks = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.Vs = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.Ws = nn.Conv3d(in_channels=self.inter_channels, out_channels=self.in_channels,
                         kernel_size=1, stride=1, padding=0)

        self.Q = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.K = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.V = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.W = nn.Conv3d(in_channels=self.inter_channels, out_channels=self.in_channels,
                         kernel_size=1, stride=1, padding=0)

        nn.init.constant_(self.Q.weight, 0)
        nn.init.constant_(self.Q.bias, 0)
        nn.init.constant_(self.K.weight, 0)
        nn.init.constant_(self.K.bias, 0)
        nn.init.constant_(self.Qs.weight, 0)
        nn.init.constant_(self.Qs.bias, 0)
        nn.init.constant_(self.Ks.weight, 0)
        nn.init.constant_(self.Ks.bias, 0)

    def forward(self, x):
        '''
        :param x: (b, c, t, h, w)   (b, 64, t=16/2, 28, 28)
        :return:
        '''

        batch_size = x.size(0)
        t = x.size(2)
        h = x.size(3)
        w = x.size(4)
        c = self.inter_channels

        # Single Attention
        # x_sa = self.sa1(x)
        # x_sa = self.sa2(x_sa)
        # x_sa = self.sa3(x_sa)
        # x_sa = self.sa4(x_sa).view(batch_size, -1) #[batch, t]
        # x_sa = F.sigmoid(x_sa)
        # # print(x_sa)
        # x_sa = x_sa.unsqueeze(2).unsqueeze(3).unsqueeze(4) #[batch, t, 1, 1, 1]
        # x = x.permute(0, 2, 1, 3, 4)

        # x = x.mul(x_sa)
        # x = x.permute(0, 2, 1, 3, 4)

        # Spatiao Attention
        # Query
        Q_x_s = self.Qs(x).view(batch_size, t, -1)
        Q_x_s = Q_x_s.permute(0, 2, 1) # [chw x t]

        # Key
        K_x_s = self.Ks(x).view(batch_size, t, -1) # [t x chw]

        # Value
        V_x_s = self.Vs(x).view(batch_size, t, -1)
        V_x_s = V_x_s.permute(0, 2, 1) # [chw x t]

        corr_s = torch.matmul(Q_x_s, K_x_s) # [chw x chw]
        corr_s_div_C = F.softmax(corr_s / math.sqrt(t), dim=-1)

        ys = torch.matmul(corr_s_div_C, V_x_s)
        ys = ys.permute(0, 2, 1).contiguous()
        ys = ys.view(batch_size, self.inter_channels, *x.size()[2:])

        # Temporal Attention
        # Query
        Q_x_t = self.Q(x).view(batch_size, c*h*w, -1)
        Q_x_t = Q_x_t.permute(0, 2, 1) # [t x chw]

        # Key
        K_x_t = self.K(x).view(batch_size, c*h*w, -1) # [chw x t]

        # Value
        V_x_t = self.V(x).view(batch_size, c*h*w, -1)
        V_x_t = V_x_t.permute(0, 2, 1) # [t x chw]

        corr_t = torch.matmul(Q_x_t, K_x_t) # [t x t]
        corr_t_div_C = F.softmax(corr_t / math.sqrt(t), dim=-1)

        yt = torch.matmul(corr_t_div_C, V_x_t)
        yt = yt.permute(0, 2, 1).contiguous()
        yt = yt.view(batch_size, self.inter_channels, *x.size()[2:])

        y_combine = ys + yt

        W = self.W(y_combine)
        z = W + x

        return z

class TABlock(nn.Module):
    def __init__(self, in_channels, inter_channels=None):
        super(TABlock, self).__init__()

        self.in_channels = in_channels
        self.inter_channels = inter_channels

        if self.inter_channels is None:
            self.inter_channels = in_channels // 2
            if self.inter_channels == 0:
                self.inter_channels = 1

        # self.sa1 = nn.Conv3d(in_channels=self.in_channels, out_channels=128,
        #                  kernel_size=(1, 2, 2), stride=(1, 2, 2), padding=0) # 8, 14, 14
        # self.sa2 = nn.Conv3d(in_channels=128, out_channels=128,
        #                  kernel_size=(1, 2, 2), stride=(1, 2, 2), padding=0) # 8, 7, 7
        # self.sa3 = nn.Conv3d(in_channels=128, out_channels=128,
        #                  kernel_size=(1, 7, 7), stride=(1, 1, 1), padding=0) # 128, 8, 1, 1
        # self.sa4 = nn.Conv3d(in_channels=128, out_channels=1,
        #                  kernel_size=(1, 1, 1), stride=(1, 1, 1), padding=0) # 1, 8, 1, 1

        self.Q = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.K = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.V = nn.Conv3d(in_channels=self.in_channels, out_channels=self.inter_channels,
                         kernel_size=1, stride=1, padding=0)
        self.W = nn.Conv3d(in_channels=self.inter_channels, out_channels=self.in_channels,
                         kernel_size=1, stride=1, padding=0)

        nn.init.constant_(self.Q.weight, 0)
        nn.init.constant_(self.Q.bias, 0)
        nn.init.constant_(self.K.weight, 0)
        nn.init.constant_(self.K.bias, 0)

    def forward(self, x):
        '''
        :param x: (b, c, t, h, w)   (b, 64, t=16/2, 28, 28)
        :return:
        '''

        batch_size = x.size(0)
        t = x.size(2)
        h = x.size(3)
        w = x.size(4)
        c = self.inter_channels

        # Single Attention
        # x_sa = self.sa1(x)
        # x_sa = self.sa2(x_sa)
        # x_sa = self.sa3(x_sa)
        # x_sa = self.sa4(x_sa).view(batch_size, -1) #[batch, t]
        # x_sa = F.sigmoid(x_sa)
        # # print(x_sa)
        # x_sa = x_sa.unsqueeze(2).unsqueeze(3).unsqueeze(4) #[batch, t, 1, 1, 1]
        # x = x.permute(0, 2, 1, 3, 4)

        # x = x.mul(x_sa)
        # x = x.permute(0, 2, 1, 3, 4)

        # Temporal Attention
        # Query
        Q_x_t = self.Q(x).view(batch_size, c*h*w, -1)
        Q_x_t = Q_x_t.permute(0, 2, 1) # [t x chw]

        # Key
        K_x_t = self.K(x).view(batch_size, c*h*w, -1) # [chw x t]

        # Value
        V_x_t = self.V(x).view(batch_size, c*h*w, -1)
        V_x_t = V_x_t.permute(0, 2, 1) # [t x chw]

        corr_t = torch.matmul(Q_x_t, K_x_t) # [t x t]
        corr_t_div_C = F.softmax(corr_t / math.sqrt(h*w*c), dim=-1)

        yt = torch.matmul(corr_t_div_C, V_x_t)
        yt = yt.permute(0, 2, 1).contiguous()
        yt = yt.view(batch_size, self.inter_channels, *x.size()[2:])

        W = self.W(yt)
        z = W + x

        return z

__all__ = [
    'ResNet3D', 'resnet3d10', 'resnet3d18', 'resnet3d34',
    'resnet3d50', 'resnet3d101', 'resnet3d152', 'resnet3d200',
]

model_urls = {
    'kinetics-400': defaultdict(lambda: None, {
        'resnet3d18': 'http://pretorched-x.csail.mit.edu/models/resnet3d18_kinetics-e9f44270.pth',
        'resnet3d34': 'http://pretorched-x.csail.mit.edu/models/resnet3d34_kinetics-7fed38dd.pth',
        'resnet3d50': 'http://pretorched-x.csail.mit.edu/models/resnet3d50_kinetics-aad059c9.pth',
        'resnet3d101': 'http://pretorched-x.csail.mit.edu/models/resnet3d101_kinetics-8d4c9d63.pth',
        'resnet3d152': 'http://pretorched-x.csail.mit.edu/models/resnet3d152_kinetics-575c47e2.pth',
    }),
    'moments': defaultdict(lambda: None, {
        'resnet3d50': 'http://pretorched-x.csail.mit.edu/models/resnet3d50_16seg_moments-6eb53860.pth',
    }),
}

num_classes = {'kinetics-400': 400, 'moments': 339}

pretrained_settings = defaultdict(dict)
input_sizes = {}
means = {}
stds = {}

for model_name in __all__:
    input_sizes[model_name] = [3, 224, 224]
    means[model_name] = [0.485, 0.456, 0.406]
    stds[model_name] = [0.229, 0.224, 0.225]

for model_name in __all__:
    if model_name in ['ResNet3D']:
        continue
    for dataset, urls in model_urls.items():
        pretrained_settings[model_name][dataset] = {
            'input_space': 'RGB',
            'input_range': [0, 1],
            'url': urls[model_name],
            'std': stds[model_name],
            'mean': means[model_name],
            'num_classes': num_classes[dataset],
            'input_size': input_sizes[model_name],
        }

def conv3x3x3(in_planes, out_planes, stride=1):
    """3x3x3 convolution with padding."""
    return nn.Conv3d(
        in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=False
    )

def downsample_basic_block(x, planes, stride):
    out = F.avg_pool3d(x, kernel_size=1, stride=stride)
    zero_pads = torch.Tensor(
        out.size(0), planes - out.size(1),
        out.size(2), out.size(3), out.size(4)).zero_()
    if isinstance(out.data, torch.cuda.FloatTensor):
        zero_pads = zero_pads.cuda()
    out = Variable(torch.cat([out.data, zero_pads], dim=1))

    return out

class BasicBlock(nn.Module):
    expansion = 1
    Conv3d = staticmethod(conv3x3x3)

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = self.Conv3d(inplanes, planes, stride)
        self.bn1 = nn.BatchNorm3d(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = self.Conv3d(planes, planes)
        self.bn2 = nn.BatchNorm3d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)
        return out

class Bottleneck(nn.Module):
    expansion = 4
    Conv3d = nn.Conv3d

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = self.Conv3d(inplanes, planes, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm3d(planes)
        self.conv2 = self.Conv3d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn2 = nn.BatchNorm3d(planes)
        self.conv3 = self.Conv3d(planes, planes * 4, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm3d(planes * 4)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)
        return out

class ResNet3D(nn.Module):

    Conv3d = nn.Conv3d

    def __init__(self, block, layers, shortcut_type='B', num_classes=400):
        self.inplanes = 64
        super(ResNet3D, self).__init__()
        self.conv1 = self.Conv3d(3, 64, kernel_size=7, stride=(1, 2, 2), padding=(3, 3, 3), bias=False)
        self.bn1 = nn.BatchNorm3d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool3d(kernel_size=(3, 3, 3), stride=2, padding=1)

        # TAT
    #     self.tat_conv1 = self.Conv3d(64, 64, kernel_size=7, stride=(1, 2, 2), padding=(3, 3, 3), bias=False) #28x28x16
    #     self.tat_conv2 = self.Conv3d(64, 21, kernel_size=7, stride=(1, 2, 2), padding=(3, 3, 3), bias=False) #14x14x16
    #     self.tat_conv3 = self.Conv3d(21, 1, kernel_size=7, stride=(1, 2, 2), padding=(3, 3, 3), bias=False) #7x7x16
    #    # self.tat_conv4 = self.Conv3d(256, 1, kernel_size=1, stride=(1, 1, 1), padding=(0, 0, 0), bias=False) #7x7x16x1
    #     self.tat_pooling = nn.MaxPool3d(kernel_size=(1, 7, 7))
    #     self.tat_norm = nn.Sigmoid()

        #self.ta = TABlock(64, 64)
        self.layer1 = self._make_layer(block, 64, layers[0], shortcut_type)

        self.layer2 = self._make_layer(block, 128, layers[1], shortcut_type, stride=2)
        #self.nl_2 = NONLocalBlock3D(in_channels=128)

        self.layer3 = self._make_layer(block, 256, layers[2], shortcut_type, stride=2)
        #self.sta3 = STABlock(256,64)
        self.inplanes_tmp = self.inplanes
        self.layer4_v = self._make_layer(block, 512, layers[3], shortcut_type, stride=2)
        #self.nl_4_v = NONLocalBlock3D(in_channels=512)
        self.inplanes = self.inplanes_tmp
        self.layer4_a = self._make_layer(block, 512, layers[3], shortcut_type, stride=2)
        #self.nl_4_a = NONLocalBlock3D(in_channels=512)
        self.avgpool = nn.AdaptiveAvgPool3d(1)
        #self.fc_v = nn.Linear(512 * block.expansion, 1)
        #self.fc_a = nn.Linear(512 * block.expansion, 1)
        self.fc_v_cls = nn.Linear(512* block.expansion, 20)
        self.fc_a_cls = nn.Linear(512* block.expansion, 20)
        self.fc_expr = nn.Linear(512 * block.expansion * 2, 7)

        self.tanh = nn.Tanh()

        self.init_weights()

    def _make_layer(self, block, planes, blocks, shortcut_type, stride=1):
        downsample = None
        if stride != 1 or self.inplanes != planes * block.expansion:
            if shortcut_type == 'A':
                downsample = partial(
                    downsample_basic_block,
                    planes=planes * block.expansion,
                    stride=stride,
                )
            else:
                downsample = nn.Sequential(
                    self.Conv3d(
                        self.inplanes,
                        planes * block.expansion,
                        kernel_size=1,
                        stride=stride,
                        bias=False,
                    ),
                    nn.BatchNorm3d(planes * block.expansion),
                )

        layers = []
        layers.append(block(self.inplanes, planes, stride, downsample))
        self.inplanes = planes * block.expansion
        for _ in range(1, blocks):
            layers.append(block(self.inplanes, planes))

        return nn.Sequential(*layers)

    def init_weights(self):
        for m in self.modules():
            if isinstance(m, self.Conv3d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out')
            elif isinstance(m, nn.BatchNorm3d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x_v = self.layer3_v(x)
        x_a = self.layer3_a(x)

        x_v = self.layer4_v(x_v)
        x_a = self.layer4_a(x_a)

        x_v = self.avgpool(x_v)
        x_a = self.avgpool(x_a)

        x_v = x_v.view(x_v.size(0), -1)
        x_v = self.fc_v(x_v)

        x_a = x_a.view(x_a.size(0), -1)
        x_a = self.fc_a(x_a)

        x_expr = self.fc_expr(torch.cat((x_v, x_a),1))
        x_expr = self.fc_expr(x_expr)

        #return self.tanh(x[:,0:2]), x[:,2:9]
        return torch.cat((x_v, x_a), 1), x_expr

def get_fine_tuning_parameters(model, ft_begin_index):
    if ft_begin_index == 0:
        return model.parameters()

    ft_module_names = []
    for i in range(ft_begin_index, 5):
        ft_module_names.append('layer{}'.format(i))
    ft_module_names.append('fc')

    parameters = []
    for k, v in model.named_parameters():
        for ft_module in ft_module_names:
            if ft_module in k:
                parameters.append({'params': v})
                break
        else:
            parameters.append({'params': v, 'lr': 0.0})

    return parameters

def resnet3d10(**kwargs):
    """Constructs a ResNet3D-10 model."""
    model = ResNet3D(BasicBlock, [1, 1, 1, 1], **kwargs)
    model = modify_resnets(model)
    return model

def resnet3d18(num_classes=400, pretrained='kinetics-400', shortcut_type='A', **kwargs):
    """Constructs a ResNet3D-18 model."""
    model = ResNet3D(BasicBlock, [2, 2, 2, 2], num_classes=num_classes,
                     shortcut_type=shortcut_type, **kwargs)
    #pretrained = None
    if pretrained is not None:
        print("######## Pretrained #######")
        settings = pretrained_settings['resnet3d18'][pretrained]
        model = load_pretrained(model, num_classes, settings)
    else:
        print("######## NOT Pretrained #######")
    model = modify_resnets(model)
    return model

def resnet3d34(num_classes=400, pretrained='kinetics-400', shortcut_type='A', **kwargs):
    """Constructs a ResNet3D-34 model."""
    model = ResNet3D(BasicBlock, [3, 4, 6, 3], num_classes=num_classes,
                     shortcut_type=shortcut_type, **kwargs)
    if pretrained is not None:
        settings = pretrained_settings['resnet3d34'][pretrained]
        model = load_pretrained(model, num_classes, settings)
    model = modify_resnets(model)
    return model

def resnet3d50(num_classes=400, pretrained='kinetics-400', **kwargs):
    """Constructs a ResNet3D-50 model."""
    model = ResNet3D(Bottleneck, [3, 4, 6, 3], num_classes=num_classes, **kwargs)
    if pretrained is not None:
        settings = pretrained_settings['resnet3d50'][pretrained]
        model = load_pretrained(model, num_classes, settings)
    model = modify_resnets(model)
    return model

def resnet3d101(num_classes=400, pretrained='kinetics-400', **kwargs):
    """Constructs a ResNet3D-101 model."""
    model = ResNet3D(Bottleneck, [3, 4, 23, 3], num_classes=num_classes, **kwargs)
    if pretrained is not None:
        settings = pretrained_settings['resnet3d101'][pretrained]
        model = load_pretrained(model, num_classes, settings)
    model = modify_resnets(model)
    return model

def resnet3d152(num_classes=400, pretrained='kinetics-400', **kwargs):
    """Constructs a ResNet3D-152 model."""
    model = ResNet3D(Bottleneck, [3, 8, 36, 3], num_classes=num_classes, **kwargs)
    if pretrained is not None:
        settings = pretrained_settings['resnet3d152'][pretrained]
        model = load_pretrained(model, num_classes, settings)
    model = modify_resnets(model)
    return model

def resnet3d200(num_classes=400, pretrained='kinetics-400', **kwargs):
    """Constructs a ResNet3D-200 model."""
    model = ResNet3D(Bottleneck, [3, 24, 36, 3], **kwargs)
    if pretrained is not None:
        settings = pretrained_settings['resnet3d200'][pretrained]
        model = load_pretrained(model, num_classes, settings)
    model = modify_resnets(model)
    return model

def resneti3d50(num_classes=400, pretrained='moments', **kwargs):
    """Constructs a ResNet3D-50 model."""
    model = ResNet3D(Bottleneck, [3, 4, 6, 3], num_classes=num_classes, **kwargs)
    if pretrained is not None:
        settings = torchvision_models.pretrained_settings['resnet50'][pretrained]
        model = inflate_pretrained(model, num_classes, settings)
    model = modify_resnets(model)
    return model

if __name__ == '__main__':
    batch_size = 1
    num_frames = 48
    num_classes = 339
    img_feature_dim = 512
    frame_size = 224
    model = resnet3d50(num_classes=num_classes, pretrained='moments')

    input_var = torch.randn(batch_size, 3, num_frames, 224, 224)
    print(input_var.shape)
    output = model(input_var)
    print(output.shape)


from bs4 import BeautifulSoup
import csv

with open("carviewer2.html") as fp:
    soup = BeautifulSoup(fp, 'html.parser')

employee_file = open('week02data.csv', mode='w')
employee_writer = csv.writer(employee_file, delimiter=',', quotechar='"',  quoting=csv.QUOTE_MINIMAL)

rows = soup.findAll("tr")
#print(rows)
for row in rows:

    cols = row.findAll("td")[0:4]  #modify code so that update and delete is not outputted
    dataList = []
    for col in cols:
        dataList.append(col.text)
        #print(dataList)
    employee_writer.writerow(dataList)
employee_file.close()


import numpy as np
from sklearn.model_selection import StratifiedKFold, GridSearchCV
from sklearn.metrics import roc_auc_score
from sklearn import preprocessing

def runTuneTest(learner, parameters, X, y):
    """
    This method takes in a learning algorithm, the possible settings you would use for the algorithm and the full data set
    It performs cross-validation to tune the algorithm; that is, it creates held-aside data to determine which settings are best

    Returns the accuracy and model weights for each fold
    """

    outer_cv = StratifiedKFold(n_splits=5, shuffle=True)
    outer_cv = outer_cv.split(X,y)

    results = []
    fold = 0
    features = []
    #For each chunk (fold) created above, treat it as the held-aside test set and group the other four to train the model
    for train, test in outer_cv:
        fold += 1
        X_train, X_test =  X[train], X[test]
        y_train, y_test = y[train], y[test]
        clf = GridSearchCV(learner, parameters, cv=3)
        clf.fit(X_train, y_train)
        score = clf.score(X_test, y_test)
        results.append(score)
        #Use the code below instead if you want roc values
        #preds = clf.predict_proba(X_test)
        #results.append(roc_auc_score(y_test,preds[:,1]))
        try: # works for random forests or logistic regression
            features.append(clf.best_estimator_.coef_[0,:])
        except:
            features.append(clf.best_estimator_.feature_importances_)

    return results, features

def getGeneRanks(weights):
    """
    Takes the weights learned from an algorithm and sorts them by the most significant weights for predicting cancer tissue.  Returns an array of length numGenes, with the ith entry being the index of the ith most significant gene
    """
    rank_weights = []
    for w in weights:
        rank_weights.append(np.argsort(np.argsort(w)))
    feat_weights = np.average(rank_weights,axis=0)
    indices = np.argsort(feat_weights)
    return indices

def loadGeneExpression(filename, delim=","):
    """
    Parses a csv file containing gene expression data.  The format of the file
    should be one expression profile per line.

    Returns: 2D numpy array of size (numProfiles, numGenes)
    """

    rawdata = np.genfromtxt(filename,delimiter=delim)
    scaled = preprocessing.normalize(rawdata, norm='l2', axis=0)
    return scaled

def loadGeneNames(filename):
    """
    Reads the names of the genes in the expression profile.  There should be
    the same number of gene names as columns from loadGeneExpression

    Returns a 1D numpy array of length numGenes
    """
    with open(filename,'r') as f:
        genes = np.array([line.rstrip() for line in f])
    return genes

def loadLabels(filename):
    """
    Reads the labels (classifications) of each expression profile loaded from
    loadGeneExpression.  There should be on label per profile.  Negative values
    indicate cancer while positive indicate normal tissue

    Returns a 1D numpy array of length numProfiles
    """
    y = np.genfromtxt(filename)
    y = np.where(y>0,1,-1) #positive is normal
    return y


# -*- coding: utf-8 -*-
"""
Created on Wed Jul 18 23:04:53 2018
@author: Carla Pastor
Project: Heat Distribution.

"""
import numpy as np
import matplotlib.pyplot as lb
from matplotlib.colors import ListedColormap

if __name__ == "__main__":
    inp=int(input("Enter the starting temperature: "))

    oldTemp=np.zeros((inp+1, inp+1))

    for index in range(0,inp+1):
        oldTemp[index, 0]=inp
    temp=np.copy(oldTemp) #np.copy returns an array copy of the given object.

    #counter to count 3000 iterations and stop if program iterates more than 3000..
	#In the interest of time, I will stop at 3000 iterations if we don’t see convergence by then.
    c=0
    # while (True):
    while c!=3000:
        flag=False # go ahead and check. EXACTLY
        for i in range(1, inp):
            for j in range(1, inp):
                temp[i,j]=0.25*(oldTemp[i-1,j] + oldTemp[i+1,j] + oldTemp[i,j-1] + oldTemp[i,j+1]) #included in the hw specifications

                if np.array_equal(temp, oldTemp):  # True if two arrays have the same shape and elements, False otherwise.
                    flag=True
                    break

            if flag==True:
                break
        oldTemp=np.copy(temp)
        if flag==True:
            break
        #increment counter
        c=c+1
    #ref : https://stackoverflow.com/questions/44443993/matplotlib-colors-listedcolormap-in-python
    cmap = ListedColormap(['darkblue','blue','aqua','lawngreen','yellow','orange','red','darkred']) # invertidos. The colors are already included :/
                           #['#7D2C1B', '#DB5033', '#F4A718', '#FCEE14','#CBFE0D', '#0DFEDD', '#08C6E4', '#0A4751'] # my bad
    colors=[]
    split=inp/8.0 #divide the temperatures equally

    for i in range(8):
        colors.append(split)
        split+=split

    #Get the current Axes instance on the current figure matching the given keyword args, or create one.
    lb.gca().invert_yaxis()
    lb.imshow(oldTemp, cmap=cmap, origin='lower') #default: None. https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imshow.html
    lb.show()
#end
# Other references:
# https://www.programcreek.com/python/example/102329/matplotlib.pyplot.pcolormesh
# https://stackoverflow.com/questions/2051744/reverse-y-axis-in-pyplot


from airflow.models import BaseOperator
from airflow.utils.decorators import apply_defaults
from airflow.hooks.postgres_hook import PostgresHook

from warnings import warn

class CheckFutureYearsOperator(BaseOperator):
    """
    Checks number of observations in Postgres table with a year in the future

    :param postgres_conn_id: reference to a specific Postgres database
    :type postgres_conn_id: str
    :param postgres_table_name: name of Postgres table to check
    :type postgres_table_name: str
    """

    @apply_defaults
    def __init__(self,
                 postgres_conn_id,
                 postgres_table_name,
                 *args, **kwargs):

        super(CheckFutureYearsOperator, self).__init__(*args, **kwargs)
        self.postgres_conn_id = postgres_conn_id
        self.postgres_table_name = postgres_table_name

    def execute(self, context):

        postgres_hook = PostgresHook(self.postgres_conn_id)
        n_future_years = postgres_hook.get_records(
            f"""
            select count(*)
            from {self.postgres_table_name}
            where year > date_part('year', current_date);
            """
        )[0][0]

        # Output warning if there are observations with future years
        if n_future_years > 0:
            warn(
                f"""
                There are {n_future_years} observations in {self.postgres_table_name} table with year in the future
                """
            )


import os
import gspread

from gplus import ClientPlus

from datetime                       import datetime
from oauth2client.service_account   import ServiceAccountCredentials
from flask                          import Flask, render_template

application = Flask(__name__, static_url_path='/static')

CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))

credentials = ServiceAccountCredentials.from_json_keyfile_name( CURRENT_DIR + '/coastal.json',
                                                                 scopes = ['https://spreadsheets.google.com/feeds',
                                                                           'https://www.googleapis.com/auth/drive' ]
                                                              )

@application.route('/')
def index():
    """
    Landing page to be rendered. Get the latest spreadsheet from Google Drive
    and display it
    """
    client   = gspread.authorize(credentials, ClientPlus)
    calendar = client.open('Coastal Calendar')
    speakers = calendar.worksheet("Speakers")

    speaker_details = []
    for r, row in enumerate( speakers.get_all_values()):

        # Skip the header
        if r == 0:
            continue

        #https://drive.google.com/uc?export=view&id=1gi-Bj-WbFE82px-k3ZZXPFdEMNIwLEce
        photo_id  = client.get_file_id( row[2] )
        photo_url = 'https://drive.google.com/uc?export=view&id={}'.format(photo_id)

        day = datetime.strptime( row[0],"%m/%d/%Y" )
        speaker_details.append( { 'date'    :day.strftime( "%B %d, %Y" ),
                                  'name'    :row[1],
                                  'photo'   :photo_url,
                                  'url'     :row[3],
                                  'describe':row[4]
                              } )

    events   = calendar.worksheet('Events')
    event_details = []
    for r,row in enumerate( events.get_all_values()):

        # Skip the header
        if r == 0:
            continue

        day = datetime.strptime( row[0],"%m/%d/%Y" )
        event_details.append( { 'date'    :day.strftime( "%a %B %d, %Y" ),
                                'describe':row[1],
                                'place'   :row[2],
                                'notes'   :row[3]
                              } )

    context = {'speakers':speaker_details, 'events':event_details}

    return render_template( 'main.html', **context )

@application.errorhandler(404)
def page_not_found(e):
    """Return a custom 404 error."""
    return 'Sorry, Nothing at this URL {}'.format(e), 404

@application.errorhandler(500)
def application_error(e):
    """Return a custom 500 error."""
    return 'Sorry, unexpected error: {}'.format(e), 500

if __name__ == '__main__':
    application.run(debug = False, host='0.0.0.0', port=8000)


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

class discrete_policy_net(nn.Module):
    def __init__(self, input_dim, output_dim, hidden_dim=128):
        super(discrete_policy_net, self).__init__()
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.hidden_dim = hidden_dim

        self.fc1_layer = nn.Linear(self.input_dim, self.hidden_dim)
        self.fc2_layer = nn.Linear(self.hidden_dim, self.hidden_dim)
        self.fc3_layer = nn.Linear(self.hidden_dim, self.output_dim)

    def forward(self, input, explore=True, mask=None, log=False, reg=False, entropy=False, all=False):
        x = F.leaky_relu(self.fc1_layer(input))
        x = F.leaky_relu(self.fc2_layer(x))
        x = self.fc3_layer(x)
        res = []
        prob = F.softmax(x, dim=-1)
        if mask is not None:
            prob.masked_fill_(mask, value=0.0)
        if explore:
            action = torch.multinomial(prob, 1)
        else:
            action = prob.max(1, keepdim=True)[1]
        res = [action]
        if reg:
            reg_policy = torch.mean(x ** 2)
            res.append(reg_policy)
        if log:
            res.append(F.log_softmax(x, -1).gather(1, action))
        if entropy:
            res.append(-(F.log_softmax(x, dim=-1) * F.softmax(x, dim=-1)).sum(1).mean())
        if all:
            res.append(F.softmax(x, dim=-1))
        if len(res) > 1:
            return tuple(res)
        else:
            return res[0]


from discord import Embed
from discord.ext import commands
import discord

class ModerationCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command(aliases=['удалить'])
    @commands.has_role('Админ')
    async def clear(self, ctx, amount: int = None):
        await ctx.message.delete()
        if amount is None:
            await ctx.send('Укажите кол-во сообщений которые надо удалить', delete_after=10)
        else:
            await ctx.channel.purge(limit=amount)
            emb = discord.Embed(title='Удаление сообщений',
                                description=f'Админ {ctx.author.mention} почистил чат.')
            await ctx.send(embed=emb, delete_after=10)

    @commands.command(aliases=['добавить_роль'])
    @commands.has_role('Админ')
    async def add_role(self, ctx, member: discord.Member = None, role: discord.Role = None):
        logs = self.bot.get_channel(669129314251309056)
        await ctx.message.delete()
        if member == None:
            await ctx.send('Укажите кому дать роль', delete_after=10)
        elif role == None:
            await ctx.send('Укажите какую роль дать', delete_after=10)
        else:
            await member.add_roles(role)
            emb = discord.Embed(title='Выдача роли',
                                description=f'Админ {ctx.author.mention} дал роль {role} для {member.name}.')
            await logs.send(embed=emb)

    @commands.command(aliases=['бан'])
    @commands.has_role('Админ')
    async def ban(self, ctx, member: discord.Member = None, reason=None):
        logs = self.bot.get_channel(669129314251309056)
        await ctx.message.delete()
        if member is None:
            await ctx.send('Укажите кого надо забанить', delete_after=10)
        elif member is ctx.message.author:
            await ctx.send('Ты шо дурной, зачем банить самого себя?', delete_after=10)
        else:
            if reason is None:
                emb = discord.Embed(title='Бан', description=f'Админ {ctx.author.mention} забанил пользователя {member}.')
                await logs.send(embed=emb)
                try:
                    await member.send(f'Вас забанили на сервере {ctx.guild.name}')
                except Exception:
                    print('Ошибочка: Кажется я не могу писать в личку')
                finally:
                    await ctx.guild.ban(member)
            elif reason is not None:
                emb = discord.Embed(title='Бан', description=f'Админ {ctx.author.mention} забанил пользователя {member} по причине {reason}.')
                await logs.send(embed=emb)
                try:
                    await member.send(f'Вас забанили на сервере {ctx.guild.name} по причине {reason}.')
                except Exception:
                    print('Ошибочка: Кажется я не могу писать в личку')
                finally:
                    await ctx.guild.ban(member, reason=reason)

    @commands.command(aliases=['мут'])
    @commands.has_role('Админ')
    async def mute(self, ctx, member: discord.Member = None):
        logs = self.bot.get_channel(669129314251309056)
        await ctx.message.delete()
        if member == None:
            await ctx.send('Укажите кого надо замутить', delete_after=10)
        elif member == ctx.message.author:
            await ctx.send("Ты шо дурной, зачем мутить самого себя?", delete_after=10)
        else:
            emb = discord.Embed(title="Мут", description=f'Админ {ctx.author.mention} замутил пользователя {member}')
            role = discord.utils.get(ctx.message.guild.roles, name='Mute')
            await member.add_roles(role)
            await logs.send(embed=emb)

    @commands.command(aliases=['анмут'])
    @commands.has_role('Админ')
    async def unmute(self, ctx, member: discord.Member = None):
        logs = self.bot.get_channel(669129314251309056)
        await ctx.message.delete()
        if member == None:
            ctx.send("Укажите кого надо размутить", delete_after=10)
        else:
            emb = discord.Embed(title="Анмут", description=f'Админ {ctx.author.mention} размутил пользователя {member}')
            role = discord.utils.get(ctx.message.guild.roles, name="Mute")
            await member.remove_roles(role)
            await logs.send(embed=emb)

def setup(bot):
    bot.add_cog(ModerationCog(bot))


import subprocess

from django.conf import settings
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = "Запуск парсера офисных документов."

    def handle(self, *args, **options):
        run_parser = subprocess.getoutput(
            f'poetry run parser -r -p {settings.RESOURSES_ROOT}'
        )
        with open(
            f'{settings.RESOURSES_ROOT}/result.txt',
            'w',
            encoding='utf-8',
        ) as file:
            print(run_parser)
            file.write(run_parser)


from django.template import loader, RequestContext
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound, Http404
from django.conf import settings
from django.utils.safestring import mark_safe
from django.contrib.auth.views import redirect_to_login
from django import forms
from django.views.generic.edit import FormView
from django.views.generic import ListView

import os

from .models import Page, Attachment

DEFAULT_TEMPLATE = 'pages/default.html'

def page(request, url='/'):
    """
    Flat page view.

    Models: `pages.page`
    Templates: Uses the template defined by the ``template_name`` field,
        or `pages/default.html` if template_name is not defined.
    Context:
        page
            `pages.page` object
    """
    if not url.endswith('/') and settings.APPEND_SLASH:
        return HttpResponseRedirect("%s/" % request.path)
    if not url.startswith('/'):
        url = "/" + url
    # here I've removed the requirement that the page be for this site
    # - this won't work if we ever have more than one site here
    # which isn't planned

    # deal with the lack of a root page
    try:
        f = Page.objects.get(url__exact=url)
    except:
        # no page, if we're after the root page then serve a default page
        if url == '/':

            f = Page(title='No Pages',
                     content='
No pages defined. Login to admin to create some.
')
        else:
            raise Http404("Page does not exist")

    # If registration is required for accessing this page check the group
    if f.group_required:
        if request.user.is_authenticated:
            if not request.user.groups.filter(name=f.group_required.name).count():
                f = Page(title='Permission denied',
                         content='
You do not have permission to access this page. This page is only available to users with the permission level of ' + f.group_required.name.lower() + '. If you believe you should have access to this page please send us feedback.
')
        else:
            # Not logged in, redirect to the login page.
            return redirect_to_login(request.path)

    if f.template_name:
        t = loader.select_template((f.template_name, DEFAULT_TEMPLATE))
    else:
        t = loader.get_template(DEFAULT_TEMPLATE)

    # To avoid having to always use the "|safe" filter in flatpage templates,
    # mark the title and content as already safe (since they are raw HTML
    # content in the first place).
    f.title = mark_safe(f.title)
    f.content = mark_safe(f.content)

    response = HttpResponse(t.render({'page': f}, request))
    return response

class UploadFileForm(forms.Form):
    file  = forms.FileField()
    description = forms.CharField()

class AttachmentView(ListView):

    template_name = "pages/attachments.html"
    model = Attachment

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["form"] = UploadFileForm
        return context

    def handle_file(self, request, fileobj):
        """Store the uploaded file"""

        fullpath = os.path.join(settings.UPLOAD_ROOT, "attachments", fileobj.name)
        relname =  os.path.join(settings.UPLOAD_URL, "attachments", fileobj.name)
        if not os.path.exists(os.path.dirname(fullpath)):
            os.makedirs(os.path.dirname(fullpath))

        with open(fullpath, 'wb+') as destination:
            for chunk in fileobj.chunks():
                destination.write(chunk)

        # create and save a new attachment object
        a = Attachment(file=relname, description=request.POST['description'], uploader=request.user)
        a.save()

        return relname

    def post(self, request):
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            destname = self.handle_file(request, request.FILES['file'])
        else:
            print("invalid form", form)
        return HttpResponseRedirect('/pages/attachments')


import pinocchio as pin
import numpy as np

class NLinkCartpole(object):
  def __init__(self, N, link_length, link_mass):
    self.N = N
    self.pin_model = pin.Model()
    # Add the cart joint (prismatic joint along x axis)
    jidx = 0
    joint_model = pin.JointModelPrismaticUnaligned()
    joint_model.axis[0] = 1
    joint_model.axis[1] = 0
    joint_model.axis[2] = 0
    jidx = self.pin_model.addJoint(jidx, joint_model, pin.SE3.Identity(), 'cart_joint')

    # Add cart link
    inertia = pin.Inertia.FromBox(link_mass, link_length, link_length, link_length)
    link_se3 = pin.SE3.Identity()
    self.pin_model.appendBodyToJoint(jidx, inertia, link_se3)
    self.pin_model.addBodyFrame('cart_link', jidx, link_se3, -1)

    # Add the additional revolute joints
    for i in range(N):
      joint_se3 = pin.SE3.Identity()

      if i != 0:
        joint_se3.translation[2] = link_length

      if i == 0:
        # The joint rotates about its x axis. Align the joint's x axis with the global y axis
        joint_se3.rotation = pin.exp3(np.array([0, 0, -np.pi/2]))

      joint_model = pin.JointModelRevoluteUnaligned()
      joint_model.axis[0] = 1
      joint_model.axis[1] = 0
      joint_model.axis[2] = 0
      jidx = self.pin_model.addJoint(jidx, joint_model, joint_se3, 'cart_joint')

      # Add link
      inertia = pin.Inertia.FromCylinder(link_mass, 0.05, link_length)
      link_se3 = pin.SE3.Identity()
      link_se3.translation[2] = link_length/2
      self.pin_model.appendBodyToJoint(jidx, inertia, link_se3)
      self.pin_model.addBodyFrame('pole_link' + str(i), jidx, link_se3, -1)

    self.pin_data = pin.Data(self.pin_model)
    self.nq = self.pin_model.nq
    self.nv = self.pin_model.nv
    self.nx = self.nq + self.nv
    self.nu = self.pin_model.nv - 1

  def get_dim(self):
    return self.nx, self.nu

  def unpack(self, x, u):
    q = x[:self.nq]
    v = x[self.nq:]
    tau = np.zeros(self.nv)
    tau[:-1] = u
    return q, v, tau

  # u actuates the cart, and all revolute joints except the last (top) one
  def dynamics(self, x, u):
    q, v, tau = self.unpack(x, u)

    xdot = np.zeros(self.nq + self.nv)
    xdot[:self.nq] = np.copy(v)
    xdot[self.nv:] = pin.aba(self.pin_model, self.pin_data, q, v, tau)

    return xdot

  def lin_dynamics(self, x, u):
    q, v, tau = self.unpack(x, u)

    A = np.zeros((2*self.nv, 2*self.nv))
    B = np.zeros((2*self.nv, self.nu))

    dtau_du = np.zeros((self.nv, self.nu))
    dtau_du[:-1] = np.eye(self.nu)

    A[:self.nv, self.nv:] = np.eye(self.nv)

    pin.computeABADerivatives(self.pin_model, self.pin_data, q, v, tau)
    A[self.nv:, :self.nv] = self.pin_data.ddq_dq
    A[self.nv:, self.nv:] = self.pin_data.ddq_dv
    B[self.nv:] = self.pin_data.Minv@dtau_du

    return A, B


#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
@FILE      : Month6_general_analysis.py
@TIME      : 2023/07/20 22:34:20
@AUTHOR    : wangyu / NMC
@VERSION   : 1.0
@DESC      : 本文件负责进行 2023年 6 月 华北地区高温事件的基础统计分析
             华北地区 6 月份高温事件集中在 6月14-17日, 6月21-30日

'''

### to import parent dir files ###
# import os, sys
### this is for jupyter notebook ###
#current_folder = globals()['_dh'][0]
#parentdir = os.path.dirname(current_folder
### this is for normal python file ###
#parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#sys.path.insert(0,parentdir)

from datetime import datetime, timedelta
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import cv2
import geopandas as gpd

from utils import common_func as cf
from utils import DataIO as DIO
from utils import draw_pictures as DP

def draw_daily_max_temperature_stat(fn_t2m_stat,  fn_daily_tmax, fn_png, idate_lst, nor, sou, wst, est, dlon, dlat):
    """
    """

def draw_daily_max_temperature(fn_t2m_grd, fn_tmx24_stat, fn_daily_tmax, fn_png, idate_lst, nor, sou, wst, est, dlon, dlat):
    """
    首先绘制华北地区 日2m最高温度 的空间分布
    这里日最高温度，比较 当日 12时 ~ 20时 温度
    华北地区:  nor, sou, wst, est = 45, 30, 110, 125

    温度数据使用 ERA-5 tmax 数据
    # Maximum 2m temperature since previous post-processing
    #   defined as:
    #   This parameter is the highest temperature of air at 2m above the
    #   surface of land, sea or inland water since the parameter was last
    #   archived in a particular forecast. 2m temperature is calculated by
    #   interpolating between the lowest model level and the Earth's
    #   surface, taking account of the atmospheric conditions. This
    #   parameter has units of kelvin (K). Temperature measured in kelvin
    #   can be converted to degrees Celsius (°C) by subtracting 273.15.
    """
    ### create daily tmx24 file
    # 通过求取 当日 12H~20H(LST) 的小时最高温度的最大值，获取网格点的日最高温度
    ifn_tmx_1h = fn_t2m_grd.format(t=idate_lst)
    bvld, tmx_1h, lons, lats = DIO.readNC(ifn_tmx_1h, 'mx2t', 'longitue', 'latitude',
                                          nor=nor, sou=sou, wst=wst, est=est, dlon=dlon, dlat=dlat)
    if not bvld:
        return None

    nrows = int((nor-sou)/dlat + 1.5)
    ncols = int((est-wst)/dlon + 1.5)
    tmx_daily = np.max(tmx_1h[12-8:21-8, :, :], axis=0)-273.15
    cnts_lonlat = daily_heatwave_detect(tmx_daily)

    ifn_tmx_daily = fn_daily_tmax.format(t=idate_lst)
    DIO.writeNC(ifn_tmx_daily, tmx_daily, lons, lats, 'mx2t', 'longitude', 'latitude')

    ### load station data
    ifn_tmx24_stat = fn_tmx24_stat.format(t=idate_lst)
    nrows = int((nor-sou)/dlat + 1.5)
    ncols = int((est-wst)/dlon + 1.5)
    dst_lonlat = {
        "nor": nor,
        "sou": sou,
        "wst": wst,
        "est": est,
        "dlon": dlon,
        "dlat": dlat,
        "nrows": nrows,
        "ncols": ncols,
        "ngrids": nrows*ncols
    }
    ifn_png = fn_png.format(t=idate_lst.replace(hour=20))
    _, stat_data = DIO.load_m3(ifn_tmx24_stat, dst_latlon_dict=dst_lonlat, encoding='gbk')
    stat_data = stat_data[stat_data["val"]>=35]

    #####################
    ### draw pictures ###

    tmax = np.max(tmx_daily)
    tmin = np.min(tmx_daily)
    clvls = np.arange(np.floor(tmin), np.ceil(tmax+1), 1)
    titles_left = {
        'left':     'Date: {t:%Y/%m/%d}'.format(t=idate_lst),
        'right':    'ERA5 Daily TMX24: %.2f ℃' % (tmax)
    }
    titles_right = {
        'right':    'Station Daily TMX24: %.2f ℃' % (np.max(stat_data["val"].values))
    }
    #DP.show_2D_mat(tmx_daily, lons, lats, ifn_png, False, clvls=clvls, cmap=mpl.colormaps['seismic'], titles=titles,
    #               contours_lonlat=cnts_lonlat)
    DP.show_2D_mat_2pic_with_obs(dmat1=tmx_daily, lons1=lons, lats1=lats, clvls1=clvls, cmap1=mpl.colormaps['seismic'], title1=titles_left, contours_lonlat1=cnts_lonlat,
                                 lons2=lons, lats2=lats, obs2=stat_data, obs2_cmap=mpl.colormaps['Reds'], title2=titles_right, contours_lonlat2=cnts_lonlat,
                                 archive_fn=ifn_png, )

def daily_heatwave_detect(dmat, thresh=35.0):
    """
    基于当日的 日最高温度数据，识别 heat wave
    返回值为 [[lon, lat], [lon, lat], ... ]组成的 list
    """

    # 使用阈值法制作 >35° 掩膜
    _, masked_mat = cv2.threshold(dmat, thresh, 255, cv2.THRESH_BINARY)
    kernel = np.ones((3, 3), np.uint8)
    masked_mat = cv2.morphologyEx(masked_mat.astype(np.uint8), cv2.MORPH_OPEN, kernel, iterations=1)
    contours, hierarchy = cv2.findContours(masked_mat, mode=cv2.RETR_EXTERNAL,
                                           method=cv2.CHAIN_APPROX_SIMPLE)

    cnts_lonlat = cf.trans_cvContours_to_lonlat(contours, wst, sou, dlon, dlat)

    return cnts_lonlat

def heatwave_co_pair():
    """
    不同日数据识别出的 > 35℃ heatwave 之间进行配对
    构建一次 heat wave 事件
    """

if __name__ == "__main__":
    fn_tmx01_grd = 'y:/ERA5_T2MX/{t:%Y/%Y%m%d}.nc'
    fn_daily_tmax = 'y:/TMP/Huabei_Daily_TMax/{t:%Y%m%d}.nc'
    fn_tmx24_stat = 'z:/YLRC_STATION/TEMP/rtmx24/{t:%Y/%Y%m%d%H}.000'
    fn_png = 'f:/华北地区热浪分析/T2Max/{t:%Y%m%d}.png'
    #nor, sou, wst, est = 47, 28, 108, 127
    nor, sou, wst, est = 60, 10, 70, 140
    dlon, dlat = 0.25, 0.25

    idate = datetime(2023, 6, 1)
    date_end = datetime(2023, 6, 1)

    # step 1.
    while idate <= date_end:
        draw_daily_max_temperature(fn_tmx01_grd, fn_tmx24_stat, fn_daily_tmax, fn_png, idate, nor, sou, wst, est, dlon, dlat)
        idate += timedelta(days=1)


from flask import Flask
from pymongo import MongoClient
import json

client = MongoClient()
db = client.devdb
collection = db.jobs

# reads json file, returns data as python dict
def load_data():
    with open("./app/data.json", "r") as file:
        data = json.load(file) # gets python dict
    return data

# insert data if not already inserted
if collection.count_documents({}) == 0:
    data = load_data()
    result = collection.insert_many(data)
    print ("total inserted:", len(result.inserted_ids))

# make job application Flask object
jobapp = Flask(__name__, static_url_path='/static')

import app.routes as routes


# -*- coding:utf-8 -*-
import multiprocessing
import os

_debug = os.environ.get('DJANGO_SETTINGS_MODULE', 'karelapan.settings').endswith('dev')

bind = "unix:/tmp/gunicorn.sock"
#bind = "127.0.0.1:8000"
workers = multiprocessing.cpu_count() * 2 + 1
preload_app = True
daemon = not _debug
pidfile = os.path.normpath(os.path.join(os.path.dirname(__file__), 'gunicorn.pid'))
accesslog = os.path.normpath(os.path.join(os.path.dirname(__file__), 'access.log'))
errorlog = os.path.normpath(os.path.join(os.path.dirname(__file__), 'error.log'))
loglevel = 'info'


import os
import unittest
from pathlib import Path

import numpy as np
from pkg_resources import resource_filename

from compliance_checker.acdd import ACDDBaseCheck
from compliance_checker.base import BaseCheck, GenericFile, Result
from compliance_checker.suite import CheckSuite

static_files = {
    "2dim": resource_filename("compliance_checker", "tests/data/2dim-grid.nc"),
    "bad_region": resource_filename("compliance_checker", "tests/data/bad_region.nc"),
    "bad_data_type": resource_filename(
        "compliance_checker",
        "tests/data/bad_data_type.nc",
    ),
    "test_cdl": resource_filename("compliance_checker", "tests/data/test_cdl.cdl"),
    "test_cdl_nc": resource_filename(
        "compliance_checker",
        "tests/data/test_cdl_nc_file.nc",
    ),
    "empty": resource_filename("compliance_checker", "tests/data/non-comp/empty.file"),
    "ru07": resource_filename(
        "compliance_checker",
        "tests/data/ru07-20130824T170228_rt0.nc",
    ),
    "netCDF4": resource_filename(
        "compliance_checker",
        "tests/data/test_cdl_nc4_file.cdl",
    ),
}

class TestSuite(unittest.TestCase):
    # @see
    # http://www.saltycrane.com/blog/2012/07/how-prevent-nose-unittest-using-docstring-when-verbosity-2/

    def setUp(self):
        self.cs = CheckSuite()
        self.cs.load_all_available_checkers()

    def shortDescription(self):
        return None

    # override __str__ and __repr__ behavior to show a copy-pastable nosetest name for ion tests
    #  ion.module:TestClassName.test_function_name
    def __repr__(self):
        name = self.id()
        name = name.split(".")
        if name[0] not in ["ion", "pyon"]:
            return "{} ({})".format(name[-1], ".".join(name[:-1]))
        else:
            return "{} ( {} )".format(
                name[-1],
                ".".join(name[:-2]) + ":" + ".".join(name[-2:]),
            )

    __str__ = __repr__

    def test_suite(self):
        # BWA: what's the purpose of this test?  Just to see if the suite
        # runs without errors?
        ds = self.cs.load_dataset(static_files["2dim"])
        self.cs.run(ds, [], "acdd")

    def test_suite_pathlib(self):
        path_obj = Path(static_files["2dim"])
        ds = self.cs.load_dataset(path_obj)
        self.cs.run(ds, [], "acdd")

    def test_unicode_formatting(self):
        ds = self.cs.load_dataset(static_files["bad_region"])
        score_groups = self.cs.run(ds, [], "cf")

        limit = 2
        for checker, rpair in score_groups.items():
            groups, errors = rpair
            score_list, points, out_of = self.cs.standard_output(
                ds.filepath(),
                limit,
                checker,
                groups,
            )
            # This asserts that print is able to generate all of the unicode
            # output
            self.cs.standard_output_generation(groups, limit, points, out_of, checker)

    def test_generate_dataset_netCDF4(self):
        """
        Tests that suite.generate_dataset works with cdl file with netCDF4
        features.
        """
        # create netCDF4 file
        ds_name = self.cs.generate_dataset(static_files["netCDF4"])
        # check if correct name is return
        assert ds_name == static_files["netCDF4"].replace(".cdl", ".nc")
        # check if netCDF4 file was created
        assert os.path.isfile(static_files["netCDF4"].replace(".cdl", ".nc"))

    def test_include_checks(self):
        ds = self.cs.load_dataset(static_files["bad_data_type"])
        score_groups = self.cs.run_all(ds, ["cf:1.7"], ["check_standard_name"])
        checks_run = score_groups["cf:1.7"][0]
        assert len(checks_run) == 1
        first_check = checks_run[0]
        assert first_check.name == "§3.3 Standard Name"
        assert first_check.value[0] < first_check.value[1]

    def test_skip_checks(self):
        """Tests that checks are properly skipped when specified"""
        ds = self.cs.load_dataset(static_files["2dim"])
        # exclude title from the check attributes
        score_groups = self.cs.run_all(ds, ["acdd"], skip_checks=["check_high"])
        msg_set = {
            msg
            for sg in score_groups["acdd"][0]
            for msg in sg.msgs
            if sg.weight == BaseCheck.HIGH
        }
        skipped_messages = {
            att + " not present" for att in ACDDBaseCheck().high_rec_atts
        }
        # none of the skipped messages should be in the result set
        self.assertTrue(len(msg_set & skipped_messages) == 0)

    def test_skip_check_level(self):
        """Checks level limited skip checks"""
        ds = self.cs.load_dataset(static_files["ru07"])
        score_groups = self.cs.run_all(
            ds,
            ["cf"],
            skip_checks=[
                "check_flags:A",
                "check_convention_possibly_var_attrs:M",
                "check_standard_name:L",
            ],
        )

        name_set = {sg.name for sg in score_groups["cf"][0]}
        # flattened set of messages
        msg_set = {msg for sg in score_groups["cf"][0] for msg in sg.msgs}

        expected_excluded_names = {
            "§3.5 flag_meanings for lat",
            "§3.5 flag_meanings for lon",
            "§3.5 lat is a valid flags variable",
            "§3.5 lon is a valid flags variable",
        }

        self.assertTrue(len(expected_excluded_names & name_set) == 0)

        # should skip references
        ref_msg = "references global attribute should be a non-empty string"
        self.assertTrue(ref_msg not in msg_set)
        # check_standard_name is high priority, but we requested only low,
        # so the standard_name check should still exist
        standard_name_hdr = "§3.3 Standard Name"
        self.assertTrue(standard_name_hdr in name_set)

    def test_group_func(self):
        # This is checking for issue #183, where group_func results in
        # IndexError: list index out of range
        ds = self.cs.load_dataset(static_files["bad_data_type"])
        score_groups = self.cs.run(ds, [], "cf")

        limit = 2
        for checker, rpair in score_groups.items():
            groups, errors = rpair
            score_list, points, out_of = self.cs.standard_output(
                ds.filepath(),
                limit,
                checker,
                groups,
            )
            # This asserts that print is able to generate all of the unicode output
            self.cs.standard_output_generation(groups, limit, points, out_of, checker)

    def test_score_grouping(self):
        # Testing the grouping of results for output, which can fail
        # if some assumptions are not met, e.g. if a Result object has
        # a value attribute of unexpected type
        res = [
            Result(BaseCheck.MEDIUM, True, "one"),
            Result(BaseCheck.MEDIUM, (1, 3), "one"),
            Result(BaseCheck.MEDIUM, None, "one"),
            Result(BaseCheck.MEDIUM, True, "two"),
            Result(BaseCheck.MEDIUM, np.isnan(1), "two"),  # value is type numpy.bool_
        ]
        score = self.cs.scores(res)
        self.assertEqual(score[0].name, "one")
        self.assertEqual(score[0].value, (2, 4))
        self.assertEqual(score[1].name, "two")
        self.assertEqual(score[1].value, (1, 2))

    def test_cdl_file(self):
        # Testing whether you can run compliance checker on a .cdl file
        # Load the cdl file
        ds = self.cs.load_dataset(static_files["test_cdl"])
        vals = self.cs.run(ds, [], "cf")

        limit = 2
        for checker, rpair in vals.items():
            groups, errors = rpair
            score_list, cdl_points, cdl_out_of = self.cs.standard_output(
                ds.filepath(),
                limit,
                checker,
                groups,
            )
            # This asserts that print is able to generate all of the unicode output
            self.cs.standard_output_generation(
                groups,
                limit,
                cdl_points,
                cdl_out_of,
                checker,
            )
        ds.close()

        # Ok now load the nc file that it came from
        ds = self.cs.load_dataset(static_files["test_cdl_nc"])
        vals = self.cs.run(ds, [], "cf")

        limit = 2
        for checker, rpair in vals.items():
            groups, errors = rpair
            score_list, nc_points, nc_out_of = self.cs.standard_output(
                ds.filepath(),
                limit,
                checker,
                groups,
            )
            # This asserts that print is able to generate all of the unicode output
            self.cs.standard_output_generation(
                groups,
                limit,
                nc_points,
                nc_out_of,
                checker,
            )
        ds.close()

        nc_file_path = static_files["test_cdl"].replace(".cdl", ".nc")
        self.addCleanup(os.remove, nc_file_path)

        # Ok the scores should be equal!
        self.assertEqual(nc_points, cdl_points)
        self.assertEqual(nc_out_of, cdl_out_of)

    def test_load_local_dataset_GenericFile(self):
        resp = self.cs.load_local_dataset(static_files["empty"])
        assert isinstance(resp, GenericFile)

    def test_standard_output_score_header(self):
        """
        Check that the output score header only checks the number of
        of potential issues, rather than the weighted score
        """
        ds = self.cs.load_dataset(static_files["bad_region"])
        score_groups = self.cs.run(ds, [], "cf")
        limit = 2
        groups, errors = score_groups["cf"]
        score_list, all_passed, out_of = self.cs.standard_output(
            ds.filepath(),
            limit,
            "cf",
            groups,
        )
        assert all_passed < out_of

    def test_netCDF4_features(self):
        """
        Check if a proper netCDF4 file with netCDF4-datatypes is created.
        """
        # create and open dataset
        ds = self.cs.load_dataset(static_files["netCDF4"])
        # check if netCDF type of global attributes is correct
        assert isinstance(ds.global_att_of_type_int, np.int32)
        # check if netCDF4 type of global attributes is correct
        assert isinstance(ds.global_att_of_type_int64, np.int64)
        # check if netCDF type of variable is correct
        assert ds["tas"].dtype is np.dtype("float32")
        # check if netCDF4 type of variable is correct
        assert ds["mask"].dtype is np.dtype("int64")


import torch.nn as nn

class MultiOutputCNN(nn.Module):
    def __init__(self, ndigits, nvocab):
        # inputsize 32*112
        super(MultiOutputCNN, self).__init__()

        feature_net = nn.Sequential()

        def Conv_Relu(depth, ni, no, nk):
            feature_net.add_module('layer_' + str(depth), nn.Conv2d(ni, no, kernel_size=nk))
            feature_net.add_module('bn_' + str(depth), nn.BatchNorm2d(no))
            feature_net.add_module('act' + str(depth), nn.ReLU())

        Conv_Relu(0, 3, 32, 3)  # 30 * 110 * 32
        Conv_Relu(1, 32, 32, 3)  # 28 * 108 * 32
        feature_net.add_module('max_pool1', nn.MaxPool2d(2))  # 14 * 54 * 32
        Conv_Relu(2, 32, 64, 3)  # 12 * 52 * 64
        Conv_Relu(3, 64, 64, 3)  # 10* 50 *64
        feature_net.add_module('max_pool2', nn.MaxPool2d(2))  # 5 * 25 * 64

        classifier = nn.ModuleList()
        for i in range(ndigits):
            classifier.append(nn.Sequential(nn.Linear(8000, 128), nn.ReLU(), nn.Linear(128, nvocab)))
        self.feature_net = feature_net
        self.classifier = classifier

    def forward(self, x):
        feats = self.feature_net(x)
        feats = feats.view(x.size(0), -1)

        preds = [classifier(feats) for classifier in self.classifier]
        return preds


from PySide2.QtWidgets import QWidget, QTableWidgetItem, QAbstractItemView, QHeaderView, QMessageBox
from Ventanas.agendar_vuelo import AgendarVuelo
from Database.aeropuerto import *
from Database.hangares_db import traer_todas_aerolineas
from PySide2.QtCore import Qt
import datetime
from datetime import datetime
from datetime import date
import time

class Agenda (QWidget, AgendarVuelo):

    def __init__ (self, parent = None):
        super().__init__(parent)

        self.padre_ventana = parent
        self.setupUi(self)
        self.setWindowFlag (Qt.Window)

        #Cargar combo aerolineas
        self.tabla_general_vuelos()
        self.cargar_combo_aerolineas()
        self.event_tabla_vuelo()

        self.bt_guardarAereolinea.clicked.connect(self.aceptar_vuelo)
        self.bt_regresarAereolinea.clicked.connect(self.denegar_vuelo)

# -----------------------------------------------------------------------------
    def cargar_combo_aerolineas(self):
        aerolineas = traer_todas_aerolineas()

        #Aquí se convierte los valores de la tupla a str y sin esos caracteres
        characters = "(,')"
        i=0
        while i < len(aerolineas):
            string = str(aerolineas [i])
            for x in range(len(characters)):
                string = string.replace(characters[x],"")

        # Aquí se manda ese string ya listo al combo box
            self.cb_Aerolinea.addItem(str(string))
            i += 1

# -------------------------------------------------------------------------------
    def tabla_general_vuelos (self):
        self.tb_agendAereolinea.setSelectionBehavior(QAbstractItemView.SelectRows)
        header = self.tb_agendAereolinea.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.ResizeToContents)
        self.tb_agendAereolinea.verticalHeader().setDefaultAlignment(Qt.AlignHCenter)
        self.tb_agendAereolinea.resizeColumnsToContents()

# -------------------------------------------------------------------------------
    def cargar_tabla_vuelos (self):
        aerolinea = self.cb_Aerolinea.currentText()
        print(aerolinea)
        nit = consultar_aerolinea(aerolinea)
        print(nit)

        characters = "(,')"
        i=0
        while i < len(nit):
            string = str(nit [i])
            for x in range(len(characters)):
                string = string.replace(characters[x],"")
            i += 1

        print(string)
        datos = traer_vuelos_espera(string)
        print (datos)

        self.tb_agendAereolinea.setRowCount(len(datos))

        for(index_fila, fila) in enumerate(datos):
            #indice, datos
            for (index_celda, celda) in enumerate(fila):
                self.tb_agendAereolinea.setItem(index_fila, index_celda,
                QTableWidgetItem(str(celda)))

# ---------------------------------------------------------------------------------
    def event_tabla_vuelo (self):
        self.cb_Aerolinea.activated.connect(self.cargar_tabla_vuelos)
# ---------------------------------------------------------------------------------
    def aceptar_vuelo (self):
        vuelo_seleccionado = self.tb_agendAereolinea.selectedItems()

        if vuelo_seleccionado:
            id_vuelo= vuelo_seleccionado[2].text()
            print (id_vuelo)
            vuelo = vuelo_seleccionado[0].row()

            # Mensaje de confirmación de si quiere borrar la aerolinea
            dlg = QMessageBox.question(self, "Guardar Vuelo",
                        "¿Esta seguro que quiere agendar este vuelo?",
                        QMessageBox.Ok, QMessageBox.Cancel)

            #Si presiona Ok
            if dlg == QMessageBox.Ok:
                if aceptar_vuelo(id_vuelo):
                    self.tb_agendAereolinea.removeRow(vuelo)
                    QMessageBox.information(self, "Agendado", "Vuelo agendado con éxito", QMessageBox.Ok)

        else:
            dlg = QMessageBox(self)
            dlg.setWindowTitle("Error")
            dlg.setText("Para agendar un vuelo primero debe seleccionarlo")
            dlg.setStandardButtons(QMessageBox.Ok)
            dlg.setIcon(QMessageBox.Critical)
            dlg.show()

# ---------------------------------------------------------------------------------
    def denegar_vuelo (self):
        vuelo_seleccionado = self.tb_agendAereolinea.selectedItems()

        if vuelo_seleccionado:
            id_vuelo= vuelo_seleccionado[2].text()
            print (id_vuelo)
            vuelo = vuelo_seleccionado[0].row()

            # Mensaje de confirmación de si quiere borrar la aerolinea
            dlg = QMessageBox.question(self, "Regresar Vuelo",
                        "¿Esta seguro que quiere regresar este vuelo?",
                        QMessageBox.Ok, QMessageBox.Cancel)

            #Si presiona Ok
            if dlg == QMessageBox.Ok:
                if rechazar_vuelo(id_vuelo):
                    self.tb_agendAereolinea.removeRow(vuelo)
                    QMessageBox.information(self, "Denegado", "Vuelo regresado a la aerolinea", QMessageBox.Ok)

        else:
            dlg = QMessageBox(self)
            dlg.setWindowTitle("Error")
            dlg.setText("Para regresar un vuelo primero debe seleccionarlo")
            dlg.setStandardButtons(QMessageBox.Ok)
            dlg.setIcon(QMessageBox.Critical)
            dlg.show()


from functools import reduce
from hashlib import md5
from jsonpath import jsonpath
from jsonpath_ng.parser import JsonPathParser
from tools.funclib import get_func_lib
import json
import re
import time

from tools.utils.utils import extract_by_jsonpath, quotation_marks

class Template:

    def __init__(self, test, context, functions, params, variable_start_string='{{', variable_end_string='}}', function_prefix='@', param_prefix='$'):
        self.param_prefix = param_prefix
        self.data = None
        self.context = context  # 关联参数
        self.params = params    # 公共参数
        self.variable_start_string = variable_start_string
        self.variable_end_string = variable_end_string
        self.function_prefix = function_prefix
        self.param_prefix = param_prefix
        self.stack = list()
        # 动态存储接口的请求信息 以便渲染
        self.request_url = None
        self.request_path = None
        self.request_headers = None
        self.request_query = None
        self.request_body = None
        self.func_lib = get_func_lib(test, functions, self.context, self.params)
        self.bytes_map = dict()
        self.parser = JsonPathParser()

    def init(self, data):
        self.data = json.dumps(data, ensure_ascii=False)
        self.stack.clear()
        self.bytes_map.clear()

    def set_help_data(self, url, path: str, headers: dict, query: dict, body: dict):
        self.request_url = url
        self.request_path = path
        self.request_headers = headers
        self.request_query = query
        self.request_body = body

    def render(self):
        start_stack = list()
        start_length = len(self.variable_start_string)
        end_length = len(self.variable_end_string)
        top = 0
        flag = False
        for cur in range(len(self.data)):
            self.stack.append(self.data[cur])
            top += 1
            if flag:
                self.stack.pop()
                top -= 1
                flag = False
                continue
            if reduce(lambda x, y: x + y, self.stack[-start_length:]) == self.variable_start_string:
                start_stack.append(top - start_length)
            if reduce(lambda x, y: x + y, self.stack[-end_length:]) == self.variable_end_string:
                if len(start_stack) == 0:
                    continue
                recent = start_stack.pop()
                tmp = ''
                for _ in range(top - recent):
                    tmp += self.stack.pop()
                    top -= 1
                if self.stack[-1] == '"' and self.data[cur + 1] == '"':
                    self.stack.pop()
                    top -= 1
                    flag = True
                else:
                    flag = False
                tmp = tmp[::-1]
                key = tmp[start_length:-end_length].strip()
                key, json_path = self.split_key(key)
                if key.startswith(self.function_prefix):
                    name_args = self.split_func(key, self.function_prefix)
                    value = self.func_lib(name_args[0], *name_args[1:])
                elif key in self.context: # 优先从关联参数中取
                    if json_path is None:
                        value = self.context.get(key)
                    else:
                        value = extract_by_jsonpath(self.context.get(key), json_path)
                elif key in self.params:
                    if json_path is None:
                        value = self.params.get(key)
                    else:
                        value = extract_by_jsonpath(self.params.get(key), json_path)
                elif key.startswith(self.param_prefix) and key[1:] in self.params:  # 兼容老版本
                    if json_path is None:
                        value = self.params.get(key[1:])
                    else:
                        value = extract_by_jsonpath(self.params.get(key[1:]), json_path)
                else:
                    raise KeyError('不存在的公共参数、关联变量或内置函数: {}'.format(key))

                if not flag and isinstance(value, str):
                    if '"' in value:
                        value = json.dumps(value)[1:-1]
                    final_value = value
                elif isinstance(value, bytes):
                    final_value = self._bytes_save(value, flag)
                elif isinstance(value, list):
                    final_value = list()
                    for list_item in value:
                        if isinstance(list_item, bytes):
                            final_value.append(self._bytes_save(list_item, False))
                        else:
                            final_value.append(list_item)
                    final_value = json.dumps(final_value)
                else:
                    final_value = json.dumps(value)
                for s in final_value:
                    self.stack.append(s)
                    top += 1
        res = json.loads(reduce(lambda x, y: x + y, self.stack))

        if len(self.bytes_map) > 0:
            pattern = r'#\{(bytes_\w+_\d+?)\}'
            if isinstance(res, str):
                bytes_value = self._bytes_slove(res, pattern)
                if bytes_value is not None:
                    res = bytes_value
            elif isinstance(res, dict) or isinstance(res, list):
                for i, j in zip(jsonpath(res, '$..'), jsonpath(res, '$..', result_type='PATH')):
                    if isinstance(i, str):
                        bytes_value = self._bytes_slove(i, pattern)
                        if bytes_value is not None:
                            expression = self.parser.parse(j)
                            expression.update(res, bytes_value)
        return res

    def _bytes_save(self, value, flag):
        bytes_map_key = 'bytes_{}_{}'.format(md5(value).hexdigest(), int(time.time() * 1000000000))
        self.bytes_map[bytes_map_key] = value
        change_value = '#{%s}' % bytes_map_key
        if flag:
            final_value = json.dumps(change_value)
        else:
            final_value = change_value
        return final_value

    def _bytes_slove(self, s, pattern):
        search_result = re.search(pattern, s)
        if search_result is not None:
            expr = search_result.group(1)
            return self.bytes_map[expr]

    def replace_param(self, param):
        param = param.strip()
        search_result = re.search(r'#\{(.*?)\}', param)
        if search_result is not None:
            expr = search_result.group(1).strip()
            if expr.lower() == '_request_url':
                return self.request_url
            elif expr.lower() == '_request_path':
                return self.request_path
            elif expr.lower() == '_request_header':
                return self.request_headers
            elif expr.lower() == '_request_body':
                return self.request_body
            elif expr.lower() == '_request_query':
                return self.request_query
            elif expr.startswith('bytes_'):
                return self.bytes_map[expr]
            else:
                # 支持从请求头和查询参数中取单个数据
                if expr.lower().startswith("_request_header."):
                    data = self.request_headers
                    expr = '$.' + expr[16:]
                elif expr.lower().startswith("_request_query."):
                    data = self.request_query
                    expr = '$.' + expr[15:]
                else:
                    data = self.request_body
                    if expr.lower().startswith("_request_body."):
                        expr = '$.' + expr[14:]
                    elif not expr.startswith('$'):
                        expr = '$.' + expr
                try:
                    return extract_by_jsonpath(data, expr)
                except:
                    return param
        else:
            return param

    def split_key(self, key: str):
        if key.startswith(self.function_prefix):
            return key, None
        key_list = key.split(".")
        key = key_list[0]
        json_path = None
        if len(key_list) > 1:
            json_path = reduce(lambda x, y: x + '.' + y, key_list[1:])
        if key.endswith(']') and '[' in key:
            keys = key.split("[")
            key = keys[0]
            if json_path is None:
                json_path = keys[-1][:-1]
            else:
                json_path = keys[-1][:-1] + "." + json_path
        if json_path is not None:
            json_path = "$." + json_path
        return key, json_path

    def split_func(self, statement: str, flag: 'str' = '@'):
        pattern = flag + r'([_a-zA-Z][_a-zA-Z0-9]*)(\(.*?\))?'
        m = re.match(pattern, statement)
        result = list()
        if m is not None:
            name, _ = m.groups()
            args = statement.replace(flag+name, "")
            result.append(name)
            if args is not None and args != '()':
                argList = [str(_) for _ in map(self.replace_param, args[1:-1].split(','))]
                argList_length = len(argList)
                if not (argList_length == 1 and len(argList[0]) == 0):
                    if name not in self.func_lib.func_param:
                        for i in range(argList_length):
                            result.append(argList[i])
                    else:
                        type_list = self.func_lib.func_param[name]
                        j = 0
                        for i in range(len(type_list)):
                            if j >= argList_length:
                                break
                            if type_list[i] is str:
                                result.append(quotation_marks(argList[j]))
                                j += 1
                            elif type_list[i] is int:
                                result.append(int(argList[j]))
                                j += 1
                            elif type_list[i] is float:
                                result.append(float(argList[j]))
                                j += 1
                            elif type_list[i] is bool:
                                result.append(False if argList[j].lower() == 'false' else True)
                                j += 1
                            elif type_list[i] is dict:
                                j, r = self.concat(j, argList, '}')
                                result.append(r)
                            elif type_list[i] is list:
                                j, r = self.concat(j, argList, ']')
                                result.append(r)
                            elif type_list[i] is bytes:
                                result.append(argList[j])
                                j += 1
                            elif type_list[i] is None:
                                result.append(argList[j])
                                j += 1
                            else:
                                raise SplitFunctionError('函数{}第{}个参数类型错误: {}'.format(name, i + 1, type_list[i]))
            return result
        else:
            raise SplitFunctionError('函数错误: {}'.format(statement))

    @staticmethod
    def concat(start: int, arg_list: list, terminal_char: str):
        end = start
        length = len(arg_list)
        for i in range(start, length):
            if terminal_char in arg_list[i]:
                end = i
                s = reduce(lambda x, y: x + ',' + y, arg_list[start:end + 1])
                try:
                    return end + 1, eval(quotation_marks(s))
                except:
                    try:
                        s = '"'+s+'"'
                        return end + 1, eval(json.loads(s))
                    except:
                        continue
        else:
            s = reduce(lambda x, y: x + ',' + y, arg_list[start:end + 1])
            return end + 1, s

class SplitFunctionError(Exception):
    """函数处理错误"""


import os
import io
import lmdb
import six
import cv2
from PIL import Image

IMAGE_SAMPLE_HEIGHT = 64

def image_bin_to_pil(image_bin):
    buf = six.BytesIO()
    buf.write(image_bin)
    buf.seek(0)
    img = Image.open(buf)
    return img

def is_valid_label(label, classes):
    for ch in label:
        if classes.get(ch) is None:
            print(f'{ch} is not valid')
            return False
    return True

def load_class_dictionary(path, add_space=False):
    class_dict = {}
    with open(path, 'r', encoding='utf-8') as f:
        lines = f.readlines()

    for line in lines:
        items = line.strip().split()
        # class_dict[items[1]] = items[0]
        class_dict[items[0]] = items[1]
    return class_dict

def load_and_resize(path, label, resize=False):
    im = Image.open(path)

    w, h = im.size
    if h > w * 1.5 and len(label) > 1:
        im = im.rotate(90.0, expand=True)

    if resize:
        scaled_w = int(IMAGE_SAMPLE_HEIGHT / h * w)
        im = im.resize((scaled_w, IMAGE_SAMPLE_HEIGHT), Image.LANCZOS)

    with io.BytesIO() as output:
        im.save(output, format="JPEG")
        contents = output.getvalue()
    return contents

class MyLMDB:
    def __init__(self, path, sync_period=100, mode='w', map_size=1e9):
        if not os.path.exists(path):
            os.makedirs(path)
        self.path = path
        self.session = lmdb.open(path, map_size=10e10)
        self.cache = {}
        self.sync_period = sync_period
        self.num_of_write = 0
        self.num_of_samples = self.get_number_of_samples()
        self.mode = mode

    def get_number_of_samples(self):
        with self.session.begin(write=False) as txn:
            num_samples = txn.get('num-samples'.encode())
            if num_samples is None:
                num_of_samples = 1
            else:
                num_of_samples = int(num_samples)
        return num_of_samples

    def write_im_label_path(self, im, label, path, row_index, resize=True):
        image_key = 'image-%09d'.encode() % self.num_of_samples
        label_key = 'label-%09d'.encode() % self.num_of_samples
        path_key = 'path-%09d'.encode() % self.num_of_samples
        row_index_key = 'row_index_key-%09d'.encode() % self.num_of_samples

        _, image_bin = cv2.imencode('.jpeg', im)
        # image_bin = im

        self.cache[image_key] = image_bin
        self.cache[label_key] = label.encode()
        self.cache[path_key] = path.encode()
        self.cache[row_index_key] = row_index.encode()

        self.num_of_samples += 1
        self.num_of_write += 1
        if self.num_of_write > self.sync_period:
            print(f'{self.path} cache write {self.num_of_samples}')
            self.cache['num-samples'.encode()] = str(self.num_of_samples - 1).encode()
            with self.session.begin(write=True) as txn:
                for k, v in self.cache.items():
                    txn.put(k, v)
            self.num_of_write = 0
            self.cache = {}

    def write_image_label(self, image_path, label, resize=True):
        image_bin = load_and_resize(image_path, label, resize)

        image_key = 'image-%09d'.encode() % self.num_of_samples
        label_key = 'label-%09d'.encode() % self.num_of_samples
        self.cache[image_key] = image_bin
        self.cache[label_key] = label.encode()

        self.num_of_samples += 1
        self.num_of_write += 1
        if self.num_of_write > self.sync_period:
            print(f'{self.path} cache write {self.num_of_samples}')
            self.cache['num-samples'.encode()] = str(self.num_of_samples - 1).encode()
            with self.session.begin(write=True) as txn:
                for k, v in self.cache.items():
                    txn.put(k, v)
            self.num_of_write = 0
            self.cache = {}

    def read_image_label(self, index):
        label_key = 'label-%09d'.encode() % index
        image_key = 'image-%09d'.encode() % index

        with self.session.begin(write=False) as txn:
            im = txn.get(image_key)
            label = txn.get(label_key).decode('utf-8')
            return im, label

    def read_image_label_path(self, index):
        label_key = 'label-%09d'.encode() % index
        image_key = 'image-%09d'.encode() % index
        path_key = 'path-%09d'.encode() % index

        with self.session.begin(write=False) as txn:
            im = txn.get(image_key)
            label = txn.get(label_key).decode('utf-8')
            path = txn.get(path_key).decode('utf-8')
            return im, label, path

    def read_image_label_path_key(self, index):
        label_key = 'label-%09d'.encode() % index
        image_key = 'image-%09d'.encode() % index
        path_key = 'path-%09d'.encode() % index
        row_index_key = 'row_index-%09d'.encode() % index

        with self.session.begin(write=False) as txn:
            im = txn.get(image_key)
            label = txn.get(label_key).decode('utf-8')
            path = txn.get(path_key).decode('utf-8')
            row_index = txn.get(row_index_key).decode('utf-8')
            return im, label, path, row_index

    def get_row_num(self, index):
        label_key = 'label-%09d'.encode() % index
        image_key = 'image-%09d'.encode() % index
        path_key = 'path-%09d'.encode() % index
        # id_key = 'id-%09d'.encode() % index

        with self.session.begin(write=False) as txn:
            im = txn.get(image_key)
            label = txn.get(label_key).decode('utf-8')
            path = txn.get(path_key).decode('utf-8')
            # id = txn.get(id_key).decode('utf-8')

            row_num = 0
            index -= 1
            while index >= 1:
                prev_path_key = 'path-%09d'.encode() % index
                prev_path = txn.get(prev_path_key).decode('utf-8')
                if prev_path != path:
                    break
                index -= 1
                row_num += 1

        return row_num

    def close(self):
        if self.mode != 'w':
            return
        self.cache['num-samples'.encode()] = str(self.num_of_samples - 1).encode()
        with self.session.begin(write=True) as txn:
            for k, v in self.cache.items():
                txn.put(k, v)


import re
import cv2
import numpy as np
import matplotlib.pyplot as plt

flat_chess=cv2.imread('DATA/flat_chessboard.png')
flat_chess=cv2.cvtColor(flat_chess,cv2.COLOR_BGR2RGB)

plt.subplot(321)
plt.imshow(flat_chess)

gray_flat_chess=cv2.cvtColor(flat_chess,cv2.COLOR_BGR2GRAY)

plt.subplot(322)
plt.imshow(gray_flat_chess,cmap='gray')

real_chess=cv2.imread('DATA/real_chessboard.jpg')
real_chess=cv2.cvtColor(real_chess,cv2.COLOR_BGR2RGB)
plt.subplot(323)
plt.imshow(real_chess)

gray_real_chess=cv2.cvtColor(real_chess,cv2.COLOR_BGR2GRAY)
plt.subplot(324)
plt.imshow(gray_real_chess,cmap="gray")
plt.show(block=False)
plt.pause(1.5)

## Harris Corner detection
gray=np.float32(gray_flat_chess)
dst=cv2.cornerHarris(src=gray,blockSize=2,ksize=3,k=0.04)

dst=cv2.dilate(dst,None)
#kjerkoli je vrednost več kot procent max() Harris obdelave naj bo rdeče
flat_chess[dst>0.01*dst.max()]=[255,0,0]
plt.subplot(325)
plt.imshow(flat_chess)

gray=np.float32(gray_real_chess)
dst=cv2.cornerHarris(src=gray,blockSize=2,ksize=3,k=0.04)
dst=cv2.dilate(dst,None)
#kjerkoli je vrednost več kot procent max() Harris obdelave naj bo rdeče
real_chess[dst>0.01*dst.max()]=[255,0,0]
plt.subplot(326)
plt.imshow(real_chess)

# Make it full Screen
wm = plt.get_current_fig_manager()
wm.window.state('zoomed')

plt.show(block=False)
plt.pause(4)
print("Konec")


import mediapipe as mp
import json

mp_pose = mp.solutions.pose

def calculate_pose(image, pose):
    results = pose.process(image)

    if (results.pose_landmarks == None):
        return {
            "error": "NO LANDMARKS"
        }

    landmarks = results.pose_landmarks.landmark

    landmarks_list = []
    for landmark in results.pose_landmarks.landmark:
        current_landmark = {"x": landmark.x, "y": landmark.y, "z": landmark.z, "visibility": landmark.visibility}
        landmarks_list.append(current_landmark)
    with open("json_output/landmarks_list.json", "w") as outfile:
        json.dump(landmarks_list, outfile, indent=2)

    landmarks_x_y_z_visibility = {}
    for l in mp_pose.PoseLandmark:
      # print(l.name)
      landmarks_x_y_z_visibility[l.name.lower()] = {
          "x": landmarks[l.value].x,
          "y": landmarks[l.value].y,
          "z": landmarks[l.value].z,
          "visibility": landmarks[l.value].visibility,
    }
    # would be nice to extract the filename from args.video or args.output & add to json filename
    with open(f"json_output/landmarks_with_labels.json", "w") as outfile:
      json.dump(landmarks_x_y_z_visibility, outfile, indent=2)
    return landmarks_x_y_z_visibility


# 发送纯文本
# SMTP: 邮件传输协议

# 发邮件
import smtplib
# 邮件标题
from email.header import Header
# 邮件正文
from email.mime.text import MIMEText

"""
user, pwd, sender, receiver, content, title
用户名，授权码，发送方邮箱，接收方邮箱，内容，标题
"""

def sendEmail(user, pwd, sender, receiver, content, title):
    # 163的SMTP服务器
    mail_host = "smtp.163.com"

    # 第一部分：准备工作
    # 1. 将对应的邮件信息打包成一个对象: 内容， 格式， 编码
    message = MIMEText(content, "plain", "utf-8")
    message["Content-Type"] = 'application/octet-stream'
    message["Content-Disposition"] = 'attachment;filename='+ file
    # 2. 设置邮件的发送者
    message["From"] = sender
    # 3. 设置邮件的接收方
    """
    seq.join(sep)
    seq: 分隔符
    sep: 要连接的元素序列，字符串，元组，字典
    返回值：字符串
    """
    message["To"] = ",".join(receiver)
    # 4. 设置邮件标题
    message["Subject"] = title

    try:
        # 第二部分：发送邮件
        # 1. 启用SSL发送邮件，参数1： SMTP服务器， 参数2 ： 端口号么一般使用465
        smtpObj = smtplib.SMTP_SSL(mail_host, 465)
        # 2.登录邮箱并进行验证
        # 参数1: 发送方用户名，参数2：授权码
        smtpObj.login(user, pwd)
        # 3. 发送邮件
        # 参数1：发送方邮箱 参数2： 接收方的邮箱 参数3：邮件正文
        smtpObj.sendmail(sender, receiver, message.as_string())

        print("mail has been send successful!")
    except BaseException as e:
        print(e)

if __name__ == '__main__':
    mail_user = "zst0717123@163.com"
    mail_pwd = "*****"
    sender = "zst0717123@163.com"
    receiver = "@qq.com"
    file = "beautiful_girl.png"
    content = open(file=file,mode='rb').read()
    title = "666"

    sendEmail(mail_user, mail_pwd, sender, receiver, content, title)


from django.conf.urls import url
from .import views
# from views import ClienteAutocomplete

urlpatterns = [
    # url(r'^cliente-autocomplete/$', ClienteAutocomplete.as_view(), name='cliente-autocomplete'),
    url(regex=r'^$', view=views.index, name='index'),
    url(r'^cliente/(?P<cliente_id>\d+)/edit/$', views.cliente_edit, name='cliente_edit'),
    url(r'^cliente/(?P<cliente_id>\d+)/$', views.cliente_detalle, name='cliente_detalle'),
    url(r'^cliente/new/$', views.cliente_nuevo, name='cliente_nuevo'),

    # Geraldo reports
    url(r'reserva-report/(?P<pk>\d+)/$', views.reserva_report, name='reserva_report'),
]


import numpy as np
import pandas as pd
import matplotlib
from matplotlib import pyplot as plt
from matplotlib.ticker import AutoMinorLocator

# datafile from COMSOL
path_to_data = "E://COMSOL//laminar_mesh_refinement/"

# % Model:              run40_lam_mesh_fluid_0.5_out.mph
# % Version:            COMSOL 5.2.1.262
# % Date:               Dec 13 2017, 08:40
# % Dimension:          1
# % Nodes:              16
# % Expressions:        1
# % Description:        Line graph
# % cln1x                   Height
lst_files = [0.5, 0.75, 1.0, 1.25, 1.5]
lst_files = ['fluid_' + str(file) + '_T_along_z_beamspot.txt' for file in lst_files]

# -------------------------------------------------------------------
# plot
# -------------------------------------------------------------------
plt.rc('text', usetex=True)
plt.rc('font', weight='bold')
matplotlib.rcParams['mathtext.fontset'] = 'custom'
matplotlib.rcParams['mathtext.rm'] = 'Arial'
matplotlib.rcParams['mathtext.it'] = 'Arial:italic'
matplotlib.rcParams['mathtext.bf'] = 'Arial:bold'
matplotlib.rcParams['mathtext.tt'] = 'Arial'
matplotlib.rcParams['mathtext.cal'] = 'Arial'
matplotlib.rcParams['text.latex.preamble'] = [r'\usepackage{sfmath} \boldmath']

fig = plt.figure(figsize=(8*0.60,5*0.60))

####################
# axis 1
####################
ax1 = fig.add_subplot(1, 1, 1)

# plot
for file in lst_files:
	# import data
	df = pd.read_csv(path_to_data + file, delimiter=r" \s+", skiprows=7)
	print(df)
	ax1.plot(df.iloc[:,0], df.iloc[:,1], 's-', linewidth=1)
# axes label
ax1.set_ylabel(r'\textbf{Maximum target temperature [$^{\circ}$C]}', fontsize=12, labelpad=10)
ax1.set_xlabel(r'\textbf{Mesh refinement}', fontsize=12, labelpad=2)
# plt.ylim(150,155)
# ticks
# ax1.xaxis.set_ticks(df['ref_fac'].values)
# ax1.yaxis.set_ticks([170, 175, 180, 185])
# minor ticks x
minor_locator = AutoMinorLocator(2)
ax1.xaxis.set_minor_locator(minor_locator)
# minor ticks y
minor_locator = AutoMinorLocator(2)
ax1.yaxis.set_minor_locator(minor_locator)
# tick font size
ax1.tick_params('x', colors='black', labelsize=12)
ax1.tick_params('y', colors='black', labelsize=12)
# grid
ax1.grid(b=True, which='major', linestyle='-')#, color='gray')
ax1.grid(b=True, which='minor', linestyle='--')#, color='gray')

# ####################
# # other axis
# ####################
# ax2 = ax1.twinx()
# # plot
# ax2.plot(df['vol_flow_rate_lpmin'], df['Re_number'], '--', marker='D', color='darkred', linewidth=2)

# ax2.yaxis.set_ticks([1000,2000,4000,6000])
# #ax2.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1e'))
# # Use the pyplot interface to change just one subplot...
# # cur_axes = plt.gca()
# # plt.yticks([0, 1.4e7], [r"\textbf{0}", r"\textbf{1.4e7}"])
# # ax2.spines['top'].set_visible(False)

fig.subplots_adjust(left=0.18, right=0.95, top=0.88, bottom=0.18)

#y label coordinates
# ax1.yaxis.set_label_coords(-0.11,0.5)
# plt.savefig('maximum_target_temperature_vs_coolant_flow_rate.eps', dpi=1200)
# plt.savefig('maximum_target_temperature_vs_coolant_flow_rate.svg', dpi=1200)
# plt.savefig('maximum_target_temperature_vs_coolant_flow_rate.png', dpi=1200)
plt.show()